0
votes

I'm developing an app in Xamarin.Forms (Shared Project Library) that sends a list of custom types (just a document number and a file type enumeration) to a locally hosted API.

If I capture the JSON string and send it from Postman, everything works fine, but as soon as I run the httpClient.PostAsync from the app, I receive the following error:

{StatusCode: 500, ReasonPhrase: 'Internal Server Error', Version: 1.1, Content: System.Net.Http.StreamContent, Headers: { Cache-Control: no-cache Pragma: no-cache Server: Microsoft-IIS/7.5 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Date: Thu, 25 May 2017 16:00:44 GMT Content-Type: application/json; charset=utf-8 Expires: -1 Content-Length: 36 }}

I'm at a loss a to what I'm doing wrong. Can anyone help, please?

Type:

class EmailFiles
{
    public string docNumber { get; set; }
    public EmailFileTypes.EmailFileType type { get; set; }
}

Request:

        List<EmailFiles> files = new List<EmailFiles>();

        if (chkShipping.IsToggled)
        {
            EmailFiles file = new EmailFiles();
            file.type = EmailFileTypes.EmailFileType.CustomerFile;
            file.docNumber = Helpers.GlobalVariables.gSOLookup.PackList;
            files.Add(file);
        }
        if (chkClosed.IsToggled)
        {
            EmailFiles file = new EmailFiles();
            file.type = EmailFileTypes.EmailFileType.ClosedFile;
            file.docNumber = Helpers.GlobalVariables.gSOLookup.Invoice;
            files.Add(file);
        }
        if (chkInvoice.IsToggled)
        {
            EmailFiles file = new EmailFiles();
            file.type = EmailFileTypes.EmailFileType.Invoice;
            file.docNumber = Helpers.GlobalVariables.gSOLookup.Invoice;
            files.Add(file);
        }

        string url = SetUrls.urlMtApi + "/api/EmailFile/?emailAddresses=" + strEmails;

        string strJson = JsonConvert.SerializeObject(files);
        //Results in: "[{\"docNumber\":\"234273\",\"type\":1},{\"docNumber\":\"633007\",\"type\":2}]" - which works in Postman!!

        StringContent content = new StringContent(strJson, Encoding.UTF8, "application/json");

        HttpClient httpClient = new HttpClient();
        HttpResponseMessage response = await httpClient.PostAsync(url, content);

Web Service:

[System.Web.Http.HttpPost]
public string EmailFile([FromBody]string jsonfiles, [FromUri] string emailAddresses)
    {
        List<EmailFiles> files = JsonConvert.DeserializeObject<List<EmailFiles>>(jsonfiles);
        ...
    }
1
You need to debug that 500 error server side. That means the server is throwing an exception somewhere. - Federico Dipuma

1 Answers

2
votes

No need to manually deserialize the json body, just let the model binder do it for you by using correct parameters:

[System.Web.Http.HttpPost]
public MyModelReturnType EmailFile([FromBody] List<EmailFiles> files, [FromUri] string emailAddresses)
{
     // the framework has already deserialized the json request for you
}

If you use string instead of the true model for your parameter the server will not be able to bind your request body to it, because it will expect a JSON string (surrounded by double quotes "), and this could cause a model binding exception that will lead to a 500 error in your client.

The same is for the return type, just use whatever class you want your client to receive as return type and do not use string if you want to send it Json.