17

I have this very simple C# APIController named "TestController" with an API method as:

[HttpPost]
public string HelloWorld([FromBody] Testing t)
{
    return t.Name + " " + t.LastName;
}

Contact is just a class that look like this:

public class Testing
{
    [Required]
    public string Name;
    [Required]
    public string LastName;
}

My APIRouter looks like this:

config.Routes.MapHttpRoute(
     name: "TestApi",
     routeTemplate: "api/{controller}/{action}/{id}",
     defaults: new { id = RouteParameter.Optional }
);

QUESTION 1:
How can I test that from a C# Client?

For #2 I tried the following code:

private async Task TestAPI()
{
    var pairs = new List<KeyValuePair<string, string>> 
    {
       new KeyValuePair<string, string>("Name", "Happy"),
       new KeyValuePair<string, string>("LastName", "Developer")
    };

    var content = new FormUrlEncodedContent(pairs);

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

        var result = await client.PostAsync( 
             new Uri("http://localhost:3471/api/test/helloworld", 
                    UriKind.Absolute), content);

        lblTestAPI.Text = result.ToString();
    }

QUESTION 2:
How can I test this from Fiddler?
Can't seem to find how to pass a Class via the UI.

SF Developer
  • 5,244
  • 14
  • 60
  • 106

1 Answers1

29

For Question 1: I'd implement the POST from the .NET client as follows. Note you will need to add reference to the following assemblies: a) System.Net.Http b) System.Net.Http.Formatting

public static void Post(Testing testing)
    {
        HttpClient client = new HttpClient();
        client.BaseAddress = new Uri("http://localhost:3471/");

        // Add an Accept header for JSON format.
        client.DefaultRequestHeaders.Accept.Add(
            new MediaTypeWithQualityHeaderValue("application/json"));

        // Create the JSON formatter.
        MediaTypeFormatter jsonFormatter = new JsonMediaTypeFormatter();

        // Use the JSON formatter to create the content of the request body.
        HttpContent content = new ObjectContent<Testing>(testing, jsonFormatter);

        // Send the request.
        var resp = client.PostAsync("api/test/helloworld", content).Result;

    }

I'd also rewrite the controller method as follows:

[HttpPost]
public string HelloWorld(Testing t)  //NOTE: You don't need [FromBody] here
{
  return t.Name + " " + t.LastName;
}

For Question 2: In Fiddler change the verb in the Dropdown from GET to POST and put in the JSON representation of the object in the Request body

enter image description here

Abhijeet Patel
  • 6,562
  • 8
  • 50
  • 93
  • 1
    Unfortunately, if I remove [FromBody] the Fiddler does NOT find it and gets a 404. The C# client code does NOT get a response either way. – SF Developer Oct 16 '13 at 15:49
  • 1
    [FromBody] is needed when you are passing a Content-Type: application/json. If you remove that, you will need to pass a Content-Type: application/x-www-form-urlencoded – SF Developer Oct 16 '13 at 18:13
  • Is there a reason why you are using URL encoded content instead of using "Content-type:application.json" which enables specifying the payload in the body? For complex types you want to use the body and not the query string. Do you have multiple POST actions defined in your controller? Can you post the full controller code? – Abhijeet Patel Oct 16 '13 at 19:50
  • No real reason. Mainly I'm learning about APIs and testing various things. Surely Json is the way for larger bodies. I was just trying to get it to work on Fiddler (which it does now). Thanks for your input !! – SF Developer Oct 18 '13 at 17:25
  • I just finished getting an inbound Twilio post to work. In Fiddler I added the Content-Type: application/x-www-form-urlencoded to the header and then the following in the body: Sid=replace+with+original+sid+for+status+callback&AccountSid=assigned+by+twilio&From=%2B12223334444&To=%2B15556667777&Body=something+really+witty&Status=sent The names of the parameters are the same as the field names in the class. – William T. Mallard Apr 14 '14 at 05:02