简体   繁体   中英

MobileServiceClient MobileServiceInvalidOperationException Response Content is null

I'm using the following code in a Xamarin Forms app:

HttpResponseMessage response = null;

try
{
    HttpContent content = new StringContent(JsonConvert.SerializeObject(register), Encoding.UTF8, "application/json");

    response = await client.InvokeApiAsync("register", content, HttpMethod.Post, null, null);

    if (!response.IsSuccessStatusCode)
    {
        string error = await response.Content.ReadAsStringAsync();

        var def = new { Message = "" };
        var errorMessage = JsonConvert.DeserializeAnonymousType(error, def);

        return KloverResult.BuildError(true, errorMessage.Message);
    }
}
catch (MobileServiceInvalidOperationException e)
{
    if (e.Response.StatusCode == System.Net.HttpStatusCode.InternalServerError)
    {
        string error = await e.Response.Content.ReadAsStringAsync();

        var def = new { Message = "" };
        var errorMessage = JsonConvert.DeserializeAnonymousType(error, def);

        return KloverResult.BuildError(true, errorMessage.Message);
    }
    else
    {
        return KloverResult.BuildError(false, "Invalid username or password");
    }
}

The issue that I'm having is when a MobileServiceInvalidOperationException is thrown as a result of a 500. When I try to read the content of the response (e.Response.Content) it's null. When I call the same API using Restlet I get the following response:

{
"Message": "Name jblogs is already taken."
}

This is what I expect to be in my error variable, however it's null.

My question is, should I be able to read the Content of the Response? If so, do I need to do some more setup on the client/server? The API being called is returning the error form a webapi using:

Request.CreateErrorResponse(HttpStatusCode.InternalServerError, "Name jblogs is already taken.");

Any help would be appreciated.

A 500 response means that the server crashed. It's likely that there was no content in that case.

If your API is returning status=500, then it is doing the wrong thing. What you should be doing is returning a status in the 400 series - 409 (conflict) seems appropriate to me.

If your API is not returning status=500 deliberately, then the server crashed and you don't get content.

According to your description, I built my Mobile App application with a custom WebApi endpoint to test this issue. Based on my test, I leverage Microsoft.Azure.Mobile.Client 3.1.0 to invoke custom WebApi, I could retrieve the content by Response.Content.ReadAsStringAsync() when the response status is 409 or 500 and so on. Here are my code snippet, you could refer to them:

WebApi

[MobileAppController]
public class ValuesController : ApiController
{
    public async Task<HttpResponseMessage> Get()
    {
        await Task.Delay(TimeSpan.FromSeconds(2));
        return Request.CreateErrorResponse(HttpStatusCode.Conflict, "Name jblogs is already taken.");
    }
}

Client App

try
{
    MobileServiceClient client = new MobileServiceClient("https://bruce-chen-002.azurewebsites.net/");
    var response = await client.InvokeApiAsync("/api/values", HttpMethod.Get, null);
}
catch (MobileServiceInvalidOperationException e)
{
    if (e.Response.StatusCode == System.Net.HttpStatusCode.InternalServerError)
    {
        string error = await e.Response.Content.ReadAsStringAsync();
    }
}

Result

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM