2013-01-06 21 views
1

我正在使用IIS中託管的WCF RESTful Web服務。我目前工作的一個相當簡單的post請求,發送下面的XML到端點:閱讀POST請求XML - 布爾值總是讀爲假

<StockListRequestData xmlns="http://myWebService.com/endpoint"> 
<UserID>2750</UserID> 
<StockDatabase>stockLeekRoadVenue</StockDatabase> 
<InStockOnly>true</InStockOnly> 
</StockListRequestData> 

該XML符合我的web服務的DataContract

[DataContract(Namespace = "http://myWebService.com/endpoint")] 
public class StockListRequestData 
{ 
    [DataMember] 
    public string UserID { get; set; } 

    [DataMember] 
    public string StockDatabase { get; set; } 

    [DataMember] 
    public bool InStockOnly { get; set; } 
} 

問題是<InStockOnly>true</InStockOnly>元素當我設置爲truefalse它都會被解釋爲false ...

下面是處理該請求的代碼:

public StockListResponseData GetListOfProducts(StockListRequestData requestData) 
    { 
     var stockList = new StockList(requestData.InStockOnly, requestData.StockDatabase); 
     StockListResponseData response; 
     if (stockList.Any()) 
     { 
      var stockArray = new Stock[stockList.Count]; 
      var i = 0; 
      foreach (var s in stockList) 
      { 
       stockArray[i] = s; 
       i++; 
      } 
      response = new StockListResponseData 
          { 
           StockList = stockArray, 
           WasSuccessful = true, 
          }; 
      return response; 
     } 
     response = new StockListResponseData 
         { 
          WasSuccessful = false 
         }; 
     return response; 
    } 

StockList類:

[DataContract] 
public class StockList : List<Stock> 
{ 
    public StockList(bool inStockOnly, string stockDb) 
    { 
     if (inStockOnly) 
     { 
      // Get only products that are in stock 
      var conn = AndyServerDatabase.ConnectToStockMovementByDb(stockDb); 
      conn.Open(); 
      // Compile SQL query 
      var q = new SqlCommand(null, conn) { CommandText = "SELECT StockID, Name, PerBox FROM Stock WHERE InStock = 1;" }; 

      // Execute query 
      var rdr = q.ExecuteReader(); 

      // Check that the output isn't null 
      if (rdr.HasRows) 
      { 
       while(rdr.Read()) 
       { 
        var id = Convert.ToInt32(rdr[0]); 
        var name = rdr[1].ToString(); 
        var perBox = Convert.ToInt32(rdr[2]); 
        Add(new Stock(id, name, perBox)); 
       } 
       conn.Close(); 
      } 
      // Output is null 
      conn.Close(); 
     } 
     else 
     { 
      // Get all products 
      // Get only products that are in stock 
      var conn = AndyServerDatabase.ConnectToStockMovementByDb(stockDb); 
      conn.Open(); 
      // Compile SQL query 
      var q = new SqlCommand(null, conn) { CommandText = "SELECT StockID, Name, PerBox FROM Stock;" }; 
      q.Prepare(); 

      // Execute query 
      var rdr = q.ExecuteReader(); 

      // Check that the output isn't null 
      if (rdr.HasRows) 
      { 
       while (rdr.Read()) 
       { 
        var id = Convert.ToInt32(rdr[0]); 
        var name = rdr[1].ToString(); 
        var perBox = Convert.ToInt32(rdr[2]); 
        Add(new Stock(id, name, perBox)); 
       } 
       conn.Close(); 
      } 
      // Output is null 
      conn.Close(); 
     } 
     // Add(); 
    } 
} 

生成的XML:

<StockListResponseData xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
    <StockList xmlns:a="http://schemas.datacontract.org/2004/07/SMS"> 
     <a:Stock> 
      <a:Id>1</a:Id> 
      <a:Name>Smirnoff Vodka (70cl)</a:Name> 
      <a:PerBox>6</a:PerBox> 
      <a:Quantity>0</a:Quantity> 
      <a:Remains>0</a:Remains> 
     </a:Stock> 
     <a:Stock> 
      <a:Id>2</a:Id> 
      <a:Name>Jagermeister (70cl)</a:Name> 
      <a:PerBox>6</a:PerBox> 
      <a:Quantity>0</a:Quantity> 
      <a:Remains>0</a:Remains> 
     </a:Stock> 
    </StockList> 
    <WasSuccessful>true</WasSuccessful> 

我希望這是足夠去,我已經難倒年齡和剛好可以不知道爲什麼它會以這種方式行事..如果您需要額外的代碼,我沒有包括在內,請隨時提問。

非常感謝,

安迪

編輯:

要添加一些背景顯示發生了什麼:

例如,我知道:

<a:Stock> 
     <a:Id>2</a:Id> 
     <a:Name>Jagermeister (70cl)</a:Name> 
     <a:PerBox>6</a:PerBox> 
     <a:Quantity>0</a:Quantity> 
     <a:Remains>0</a:Remains> 
    </a:Stock> 

它的InStock行設置爲0,這意味着這一點如果我通過true,則不應在結果XML中顯示。

我已經改變了StockList構造if(inStockOnly)if(!inStockOnly) - 然後我通過在<InStockOnly>true</InStockOnly> - 當它到達StockList構造它,然後反轉,顯示出正確的數據 - 因此它必須讀它的時候爲假時得到這if聲明。

如果我通過<InStockOnly>false</InStockOnly>它仍然顯示「正確」的結果,因此它讀取它爲假,直到它倒置!

同樣,如果我將它作爲if(inStockOnly)並通過<InStockOnly>false</InStockOnly>它顯示的數據爲false

我也添加了requestData.InStockOnly to StockListResponseData DataContract並在那裏它顯示它輸出的值爲requestData.InStockOnlyfalse

+0

您的代碼看起來不錯,但你不填充量和遺蹟,所以那些將始終爲0是否確定正在退貨的物品實際上沒有庫存?順便說一句,你用來填充stockArray的代碼是沒有必要的。你應該只使用Stock [] stockArray = stockList.ToArray(); – JLRishe

+0

是的,我認爲這可能會導致一些混淆,'真正的

+0

那你怎麼證實InStockOnly其實總是假的?你的文章沒有提到這些細節,也沒有提供任何證明它總是假的東西。 – JLRishe

回答

1

你的發現使我的解釋,並與你類似問題的人:

WCF DataContract DataMember order? http://msdn.microsoft.com/en-us/library/ms729813.aspx

下一頁爲了是當前類型的數據成員沒有訂單DataMemberAttribute屬性集的屬性,按字母順序排列。

當數據成員的順序沒有明確指定時,它們的序列化順序是按字母順序的。這就解釋了爲什麼InStockOnly在它移動到頂端時工作的原因,因爲它是按字母順序排列的。另一方面,爲什麼StockDatabase的工作有點神祕,因爲這是按字母順序排列的UserId(如果StockDb爲空,AndyServerDatabase.ConnectToStockMovementByDb()使用默認值嗎?)。

爲了論證的緣故,如果出於某種原因,你想保持你那裏的順序,你可以這樣做:

[DataContract(Namespace = "http://myWebService.com/endpoint")] 
public class StockListRequestData 
{ 
    [DataMember(Order = 0)] 
    public string UserID { get; set; } 

    [DataMember(Order = 1)] 
    public string StockDatabase { get; set; } 

    [DataMember(Order = 2)] 
    public bool InStockOnly { get; set; } 
} 

事實上,它可能是一個很好的做法,明確地指示訂單,所以稍後添加新的屬性不會破壞任何東西。

+0

這樣做是完全有道理的,是的,數據庫連接似乎默認爲同一個數據庫,這就是爲什麼它工作正常 - 我需要解決這個問題。至少它的發現,謝謝你的解釋! –

0

我嘗試了上面的建議,它仍然沒有工作!不停地搜索和發現了另一個解決方案中,「指定」屬性實際上設置爲true:

PackageImagesPayload payload = new PackageImagesPayload(); 
payload.UsesSplitBy = usesSplitBy; 
payload.UsesSplitBySpecified = true;