1

I have created POST/GET request in MVC before.

In my HomeController

    [HttpPost]
    public string Index(int Value)
    {
        return Value.ToString();
    }

And setting chrome extension POSTMAN with a form-data

I can call http://localhost/mvcApp/ with a variable 'Value' with value '1' and get a string '1' in return

But when I create a surveyController : ApiController doesn't work when I call http://localhost/mvcApp/api/survey/

    public string Post(int Value)
    {
        return Value.ToString();
    }

"Message": "No HTTP resource was found that matches the request URI 'http://localhost/mvcApp/api/survey/'.",

"MessageDetail": "No action was found on the controller 'survey' that matches the request."

I'm not sure if the error is in the way the api is created, or in the way the POSTMAN is trying to call the api. Because that '.'

Also try in my HomeControler Index

client.BaseAddress = new Uri("http://localhost/mvcApp");
var result = client.PostAsync("/api/survey", new
{
   Value = 1                    
}, new JsonMediaTypeFormatter()).Result;

if (result.IsSuccessStatusCode) // here return Not found
Juan Carlos Oropeza
  • 47,252
  • 12
  • 78
  • 118

2 Answers2

3

The WebApi controllers' conventions are not the same as those of plain ol' MVC controllers.

Basically the problem is that you can't specify the int parameter the way you did.

Try this in you WebApi controller:

// nested helper class
public class PostParams {
    public int Value { get; set; }
} 

public string Post(PostParams parameters) {
    return parameters.Value.ToString();
}

and see how that works.

Here's a thorough article on passing parameters within POST requests to WebAPI controllers: Passing-multiple-POST-parameters-to-Web-API-Controller-Methods

Long story short, these are the conventions, roughly speaking:

  • you can't capture POST form name-value pairs in parameters
  • you can capture them inside the properties of a class if that class is the parameter type of one of your method's parameters
  • you can capture query parameters in method parameters

EDIT

If you wish to test your WebAPI server using C# you could follow these steps:

  1. Create a nice Console Application (preferably within the same solution)
  2. Add the Web API Client NuGet package to this Console Application
  3. Make your Program.cs do something like this.

The following code uses the C# 5.0 async and await operators. It also uses the Task class and anonymous types. I've pointed out official MSDN articles (click on the links) should you be interested in what those things are.

using System.Net.Http;
using System.Threading.Tasks;

namespace ConsoleApplication1 {
    class Program {

        public static void Main(string[] args) {
            Test().Wait();
        }

        private static async Task Test() {
            HttpClient client = new HttpClient();

            await client.PostAsJsonAsync(
                "http://localhost/mvcApp/api/survey/",
                new {
                    value = 10
                }
            );
        }

    }
}
Eduard Dumitru
  • 3,242
  • 17
  • 31
  • At least im getting an error because doesnt understand PostParams. So doesnt look like a Route problem. Let me investigate how pass an object with POSTMAN – Juan Carlos Oropeza Mar 12 '15 at 21:25
  • Where exactly did you place the `PostParams` class? – Eduard Dumitru Mar 12 '15 at 21:26
  • Inside of surveyController, I think the POST function is ok. Now how I test it? I have been using POSTMAN, but dont know how to pass a PostParam object – Juan Carlos Oropeza Mar 12 '15 at 21:29
  • What is the error you were receiving earlier. You said "it" didn't understand `PostParams`. Personally I've never used POSTMAN but it sounds alright. What I prefer is programmatically sending POST requests via the `HttpClient` class from within an Nunit test, right there, in Visual Studio, side by side with the server project – Eduard Dumitru Mar 12 '15 at 21:34
  • ExceptionMessage": "No MediaTypeFormatter is available to read an object of type 'PostParams' from content with media type 'text/plain'.", – Juan Carlos Oropeza Mar 12 '15 at 21:37
  • I will follow your link tutorial, and use Ajax to make the test. And I also will check the Nunit, i havent use it any test framework yet. – Juan Carlos Oropeza Mar 12 '15 at 21:41
  • Ok. That settles it. It's not the WebAPI (anymore) and it's not POSTMAN. It's how you're using POSTMAN. You said in your question (and I quote) that you're sending "form-data". In that case you should specify that the Content-Type is `application/x-www-form-urlencoded`. In your case, that is set (probably by default) to `text/plain`. – Eduard Dumitru Mar 12 '15 at 21:41
  • You could also (and I personally recommend this) send JSON instead of form-data. That will fit it nicely later on. Should you prefer to send JSON, make sure that your request's payload / body looks like this `{ value: 10 }` and that the Content-Type (or mime type or media type) is set to "application/json". Good luck! – Eduard Dumitru Mar 12 '15 at 21:43
  • Check the latest edit for testing things in C#. I didn't create an Nunit sample but rather a more direct Console Application approach. – Eduard Dumitru Mar 12 '15 at 22:02
  • Solve the issue, check my final solution. Thanks for your help – Juan Carlos Oropeza Mar 13 '15 at 04:13
0

This wasnt easy. After lot of reading I solve it like this.

First the api controler need to define the input parameter with the [FromBody] attribute

// POST api/survey
public void Post([FromBody]string value)
{
}

For testing I put a button in the view and use an Ajax / Post, the variable name need to be an empty string before the variable value.

$(document).ready(
    $('#post').click(function () {
        var url = 'http://localhost/mvcApi/api/survey';
        var data = { "": 'Hola' };  // Define a simple variable this way

        $.ajax({
            type: "POST",
            url: url,
            data: data,
            success: sucess
            }
        });
    })

Or if you want send mutliple values

data = { "": ["update one", "update two", "update three"] }; 

enter image description here

But if you want receive an object

public void Post(Survey data)
{
   string value = data.Value.ToString();
}

$('#post').click(function () {
   ....
   var data =   { value: 25 }

More info here Sending Data and here Binding

Community
  • 1
  • 1
Juan Carlos Oropeza
  • 47,252
  • 12
  • 78
  • 118