ASMX 服务并不总是返回数据

发布于 2024-10-15 08:55:15 字数 5842 浏览 4 评论 0原文

我正在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

深巷少女 2024-10-22 08:55:15

如果您禁用从缓存加载内容,这两种方法是否总是成功返回预期结果集?我会先尝试一下,我的直觉是缓存有些奇怪(即在你的方法返回之前过期)。然后从那里出发。

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.

旧时浪漫 2024-10-22 08:55:15

尝试通过直接在 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.

未蓝澄海的烟 2024-10-22 08:55:15

我发现问题是读取器检索到的某些字段为空,并且您无法创建空字符串。解决方案本质上是对每个项目属性使用类似的东西:

item.Amount = (reader["Amount"] != DBNull.value) ? (decimal)reader["Amount"] : 0;

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:

item.Amount = (reader["Amount"] != DBNull.value) ? (decimal)reader["Amount"] : 0;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文