3

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

Oris Sin
  • 834
  • 10
  • 26
  • 1
    I would ignore any errors you are getting in VS until you fix the the response status of 400 and get a 200 OK. The error is due to the server not liking the request so any processing of the response is meaningless. The default headers in c# are different from Postman. The best way of debugging is to use a sniffer like wireshark or fiddler and compare the Postman headers with the c# headers. Then make c# look like Postman. There are many reasons for the 400 error. Often it is just adding the User Agent header which specifies the type of browser your code is emulating. – jdweng Dec 22 '20 at 13:57

3 Answers3

2

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#

1

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.

OfirD
  • 7,020
  • 2
  • 33
  • 68
  • That's one thing, I already did it. My machine for some reason is still caching the request from before (with the comma included). I cleared my cache and cookies but there is something weird there that is still persistent. I will try serializing my JSON also. Will let you know if it worked. Thanks – Oris Sin Dec 22 '20 at 13:54
  • Hard to believe that the POST request is cached ([see this](https://stackoverflow.com/questions/626057/is-it-possible-to-cache-post-methods-in-http)). Do you have access to the server-side so that you could see the incoming request? if not, you should probably just use [fiddler](https://stackoverflow.com/questions/57228186/how-to-capture-visual-studio-code-traffic-through-fiddler) or wireshark to see it. – OfirD Dec 22 '20 at 14:25
1

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;
   }
Oris Sin
  • 834
  • 10
  • 26