Служба ASMX не всегда возвращает данные - PullRequest
1 голос
/ 02 февраля 2011

Я работаю со службой ASMX в ASP.NET/C#. Мой сервис возвращает правильные данные для некоторых моих WebMethods, но не для всех. Интересная часть - все WebMethods очень похожи.

Вот тот, который всегда возвращает данные:

[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="Product.cshtml?acctid=@item.AccountId">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="Product.cshtml?acctid=@item.CustomerId">Account #@item.CustomerId.ToString() (@item.CustomerId)</a></h3>
                    <p>Customer: @item.CustomerId</p>
                    <p>Account Balance: @item.CustomerId</p>
                </li>
            }
       </ul>
  </div>

... Так что в основном я сбит с толку. Я не понимаю, почему данные не возвращаются, как ожидалось, из нерабочего WebMethod (GetAllCustomers()). Чего мне не хватает?

Ответы [ 3 ]

1 голос
/ 02 февраля 2011

Если вы отключите загрузку содержимого из кэша, всегда ли оба метода вернут ожидаемый набор результатов? Я бы попробовал это в первую очередь, мое внутреннее чувство заключается в том, что с кешем что-то непонятное (т.е. истекает до того, как ваш метод возвращается). Тогда иди оттуда.

0 голосов
/ 08 февраля 2011

Я обнаружил, что проблема в том, что некоторые поля, извлеченные читателем, были нулевыми, и вы не можете создать пустую строку.По сути, решение было использовать что-то подобное для каждого свойства элемента:

item.Amount = (reader["Amount"] != DBNull.value) ? (decimal)reader["Amount"] : 0;
0 голосов
/ 02 февраля 2011

Попробуйте изолировать проблему от веб-службы, открыв веб-службу непосредственно в веб-браузере.Также, если возможно, используйте SQL Server Profiler, чтобы убедиться, что веб-метод запрашивает базу данных.

Если он не запрашивает базу данных, то я бы предположил, что он уже кэшировал пустой массив.

Следовательно, начальная проверка if (tranItems == null) возвращает false, но затем возвращает пустой массив в качестве результата.

...