【发布时间】:2012-12-20 16:20:59
【问题描述】:
我正在开发托管在 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 构造函数时,它会被反转并显示正确的数据 - 所以它必须将其读取为到此 if 声明时为 false。
如果我传入<InStockOnly>false</InStockOnly>,它仍会显示“正确”的结果,因此在反转之前它会将其读取为假!
同样,如果我将其保留为if(inStockOnly) 并传入<InStockOnly>false</InStockOnly>,它会显示false 的数据!
我还将requestData.InStockOnly 添加到 StockListResponseData DataContract 中,并在那里显示它以false 输出requestData.InStockOnly 的值。
【问题讨论】:
-
您的代码看起来没问题,只是您没有填写 Quantity 和 Remains,因此它们始终为 0。您确定退回的商品实际上没有库存吗?顺便说一句,您用来填充 stockArray 的代码不是必需的。你应该只使用 Stock[] stockArray = stockList.ToArray();
-
是的,我认为这可能会引起一些混乱,
<InStockOnly>true</InStockOnly元素的目的是检查股票表中的InStock行 - 这是bit类型。 Quantity 和 Remains 元素无关紧要。 -
那么您如何验证 InStockOnly 实际上总是错误的?你的帖子没有提到那个细节,也没有提供任何东西来证明它总是错误的。
-
我会更详细地更新问题。
-
修复了!我将
<InStockOnly>的数据类型更改为string,我还将if(inStockOnly)更改为if(inStockOnly.Equals("1"))- 然后我传入<InStockOnly>1</InStockOnly>,我得到了NullReferenceException。诡异的!所以我决定重新排序我的请求 XML,将InStockOnly元素移动到顶部 - 它有效!所以我将数据类型切换回bool,现在一切正常,如果有人知道为什么会发生这种情况,我非常想知道!很奇怪!一旦它在这里持续了 8 小时,我将用我的答案更新它 - 没有足够的声誉......