PostAsJsonAsync C# - How to set headers correctly for POST request - BAD REQUEST 400

Viewed 2176

Hello to everyone out there.

I am having this next problem. I am trying to do a POST request but when I am compiling and executing it with the debugger of Visual Studio Code, I am getting an error of 400 Bad Request. Regardless of that, when I am doing the same POST request in Postman, I am getting a 200 OK status request with all the values that I need for continuing to the next part in which I am working on. enter image description here

Moreover, there is a Basic Auth in the request which in this case I am including it in Postman and it works fine. From the other side, in my script with C#, I am executing it like this:

*This is my model in which all my data is included for serializing the object into JSON.

 public class patientMediktor{
    public string deviceId { get; set; }        
    public string deviceType { get; set; }
    public string apiVersion { get; set; }
    public string language { get; set; }
    public externUserClass externUser{ get;set; }

    public class externUserClass{
        public externUserClass(string partnerExternalId, string username, string newPassword, string gender){
            this.partnerExternalId = partnerExternalId;
            this.username = username;
            this.newPassword = newPassword;
            this.gender = gender;
        }
        public string partnerExternalId { get; set; }
        public string username { get; set; }
        public string newPassword { get; set; }
        public string gender { get; set; }
    }
    public string includeAuthToken{ get; set; }
}

*This is my Helper class for creating the POST request. I insert all the data that I need and then I serialize the object to JSON as some of you have adviced me to do so. It is quite cleaner.

 public async Task<string> MediktorHubCrearUsuario(string conf, string userId, string sexo, string deviceId)
    {
        var sexoStr = "";  
        if(sexo == "MALE") {
            sexoStr = "MALE";
        } else if(sexo == "FEMALE") {
            sexoStr = "FEMALE";
        }

        var guid = Guid.NewGuid().ToString(); // guid para el username y el password
        var data = new patientMediktor();
        data.deviceId = userId;
        data.deviceType = "WEB";
        data.apiVersion = "4.0.3";
        data.language = "es_ES";
        data.externUser = new patientMediktor.externUserClass(userId, guid, guid, sexoStr); // extern user
        data.includeAuthToken = "true";

        string output = JsonConvert.SerializeObject(data);

        var ServerMedictor = conf;
        var client =  new HttpClient{BaseAddress = new Uri(ServerMedictor)};
        MediaType = "application/json";
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaType)); //ACCEPT header
        client.DefaultRequestHeaders.Authorization =  new AuthenticationHeaderValue("xxxxxx", "xxxxxxxxxxxx");
        var Client = client;
        var request = await Client.PostAsJsonAsync("externUser", output);

        request.EnsureSuccessStatusCode();
        var status = await request.Content.ReadAsStringAsync();
        return status;
    }

enter image description here

If anyone has any clue on how to deal with this, it would be really appreciating. I will keep trying combinations on how to tackle with an alternative on the issue. *Despite the modifications, I am still having the same issue. I did serialize the object and I am getting it the way I need to. But, whenever it comes to the request, it gives me a 400 Bad Request.

kind regards and thanks you

3 Answers

Try with PostAsync instead of 'PostAsJsonAsync'

var content = new StringContent(JsonConvert.SerializeObject(data), Encoding.UTF8, "application/json");

var request = await httpClient.PostAsync(requestUrl, content);

Please find more details on 'PostAsJsonAsync' at HttpClient not supporting PostAsJsonAsync method C#

It seems you should remove the comma of the end of the following lines:

sexoStr = "\"gender\": \"MALE\",";
...
sexoStr = "\"gender\": \"FEMALE\",";

Generally speaking, prefer working with model class and serializing them (using Newtonsoft.Json (example) or System.Text.Json), instead of hardcoded strings.

The answer is here. The construction of the header of Basic Auth was wrong from the beginning. In order to encode it, I had to pass it like this new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray)); and therefore to the request. I also replaced the PostAsJsonAsync with PostAsync. It works like a charm! Finally, I am getting a status code 200 OK with the data that I need to pass to my view.

public async Task<string> CreateUser(string conf, string userId, string sexo, string deviceId)
        {
            var sexoStr = "";  
            if(sexo == "MALE") {
                sexoStr = "MALE";
            } else if(sexo == "FEMALE") {
                sexoStr = "FEMALE";
            }

            var guid = Guid.NewGuid().ToString(); // guid para el username y el password
            var data = new patientMediktor();
            data.deviceId = userId;
            data.deviceType = "WEB";
            data.apiVersion = "4.0.3";
            data.language = "es_ES";
            data.externUser = new patientMediktor.externUserClass(userId, guid, guid, sexoStr); // extern user
            data.includeAuthToken = true;

            string json = JsonConvert.SerializeObject(data);
            var Client =  new HttpClient();
            var prueba = "https://xxxxxx.com:443/";
            Client.BaseAddress = new Uri(prueba);

            var byteArray = Encoding.ASCII.GetBytes("xxxxxxxx:xxxxxxxxx");
            Client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(byteArray));
            var response = Client.PostAsync("backoffice/services/externUser", new StringContent(json, Encoding.UTF8, "application/json")).Result;

            response.EnsureSuccessStatusCode();
            var respuesta = await response.Content.ReadAsStringAsync();
            return respuesta;
   }
Related