我使用JsonNetFormatter
发现here与ASP.Net MVC 4测试版网站中托管的Web API测试项目,并发现模型绑定似乎工作方式略有不同当我使用默认JsonMediaTypeFormatter
。切换到JsonNetFormatter
模型绑定后,似乎破坏了在URL中设置的参数。例如,下面的代码工作正常使用默认JsonMediaTypeFormatter
,但是当我使用JsonNetFormatter
被抛出此错误:在ASP.Net Web API中使用自定义MediaTypeFormatter的模型绑定错误
"The parameters dictionary contains a null entry for parameter 'id' of non-nullable type 'System.Int32' for method 'System.Net.Http.HttpResponseMessage Put(Int32, WebAPISpike.Website.Api.Model.PutLesson)'...
JsonNetFormatter
public class JsonNetFormatter : MediaTypeFormatter
{
private JsonSerializerSettings _jsonSerializerSettings;
public JsonNetFormatter(JsonSerializerSettings jsonSerializerSettings)
{
_jsonSerializerSettings = jsonSerializerSettings ?? new JsonSerializerSettings();
// Fill out the mediatype and encoding we support
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
Encoding = new UTF8Encoding(false, true);
}
protected override bool CanReadType(Type type)
{
if (type == typeof(IKeyValueModel))
{
return false;
}
return true;
}
protected override bool CanWriteType(Type type)
{
return true;
}
protected override Task<object> OnReadFromStreamAsync(Type type, Stream stream, HttpContentHeaders contentHeaders, FormatterContext formatterContext)
{
// Create a serializer
JsonSerializer serializer = JsonSerializer.Create(_jsonSerializerSettings);
// Create task reading the content
return Task.Factory.StartNew(() =>
{
using (StreamReader streamReader = new StreamReader(stream, Encoding))
{
using (JsonTextReader jsonTextReader = new JsonTextReader(streamReader))
{
return serializer.Deserialize(jsonTextReader, type);
}
}
});
}
protected override Task OnWriteToStreamAsync(Type type, object value, Stream stream, HttpContentHeaders contentHeaders, FormatterContext formatterContext, TransportContext transportContext)
{
// Create a serializer
JsonSerializer serializer = JsonSerializer.Create(_jsonSerializerSettings);
// Create task writing the serialized content
return Task.Factory.StartNew(() =>
{
using (StreamWriter streamWriter = new StreamWriter(stream, Encoding))
{
using (JsonTextWriter jsonTextWriter = new JsonTextWriter(streamWriter))
{
serializer.Serialize(jsonTextWriter, value);
}
}
});
}
}
的Web API配置
var serializerSettings = new JsonSerializerSettings();
serializerSettings.Converters.Add(new IsoDateTimeConverter());
GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.JsonFormatter);
GlobalConfiguration.Configuration.Formatters.Add(new JsonNetFormatter(serializerSettings));
控制器
public class LessonsController : ApiController {
public HttpResponseMessage Put(int id, PutLesson updates) {
// get lesson by id and update it with new values in from updates
return new HttpResponseMessage(HttpStatusCode.OK);
}
}
型号
public class PutLesson {
public string LessonName { get; set; }
public string Overview { get; set; }
}
我可以解决此问题由id参数移动到我的PutLesson
模型,然后将其设置在那里,但当时它不是URI标识资源,它是请求主体。 JsonNetFormatter
实施或我的配置中是否有缺失?