WebMethod 异步结果显示对象

Posted

技术标签:

【中文标题】WebMethod 异步结果显示对象【英文标题】:WebMethod async Results Show Object 【发布时间】:2016-08-30 14:35:40 【问题描述】:

我正在尝试使用异步返回结果,但不是返回我想要的数据,而是返回整个对象

[System.Web.Services.WebMethod(BufferResponse=false)]
public static async Task<bool> getLogin(string username, string password)

    Login login = new Login();
    Task<bool> loginVerify = login.verifyLogin(username,password);
    await loginVerify;
    return loginVerify.Result;


public class Login

    public async Task<bool> verifyLogin(string username, string password)
    
        return true;
    

Firefox Firebug 的结果表明:

"d":"Result":true,"Id":2,"Exception":null,"Status":5,"IsCanceled":false,"IsCompleted":true,"CreationOptions":0,"AsyncState":null,"IsFaulted":false

为什么不只是显示结果?

我试过跑步

public static async Task<bool> getLogin(string username, string password)

    Login login = new Login();
    Task<bool> loginVerify = login.verifyLogin(username,password);
    await loginVerify;
    return false;

但萤火虫报告是一样的,只是它在 json 中说 Result false

"d":"Result":false,"Id":2,"Exception":null,"Status":5,"IsCanceled":false,"IsCompleted":true,"CreationOptions":0,"AsyncState":null,"IsFaulted":false

所以我的问题是为什么它显示整个对象而不是结果?

【问题讨论】:

WebMethods 是否支持async-await 我假设是这样,因为我得到了结果并且在结果中我得到了正确的答复。它只是不断发送整个对象,而不仅仅是结果。对我来说有点莫名其妙..... 这告诉我不支持async-await。你应该阅读更多关于async-await的信息。 我会假设如果不支持它会返回答案。我的意思是不要误会我的意思,我可以在 jquery 中对对象进行排序并得到结果,但我希望有人知道为什么它返回完整的对象,然后只返回数据。 【参考方案1】:

正如this answer 中所解释的,WebMethod 不支持async-await(它确实支持另一种异步模式,APM,您可以将async-await 转换为APM,但它相当尴尬)。

那么为什么你会得到这么奇怪的结果呢? WebMethod 不知道 Task 是某种特殊类型,因此它通过访问和序列化其属性来将其视为常规对象。这包括Result,它同步返回Task 的结果。这也意味着代码实际上并不是异步的。

【讨论】:

【参考方案2】:

请在返回之前将结果转换为 json。您可以使用任何 json 转换为该结果

[System.Web.Services.WebMethod(BufferResponse=false)]
public static async Task<bool> getLogin(string username, string password)

    Login login = new Login();
    Task<bool> loginVerify = login.verifyLogin(username,password);
    await loginVerify;
    var result= new javascriptSerializer().Serialize(loginVerify.Result);
    return result;

【讨论】:

别忘了添加对 System.Web.Extensions 的引用 我关注了这个,但它仍然给了我完整的对象,而不仅仅是结果这是我从你发布的代码中得到的回复"d":"Result":"true","Id":2,"Exception":null,"Status":5,"IsCanceled":false,"IsCompleted":true,"CreationOptions" :0,"AsyncState":null,"IsFaulted":false 这不会编译:result 是一个string,但它需要是bool 才能编译。尝试序列化 Task 对我来说没有任何意义。 它为我编译。我只是将任务从 bool 更改为 string @ArcSet 但是你没有在你发布的代码中改变它。【参考方案3】:

这很简单,考虑以下几点:

[System.Web.Services.WebMethod(BufferResponse=false)]
public static async Task<bool> getLogin(string username, string password)

    Login login = new Login();
    Task<bool> loginVerify = login.verifyLogin(username, password);
    return await loginVerify;


public class Login

    public async Task<bool> verifyLogin(string username, string password)
    
        return true;
    

getLogin 被调用时,它将实例化Login 类并调用.verifyLogin 方法,这将返回一个Task&lt;bool&gt;——这意味着它是“可等待的”。当您await 它时,您将获得boolean 结果值。

这可以简化为返回Task&lt;bool&gt; 批发,因为有一个Task 有问题。将Task 视为单个异步操作并返回它——允许消费者await 它:

[System.Web.Services.WebMethod(BufferResponse=false)]
public static Task<bool> getLogin(string username, string password)

    Login login = new Login();
    return login.verifyLogin(username, password);


async Task FooBar()

    boolean isLoggedIn = await _loginService.getLogin(this.Username, this.Password);

备注

    尽量避免使用Task.Result,即使它已被等待。 后缀异步方法(TaskTask&lt;T&gt; 返回)带有“Async”。

【讨论】:

我运行了它,它仍然将完整的对象返回给浏览器。 Firebug 结果"d":"Result":true,"Id":2,"Exception":null,"Status":5,"IsCanceled":false,"IsCompleted":true,"CreationOptions" :0,"AsyncState":null,"IsFaulted":false 你建议我需要做什么来配置 JSON。 我不确定萤火虫在做什么,但我认为这是不正确的,***.com/questions/18367054/…。这是一个按您预期工作的示例。【参考方案4】:

我知道我迟到了,但只是想分享一个解决方案。 在 Javascript 中,我们可以使用 response.d.Result 从 c# 获取实际字符串。 例如:

success: function (response) 
                    var gJson = eval(response.d.Result);
                    console.log(gJson);

【讨论】:

以上是关于WebMethod 异步结果显示对象的主要内容,如果未能解决你的问题,请参考以下文章

从 ajax 调用到 javascript 日期的 ASP.NET 解析 DateTime 结果

webmethod结果中的文本框值没有改变

Webmethod jquery ajax调用不返回任何结果

通过jquery ajax将json对象传递给webmethod

在 WebMethod 中设置 Session 对象(使用 EnableSession = true)不存储值

如何使用 AJAX (jquery) 将嵌套的对象数组传递和接收到 c# WebMethod 中?