1

I am learning to create a RESTful API with a client, but am struggling with passing user input to the post. My controller is fine as I can send data to db (tested with Swagger) but on the client side the debugger is giving me an error on my PostAsJsonAsync. I think it probably has to do with the routing. Here is my post code from my client:

static async Task AddAsync(ForumPost fp)
{
    try
    {
        using (HttpClient client = new HttpClient())
        {
            client.BaseAddress = new Uri("http://localhost:7656/");

            client.DefaultRequestHeaders.Accept
                      .Add(new MediaTypeWithQualityHeaderValue("application/json"));

            // HTTP POST
            ForumPost thePost = new ForumPost() { 
                                    Subject = fp.Subject, 
                                    Message = fp.Message};
            HttpResponseMessage response = await client.PostAsJsonAsync("post", thePost);
            if (response.IsSuccessStatusCode)
            {
                Uri uri = response.Headers.Location;
                Console.WriteLine("URI for new resource: " + uri.ToString());
            }
            else
            {
                Console.WriteLine(response.StatusCode + " " + response.ReasonPhrase);
            }
        }
    }
    catch (Exception e)
    {
        Console.WriteLine(e.ToString());
        Console.ReadLine();
    }
}

and the relevant bit of the controller

[HttpPost]
// POST: api/Forum
[Route("post")]
public void PostNewMessage (string subject, string message)
{
    if (ModelState.IsValid)
    {
        ForumPost p = new ForumPost(subject, message);
        db.ForumPosts.Add(p);
        db.SaveChanges();
    }
}

I have looked around at various different but similar questions here on SO but struggling to understand. I have tried putting placeholders in the route but maybe I implemented it incorrectly? (that's if that is even the correct way to be thinking!) If anyone could help me out on this I would appreciate it.

Todd Menier
  • 37,557
  • 17
  • 150
  • 173
Inkers
  • 219
  • 7
  • 27

1 Answers1

1

When your Web API action parameters are simple types like strings, the parameter binding mechanism assumes they are coming from the query string. To infer that the values should come from the request body, just use your ForumPost class directly as your parameter instead of the individual string values:

[HttpPost]
// POST: api/Forum
[Route("post")]
public void PostNewMessage(ForumPost p)
{
    if (ModelState.IsValid)
    {
        db.ForumPosts.Add(p);
        db.SaveChanges();
    }
}

Also note that ForumPost needs a parameterless constructor in order for the framework to know how to create an instance. Define it like this and you should be good:

public class ForumPost 
{
    public string Subject { get; set; }
    public string Message { get; set; }
}
Todd Menier
  • 37,557
  • 17
  • 150
  • 173
  • Hi Todd,Thanks for reply. I tried to implement what you said but to no avail. I'm not sure that this was the (biggest!) problem anyway. Even when I hard code a new post in the client and pass it to PostAsJsonAsync I am getting an error. It is a socket error exception: "System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it 127.0.0.1:23226\r\n...etc – Inkers Mar 04 '16 at 13:20
  • That's a networking issue and if you google that exception message you'll find no shortage of results, like [this one](http://stackoverflow.com/questions/9695224/no-connection-could-be-made-because-the-target-machine-actively-refused-it-127-0) for example. Though I'm confident my suggested fix was also needed to get this working. – Todd Menier Mar 04 '16 at 14:12
  • Thanks again Todd, Simple typo in the end - wrong port number. Yes, I have now implemented your suggestions and my post is now working. – Inkers Mar 04 '16 at 14:23