Firstly thank you for taking the time out to read this post.
I've been building my first asp.net 4.5 MVC4 Web Api, but the value received in the controll POST method is always NULL.
To test the POST api method I've tried Fiddler and Google Chrome Simple REST Clinet but the result is always the same.
Here's my code:
Controller (POST)
// POST api/Terminal
public HttpResponseMessage PostTerminal(Terminal terminal)
{
if (terminal == null)
{
return Request.CreateResponse(HttpStatusCode.BadRequest, terminal);
}
if (ModelState.IsValid)
{
db.Terminals.Add(terminal);
db.SaveChanges();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, terminal);
response.Headers.Location = new Uri(Url.Link("DefaultApi", new { id = terminal.Id }));
return response;
}
else
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
}
}
Model Class
public class Terminal
{
public int Id { get; set; }
[Required]
public int TerminalId { get; set; }
[Required]
public string Tag { get; set; }
[Required]
public DateTime TagDate { get; set; }
}
In the above code, the value received in the POST method terminal is always NULL.
Here's the command I've been using to POST using Fiddler:
Method: POST
Address:
http://localhost:52036/api/terminal
Header:
Content-Type: application/json
Host: localhost:52036
Content-Length: 60
Body:
{"TerminalId":123,"Tag":"222","TagDate":2014-04-13 04:22:12}
----------- EDIT - 13-04-2014 14:56 -------------
I have modified my Fiddler http post request as advised to in some of the replies to this question with the following details. However I keep getting a 500 HTTP error and my API code doesn't even reach the Controller when testing in VS2013 debug mode.
Address
POST
http://localhost:52036/api/terminal/
Header
Content-Type: application/json; charset=utf-8
Host: localhost:52036
Content-Length: 62
Body
{"TerminalId":123,"Tag":"222","TagDate":"2014-04-13 04:22:12"}
-------------- Edit 13/04/2014 20:38 -----------------
Ok, using Google's Chrome REST Client, I've noticed the following return error message:
{"Message":"An error has occurred.","ExceptionMessage":"Property 'TerminalId' on type 'ClockingDemo.Models.Terminal' is invalid. Value-typed properties marked as [Required] must also be marked with [DataMember(IsRequired=true)] to be recognized as required. Consider attributing the declaring type with [DataContract] and the property with [DataMember(IsRequired=true)].","ExceptionType":"System.InvalidOperationException","StackTrace":" at System.Web.Http.Validation.Validators.ErrorModelValidator.Validate(ModelMetadata metadata, Object container)\r\n at System.Web.Http.Validation.DefaultBodyModelValidator.ShallowValidate(ModelMetadata metadata, ValidationContext validationContext, Object container)\r\n
at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, ValidationContext validationContext, Object container)\r\n
at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateProperties(ModelMetadata metadata, ValidationContext validationContext)\r\n at System.Web.Http.Validation.DefaultBodyModelValidator.ValidateNodeAndChildren(ModelMetadata metadata, ValidationContext validationContext, Object container)\r\n
at System.Web.Http.Validation.DefaultBodyModelValidator.Validate(Object model, Type type, ModelMetadataProvider metadataProvider, HttpActionContext actionContext, String keyPrefix)\r\n at System.Web.Http.ModelBinding.FormatterParameterBinding.<>c__DisplayClass1.b__0(Object model)\r\n at System.Threading.Tasks.TaskHelpersExtensions.<>c__DisplayClass361.<>c__DisplayClass38.<Then>b__35()\r\n at System.Threading.Tasks.TaskHelpersExtensions.<>c__DisplayClass49.<ToAsyncVoidTask>b__48()\r\n at System.Threading.Tasks.TaskHelpers.RunSynchronously[TResult](Func
1 func, CancellationToken cancellationToken)"}
I think the problem is coming from the fact that my INTEGER property TerminalId is defined as [Required]. I have a feeling there might be an issue with setting a non-NULLABLE property and [Required].
Very much open to suggestions.
----------------- ANSWER ---------------
I finally stumbled across this thread which solved the problem for me. DataAnnotation for Required property
Simply paste this into the Global.asax file:
GlobalConfiguration.Configuration.Services.RemoveAll(
typeof(System.Web.Http.Validation.ModelValidatorProvider),
v => v is InvalidModelValidatorProvider);
I'm still open to other solutions if you believe there is a better method.