1

I am trying to return results using async but instead of returning the data I want it returns the entire object

[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;
    }
}

The results from Firefox Firebug show this :

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

Why isn't it just showing the result?

I tried running

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;
}

but the firebug report was the same except it said Result false in the json

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

So my question is why does it show the whole object instead of just the result?

svick
  • 236,525
  • 50
  • 385
  • 514
ArcSet
  • 6,518
  • 1
  • 20
  • 34
  • 1
    Do WebMethods support `async-await`? – Paulo Morgado May 04 '16 at 23:40
  • I assume so since I am getting results and in the results I have the correct reply. It just keeps sending the entire object instead of just the Result. Its kinda of baffling to me..... – ArcSet May 04 '16 at 23:55
  • 2
    That tells me that `async-await` is not supported. And you should read more about `async-await`. – Paulo Morgado May 05 '16 at 08:39
  • i would assume if it wasn't supported it would return the answer. I mean don't get me wrong I could sort through the object in jquery and get the result but I was hoping someone knew why it returns the full object then just the data. – ArcSet May 05 '16 at 13:52

4 Answers4

5

As explained in this answer, WebMethod does not support async-await (it does support another async pattern, APM, and you can convert async-await to APM, but it's quite awkward).

So why do you get such weird result? WebMethod does not know that Task is some special type, so it treats it just like a regular object, by accessing and serializing its properties. This includes Result, which synchronously returns the result of the Task. This also means that the code is not actually asynchronous.

Community
  • 1
  • 1
svick
  • 236,525
  • 50
  • 385
  • 514
0

please convert the result to json before returning it.You can use any json convert to that

[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;
}
suulisin
  • 1,414
  • 1
  • 10
  • 17
  • dont forget to add reference to System.Web.Extensions – suulisin May 04 '16 at 23:41
  • I followed this but it still gives me the full object instead of just the result Here is the reply i got from the code you posted `{"d":{"Result":"true","Id":2,"Exception":null,"Status":5,"IsCanceled":false,"IsCompleted":true,"CreationOptions" :0,"AsyncState":null,"IsFaulted":false}}` – ArcSet May 04 '16 at 23:52
  • This won't compile: `result` is a `string`, but it needs to be `bool` to compile. And trying to serialize a `Task` doesn't make any sense to me. – svick May 05 '16 at 10:14
  • it compiled for me. I just changed the Task from bool to string – ArcSet May 05 '16 at 13:50
  • @ArcSet But you didn't change that in the code you posted. – svick May 05 '16 at 14:33
0

This is rather simple, consider the following:

[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;
    }
}

When getLogin is invoked it will instantiate the Login class and call into the .verifyLogin method, this returns a Task<bool> -- which means it's "awaitable". When you await it, you are given the boolean result value.

This could be simplified to return the Task<bool> wholesale, since there is a single Task in question. Treat the Task as a single asynchronous operation and return it -- allowing the consumer to await it:

[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);
}

Notes

  1. Try to avoid using Task.Result, even if it has been awaited.
  2. Postfix async methods (Task or Task<T> returning) with "Async".
David Pine
  • 23,787
  • 10
  • 79
  • 107
  • I ran this and it still returns the full object to the browser. Firebug results `{"d":{"Result":true,"Id":2,"Exception":null,"Status":5,"IsCanceled":false,"IsCompleted":true,"CreationOptions" :0,"AsyncState":null,"IsFaulted":false}}` – ArcSet May 05 '16 at 13:49
  • What would you suggest I would need to do to get JSON configured. – ArcSet May 05 '16 at 13:57
  • I'm not sure what firebug is doing but I believe that it's incorrect, http://stackoverflow.com/questions/18367054/creating-an-async-webservice-method. This is an example of it working as you'd expect. – David Pine May 05 '16 at 14:06
0

I know I am late, but just want to share a solution. in Javascript we can use response.d.Result to get actual string from c#. For example:

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