ASMX 服务并不总是返回数据
我正在 ASP.NET/C# 中使用 ASMX 服务。我的服务为我的 WebMethod 的一些返回正确的数据,但不是全部。有趣的是所有 WebMethod 都非常相似。
这是一个总是返回数据的:
[WebMethod]
public AccountItem[] GetAllAccounts()
{
AccountItem[] AccountItems = HttpContext.Current.Cache[AccountItemsCacheKey] as AccountItem[];
if (AccountItems == null)
{
List<AccountItem> items = new List<AccountItem>();
using (SqlManager sql = new SqlManager(SqlManager.GetSqlDbiConnectionString()))
{
using (SqlDataReader reader = sql.ExecuteReader("SELECT A.Account_Id, A.Customer_Id, C.Last_Name + ', ' + C.First_Name AS CustomerName, A.[Status], AT.Name AS AcctType, A.Employee_Id, A.Initial_Balance, A.Interest_Rate, '$'+CONVERT(varchar(50), A.Balance, 1) AS Balance FROM Account A JOIN Account_Type AT ON A.Account_Type_Id=AT.Account_Type_Id JOIN Customer C ON A.Customer_Id=C.Customer_Id WHERE [Status]=1"))
{
while (reader.Read())
{
AccountItem item = new AccountItem();
item.AccountId = (int)reader["Account_Id"];
item.CustomerId = (int)reader["Customer_Id"];
item.CustomerName = (string)reader["CustomerName"];
item.AccountStatus = (bool)reader["Status"];
item.AccountType = (string)reader["AcctType"];
item.InitialBalance = (decimal)reader["Initial_Balance"];
item.InterestRate = (decimal)reader["Interest_Rate"];
item.Balance = (string)reader["Balance"];
items.Add(item);
}
reader.Close();
}
}
HttpContext.Current.Cache.Add(AccountItemsCacheKey, items.ToArray(), null, DateTime.Now.AddMinutes(CacheDuration), Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
return items.ToArray();
}
else
{
return AccountItems;
}
}
这是一个从不返回数据的:
[WebMethod]
public TransactionItem[] GetAllTransactions()
{
TransactionItem[] tranItems = HttpContext.Current.Cache[TransactionItemsCacheKey] as TransactionItem[];
if (tranItems == null)
{
List<TransactionItem> items = new List<TransactionItem>();
using (SqlManager sql = new SqlManager(SqlManager.GetSqlDbiConnectionString()))
{
using (SqlDataReader reader = sql.ExecuteReader("SELECT [Transaction_Id],[Account_Id],[Amount],[DateTime],[Comment],TT.[Name] AS [TransType],[Flagged],[Employee_Id],[Status] FROM [Transaction] T JOIN [Trans_Type] TT ON T.Trans_Type_Id=TT.Trans_Type_Id"))
{
while (reader.Read())
{
TransactionItem item = new TransactionItem();
item.TransactionId = (int)reader["Transaction_Id"];
item.AccountId = (int)reader["Account_Id"];
item.Amount = (decimal)reader["Amount"];
item.Timestamp = (DateTime)reader["DateTime"];
item.Comment = (string)reader["Comment"];
item.TransType = (string)reader["TransType"];
item.Flagged = (bool)reader["Flagged"];
item.EmployeeId = (int)reader["Employee_Id"];
item.Status = (bool)reader["Status"];
items.Add(item);
}
reader.Close();
}
}
HttpContext.Current.Cache.Add(TransactionItemsCacheKey, items.ToArray(), null, DateTime.Now.AddMinutes(CacheDuration), Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
return items.ToArray();
}
else
{
return tranItems;
}
}
正如您所看到的,它们几乎是相同的。两者的 SQL 查询都会返回大量记录,但只有 GetAllAccounts()
WebMethod 实际返回该数据。
这就是我显示从 GetAllAccounts()
传回的数据的方式,它工作正常:
@{
Layout = "~/Shared/_Layout.cshtml";
Page.Title = "Accounts";
Page.Header = "BankSite Mobile - Accounts";
var svc = IntranetService.GetAllAccounts();
}
<div data-role="content">
<ul data-role="listview" data-inset="true" data-theme="c">
@foreach(var item in svc){
<li>
<h3><a href="[email protected]">Account #@item.AccountId.ToString() (@item.AccountType)</a></h3>
<p>Customer: @item.CustomerName</p>
<p>Account Balance: @item.Balance</p>
</li>
}
</ul>
</div>
然而,这不能正常工作,尽管它的代码几乎完全相同:
@{
Layout = "~/Shared/_Layout.cshtml";
Page.Title = "Customers";
Page.Header = "BankSite Mobile - Customers";
var svc = IntranetService.GetAllCustomers();
}
<div data-role="content">
<ul data-role="listview" data-inset="true" data-theme="c">
@foreach(var item in svc){
<li>
<h3><a href="[email protected]">Account #@item.CustomerId.ToString() (@item.CustomerId)</a></h3>
<p>Customer: @item.CustomerId</p>
<p>Account Balance: @item.CustomerId</p>
</li>
}
</ul>
</div>
...所以基本上我很困惑。我不明白为什么数据没有按预期从不工作的 WebMethod (GetAllCustomers()
) 返回。我缺少什么?
I am working with an ASMX service in ASP.NET/C#. My service returns proper data for some of my WebMethods, but not all. The interesting part is all of the WebMethods are very similar.
Here's one that always returns data:
[WebMethod]
public AccountItem[] GetAllAccounts()
{
AccountItem[] AccountItems = HttpContext.Current.Cache[AccountItemsCacheKey] as AccountItem[];
if (AccountItems == null)
{
List<AccountItem> items = new List<AccountItem>();
using (SqlManager sql = new SqlManager(SqlManager.GetSqlDbiConnectionString()))
{
using (SqlDataReader reader = sql.ExecuteReader("SELECT A.Account_Id, A.Customer_Id, C.Last_Name + ', ' + C.First_Name AS CustomerName, A.[Status], AT.Name AS AcctType, A.Employee_Id, A.Initial_Balance, A.Interest_Rate, '
And here's one that never returns data:
[WebMethod]
public TransactionItem[] GetAllTransactions()
{
TransactionItem[] tranItems = HttpContext.Current.Cache[TransactionItemsCacheKey] as TransactionItem[];
if (tranItems == null)
{
List<TransactionItem> items = new List<TransactionItem>();
using (SqlManager sql = new SqlManager(SqlManager.GetSqlDbiConnectionString()))
{
using (SqlDataReader reader = sql.ExecuteReader("SELECT [Transaction_Id],[Account_Id],[Amount],[DateTime],[Comment],TT.[Name] AS [TransType],[Flagged],[Employee_Id],[Status] FROM [Transaction] T JOIN [Trans_Type] TT ON T.Trans_Type_Id=TT.Trans_Type_Id"))
{
while (reader.Read())
{
TransactionItem item = new TransactionItem();
item.TransactionId = (int)reader["Transaction_Id"];
item.AccountId = (int)reader["Account_Id"];
item.Amount = (decimal)reader["Amount"];
item.Timestamp = (DateTime)reader["DateTime"];
item.Comment = (string)reader["Comment"];
item.TransType = (string)reader["TransType"];
item.Flagged = (bool)reader["Flagged"];
item.EmployeeId = (int)reader["Employee_Id"];
item.Status = (bool)reader["Status"];
items.Add(item);
}
reader.Close();
}
}
HttpContext.Current.Cache.Add(TransactionItemsCacheKey, items.ToArray(), null, DateTime.Now.AddMinutes(CacheDuration), Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
return items.ToArray();
}
else
{
return tranItems;
}
}
As you can see, they're almost identical. The SQL queries for both return a ton of records, but only the GetAllAccounts()
WebMethod actually returns that data back.
This is how I'm displaying the data passed back from GetAllAccounts()
, which works fine:
@{
Layout = "~/Shared/_Layout.cshtml";
Page.Title = "Accounts";
Page.Header = "BankSite Mobile - Accounts";
var svc = IntranetService.GetAllAccounts();
}
<div data-role="content">
<ul data-role="listview" data-inset="true" data-theme="c">
@foreach(var item in svc){
<li>
<h3><a href="[email protected]">Account #@item.AccountId.ToString() (@item.AccountType)</a></h3>
<p>Customer: @item.CustomerName</p>
<p>Account Balance: @item.Balance</p>
</li>
}
</ul>
</div>
Yet, this doesn't work fine, though it's the almost the exact same code:
@{
Layout = "~/Shared/_Layout.cshtml";
Page.Title = "Customers";
Page.Header = "BankSite Mobile - Customers";
var svc = IntranetService.GetAllCustomers();
}
<div data-role="content">
<ul data-role="listview" data-inset="true" data-theme="c">
@foreach(var item in svc){
<li>
<h3><a href="[email protected]">Account #@item.CustomerId.ToString() (@item.CustomerId)</a></h3>
<p>Customer: @item.CustomerId</p>
<p>Account Balance: @item.CustomerId</p>
</li>
}
</ul>
</div>
...So basically I'm baffled. I don't understand why the data isn't being returned as expected from the non-working WebMethod (GetAllCustomers()
). What am I missing?
+CONVERT(varchar(50), A.Balance, 1) AS Balance FROM Account A JOIN Account_Type AT ON A.Account_Type_Id=AT.Account_Type_Id JOIN Customer C ON A.Customer_Id=C.Customer_Id WHERE [Status]=1"))
{
while (reader.Read())
{
AccountItem item = new AccountItem();
item.AccountId = (int)reader["Account_Id"];
item.CustomerId = (int)reader["Customer_Id"];
item.CustomerName = (string)reader["CustomerName"];
item.AccountStatus = (bool)reader["Status"];
item.AccountType = (string)reader["AcctType"];
item.InitialBalance = (decimal)reader["Initial_Balance"];
item.InterestRate = (decimal)reader["Interest_Rate"];
item.Balance = (string)reader["Balance"];
items.Add(item);
}
reader.Close();
}
}
HttpContext.Current.Cache.Add(AccountItemsCacheKey, items.ToArray(), null, DateTime.Now.AddMinutes(CacheDuration), Cache.NoSlidingExpiration, CacheItemPriority.Default, null);
return items.ToArray();
}
else
{
return AccountItems;
}
}
And here's one that never returns data:
As you can see, they're almost identical. The SQL queries for both return a ton of records, but only the GetAllAccounts()
WebMethod actually returns that data back.
This is how I'm displaying the data passed back from GetAllAccounts()
, which works fine:
Yet, this doesn't work fine, though it's the almost the exact same code:
...So basically I'm baffled. I don't understand why the data isn't being returned as expected from the non-working WebMethod (GetAllCustomers()
). What am I missing?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您禁用从缓存加载内容,这两种方法是否总是成功返回预期结果集?我会先尝试一下,我的直觉是缓存有些奇怪(即在你的方法返回之前过期)。然后从那里出发。
If you disable loading stuff from the cache, would both methods always succeed to return expected result set? I would try that first, my gut feeling is that something funky with the cache (i.e expires before your method returns). Then go from there.
尝试通过直接在 Web 浏览器中访问 Web 服务来将问题隔离到 Web 服务。另外,如果可能,请使用 SQL Server Profiler 确保 Web 方法正在查询数据库。
如果它没有查询数据库,那么我猜它已经缓存了一个空数组。
因此,初始的“if (tranItems == null)”检查返回 false,但随后返回一个空数组作为结果。
Try to isolate the problem to the web service by accessing the web service directly in a web browser. Also, if possible, use SQL Server Profiler to make sure the web method is querying the database.
If it is not querying the database, then I would guess that it has already cached an empty array.
Therefore, the inital "if (tranItems == null)" check returns false, but it then returns an empty array as the results.
我发现问题是读取器检索到的某些字段为空,并且您无法创建空字符串。解决方案本质上是对每个项目属性使用类似的东西:
I found the issue to be that some fields retrieved by the reader were null, and you can't create a null string. The solution was essentially to use something like this for every item property: