0

I don't know how send values strings or models to a HttpPost-action

I want to send a value to a HttpPost-action in a API. He reach the HttpPost-action. But the value of parameter name is NULL. What do I wrong?

By example the value of "name" = "Netherlands".

public async Task<long> UpdateCountry(string name)
{
    string url = $"{myApi}/Address/UpdateCountry";
    var model = JsonConvert.SerializeObject(new KeyValuePair<string, string>("name", name));
    long id = await Post(url, model);

    return id;
}

than the process starts in the BaseClass... in the function Post.

protected async Task<dynamic> Post(string url, string data)
{
    var client = new HttpClient();

    var httpContent = new StringContent(data);
    HttpResponseMessage responseMessage = await client.PostAsync(url, httpContent);

    var result = await responseMessage.Content.ReadAsStringAsync();

    return JsonConvert.DeserializeObject<dynamic>(result);
}

And in the API the value of parameter name is NULL.

[HttpPost("UpdateCountry")]
    public async Task<long> UpdateCountry(string name)
    {
        var countryId = _countryService.GetIdByName(name);

        if (countryId == null)
        {
            var dto = new CountryDto() { Name = name };
            ....
            countryId = await _countryService.Insert(dto);
        }
        else
{
dto.Name = name;
            countryId = await _countryService.Update(dto);
}
        return countryId.Value;
    }

enter image description here

ADyson
  • 57,178
  • 14
  • 51
  • 63
user1531040
  • 2,143
  • 6
  • 28
  • 48
  • 1
    Does this answer your question? [POSTing JsonObject With HttpClient From Web API](https://stackoverflow.com/questions/6117101/posting-jsonobject-with-httpclient-from-web-api). (Although of course you're not obliged to send it as JSON, you could use form-url-encoded format instead if you wish). – ADyson Aug 04 '22 at 08:31
  • I change the code to this: var httpContent = new StringContent(data, Encoding.UTF8, "application/json"); Same result... – user1531040 Aug 04 '22 at 08:35
  • Tip: Don't ever use `dynamic` unless you really know what you're doing. In this case, it's a hack. Instead use generics, it's much safer. Remember, every time you use `dynamic`, a kitten dies! – DavidG Aug 04 '22 at 08:36
  • Also, is this really your code? None of this would compile. For example, the action method only takes a country name, but what are you actually updating and what is `dto`? Please post actual code. – DavidG Aug 04 '22 at 08:38
  • dto is a data-object. It doesn't mind what it means. That's not the problem. The parameter name is NULL. This value has to have the value "Netherlands". – user1531040 Aug 04 '22 at 08:41
  • It absolutely does matter because this cannot be your real action method. To update a country, you surely need to pass the old value (to do the lookup) and the new value so you can make the change. This code doesn't make sense and nobody can really help you with it until you provide a [mre] – DavidG Aug 04 '22 at 08:42
  • I have edited the code with an example of dto. – user1531040 Aug 04 '22 at 08:49
  • That is even less possible to compile than the original. I'm not going to beg for code any more, good luck finding your answer from someone else. – DavidG Aug 04 '22 at 08:52
  • 1
    @DavidG I agree the action method as shown is a mess (doesn't compile and the logic for deciding whether to update or insert is nonsense) but I actually don't think it's relevant to the specific issue the OP is asking about, which is why the "name" value seemingly isn't being passed correctly from the HTTP request to the parameter in the action method. – ADyson Aug 04 '22 at 09:07
  • 1
    @user1531040 you may need to write `UpdateCountry([FromBody] string name)` in the action method definition as well, or even wrap it in a simple object - see https://stackoverflow.com/questions/37842231/webapi-2-post-with-single-string-parameter-not-working – ADyson Aug 04 '22 at 09:11
  • Thank you ADyson. I need FromBody and this is a string text. So I had to use mediatype "text/json". For a model I need mediatype in StringContent => "application/json". – user1531040 Aug 04 '22 at 09:34
  • 1
    Great. You should post your complete solution as an Answer below for the benefit of anyone with a similar problem, and also so you can collect upvote points for it :-) – ADyson Aug 04 '22 at 11:30

1 Answers1

0

in the Client

public async Task<long> UpdateCountry(string name)
{
    string url = $"{myApi}/Address/UpdateCountry";
    var json = JsonConvert.SerializeObject(name);
    long id = await Post(url, json, "text/json"); // or "application/json" when  you use a model.

    return id;
}

... and the BaseClass

protected async Task<dynamic> Post(string url, string data, string mediaType)
{
    var client = new HttpClient();
    var content = new StringContent(data, Encoding.UTF8, mediaType);
    var response = await client.PostAsync(url, content);
    if (response.IsSuccessStatusCode)
    {
        var result = await response.Content.ReadAsStringAsync();
        return JsonConvert.DeserializeObject<dynamic>(result);
    }

    return null;
}

... and in the API

    [HttpPost("UpdateCountry")]
    public async Task<long> UpdateCountry([FromBody] string name)
    {
        var countryId = _countryService.GetIdByName(name);

        if (!countryId.HasValue)
        {
            var dto = new CountryDto() { Name = name };
            ....
            countryId = await _countryService.Insert(dto);
        }
        else
        {
            ....
            dto.Name = name;
            countryId = await _countryService.Update(dto);
        }

        return countryId.Value;
    }
user1531040
  • 2,143
  • 6
  • 28
  • 48