我正在研究IIS中托管的WCF RESTful Web服务。我目前正在处理一个相当简单的帖子请求,将以下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>
元素,当我将其设置为true
或false
时,它将始终被解释为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构造函数时,它将被反转并显示正确的数据-因此,它必须将其读取为false时间到达此if
语句。如果我输入了
<InStockOnly>false</InStockOnly>
,它仍然显示“正确”的结果,因此它将读为false直到返回反转!同样,如果我将其保留为
if(inStockOnly)
并传入<InStockOnly>false</InStockOnly>
,则会显示false
的数据!我还已将
requestData.InStockOnly
添加到StockListResponseData DataContract,并在其中显示将requestData.InStockOnly
的值输出为false
。 最佳答案
您的发现使我得到了解释,并且遇到了与您类似的问题:
WCF DataContract DataMember order?
http://msdn.microsoft.com/en-us/library/ms729813.aspx
接下来的是当前类型的数据成员,这些成员没有按字母顺序设置DataMemberAttribute属性的Order属性。
如果未明确指定数据成员的顺序,则其序列化顺序为字母顺序。这就解释了为什么将InStockOnly移到顶部时起作用的原因,因为它是按字母顺序排列的。另一方面,为什么StockDatabase起作用是一个谜,因为那是按字母顺序在UserId之后的(如果StockDb为null,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; }
}
实际上,明确指示顺序可能是一个好习惯,因此以后添加新属性不会破坏任何内容。
关于c# - 读取POST请求XML- boolean 值始终读为false,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14187461/