0

I am doing an MVC 5 Application, and I am calling a API controller method that is in another Solution.

I am using HttpClient(). and I am calling PostAsJsonAsync with some parameters, an instance of a class.

It looks like this.

string apiUrl = "localhost:8080/api/";
ContactWF contactWF = new contactWF();
contactWF.contact_id=0;
contactWF.UserOrigin_id=20006
contactWF.ProcessState_id=2;

using (HttpClient client = new HttpClient())
{
    client.BaseAddress = new Uri(apiUrl);
    client.DefaultRequestHeaders.Accept.Clear();
    client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
    HttpResponseMessage response = await client.PostAsJsonAsync(apiUrl + "Contact/Method", contactWF);
    if (response.IsSuccessStatusCode)
    {
        return response.Content.ReadAsAsync<int>().Result;
    }
}

My API controller method is like this.

[ActionName("Method")]
[HttpGet]
public int Method([FromBody] ContactWF userwf)
{
    return 10;
}

It Works fine...

My problem is when I try Serialized the parameter class instance I replace line

HttpResponseMessage response = await client.PostAsJsonAsync(apiUrl + "Contact/Method", contactWF);

with this one

string jsonData = JsonConvert.SerializeObject(contactWF);
HttpResponseMessage response = client.PostAsJsonAsync("api/Contact/Method", jsonData).Result;

I've got an Error:405...

It looks like the Json string it is not recognize as a Parameter.

My Json string looks like this.

"{\"Contact_id\":0,\"Description\":null,\"ProcessState_id\":2,\"Type_id\":0,\"Object_id\":0,\"Parent_id\":null}"

that is ContactWD class converter to json.

What´s wrong?

Diego
  • 2,238
  • 4
  • 31
  • 68

2 Answers2

1

Change verb to HttpPost in your api controller

[ActionName("Method")]
[HttpPost]
public int Method([FromBody] ContactWF userwf)
{
    return 10;
}

Update

You don't need to serialize object in PostAsJsonAsync

HttpResponseMessage response = client.PostAsJsonAsync("api/Contact/Method", contactWF).Result;

Take a look at sample code from microsoft https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/testing

internal class NewIdeaDto
    {
        public NewIdeaDto(string name, string description, int sessionId)
        {
            Name = name;
            Description = description;
            SessionId = sessionId;
        }

        public string Name { get; set; }
        public string Description { get; set; }
        public int SessionId { get; set; }
    }

//Arrange
var newIdea = new NewIdeaDto("Name", "", 1);

// Act
var response = await _client.PostAsJsonAsync("/api/ideas/create", newIdea);

// Assert
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
Hung Quach
  • 2,079
  • 2
  • 17
  • 28
  • Did you post to the correct URI? I see two different endpoint "Contact/Method" & "api/Filler/CountMensajeByUser" – Hung Quach Aug 08 '17 at 17:59
  • yes... I replaced the name for this example...thanks.. I have to put HttpGet, otherwise I got error 404... Method not found. But my principal problem is to serialized Json... – Diego Aug 08 '17 at 18:08
1

Method PostAsJsonAsync serialize parameter object himself, so it serialized your json string again.

If you need serialize object himself for some reason, then use method HttpClient.PostAsync

string jsonData = JsonConvert.SerializeObject(contactWF);
var stringContent = new StringContent(jsonData, Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync("api/Filler/CountMensajeByUser", stringContent);
  • Thanks... So i was serialzing twice... but, what I do not understand is that if I am using PostAsJsonAsync, In api controller Method I should get a string? becouse now, i get an instance of the same class... Thanks – Diego Aug 08 '17 at 18:18
  • Web Api deserialize request json body to method argumet class. If you'll declare it as `public int Method([FromBody] string userwf)` then your second variant with twice serialized object will work and you'll get in userwf serialized object. – Vitaliy Smolyakov Aug 08 '17 at 18:27