2

I have an ASP.NET web api built into my MVC application and it currently receives all data accompanying a request as form encoded data.

I receive this as a FormDataCollection object and parse like so:

public string Post(FormDataCollection data)
{
    var first = data.Get("FirstName");
    //for every supported field.
}

My response is always a JSON string.

This is fine and I want to continue to accomodate this, however I'd like my users to be able to send a JSON with content type header application/JSON as well so that I can support both.

How do I accommodate both in a simple way? Will it have to involve checking the content header and having different code to extract the attributes in each case?

Sam Hosseini
  • 813
  • 2
  • 9
  • 17
JonnyKnottsvill
  • 1,123
  • 2
  • 16
  • 39
  • Is using a model not appropriate? i.e. `public string Post(TargetModel)...` The framework should parse the data it receives (form submission or JSON) in to your target model. – R Day Sep 17 '15 at 13:55
  • I'm very new to building an API, how exactly would I implement this? Will I run into parsing errors should the data not completely satisfy the model? – JonnyKnottsvill Sep 17 '15 at 13:57
  • I'll write a quick answer. – R Day Sep 17 '15 at 13:57

2 Answers2

4

Let the asp.net model binder handle the bindings for you. Define a class that will represent your model:

public class Person
{
  public string Firsname{ get; set; }
}

then have your controller action take this view model as argument:

public class PersonController : ApiController
{

  public void Post(Person model)
  {
    ...
  }
}

Finally you can post using jquery ajax or whatever you pick. e.g

$.ajax({
type: 'POST',
url: '/api/person',
cache: false,
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({ Firstname: "John Doe" }),
success: function() {
    ...    
   }
});
Overmachine
  • 1,723
  • 3
  • 15
  • 27
3

Try using a model class like below;

public class MyTargetModel
{
    public string FirstName { get; set; }
}

public string Post(MyTargetModel model)
{
    var first = model.FirstName;
    //for every supported field.
}

When I say model class I mean a POCO class. ASP.NET MVC and Web API should be able to parse the request data in to the class as appropriate.

Community
  • 1
  • 1
R Day
  • 962
  • 9
  • 25
  • Thanks for the answer. So this would automatically be parsed regardless of content type? Wwhat if for example the model contained Id, FirstName, LastName, Mobile. and only FirstName and LastName were passed and Mobile wasn't required? It would parse correctly and Mobile would simply be null? – JonnyKnottsvill Sep 17 '15 at 14:04
  • Would this handle complex types like an Enumerable? – JonnyKnottsvill Sep 17 '15 at 14:14
  • 1
    For reference types you will get `null` if nothing is passed, for value types I believe you'll get the default value (0 for `int`). You can use [DataAnnotations](https://msdn.microsoft.com/en-us/library/ee256141%28v=vs.100%29.aspx) to provide more details about your data requirements. – R Day Sep 17 '15 at 14:14
  • 1
    Yes, it can handle sequences too. – R Day Sep 17 '15 at 14:15