JSON.NET Serialiser for Web API (mvc5)
本文关键字:mvc5 API Web NET Serialiser for JSON | 更新日期: 2023-09-27 17:51:18
我已经添加了一个TypeFormatter以便使用JSON。. NET作为web api操作的主要序列化/反序列化器。
给定这个简单的动作
[HttpPost]
[Route("api/myentity/")]
public async Task<HttpResponseMessage> CreateMyEntity(MyEntity entity)
{
// .. stuff to add
// return 200, with some additional info
return ResultOk(new {status = "Yay, added"});
}
然后是JSON.net类型格式化器(也添加到配置中)
public JsonSerializer Serializer { get; private set; }
/// <summary>
/// Specify the media types that this MediaTypeFormatter handles
/// </summary>
public JsonNetMediaTypeFormatter()
{
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json") { CharSet = "utf-8" });
SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/json") { CharSet = "utf-8" });
Serializer = new JsonSerializer
{
TypeNameHandling = TypeNameHandling.Objects,
NullValueHandling = NullValueHandling.Ignore
};
}
public override Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
return readStream.ReadAsJson(type, Serializer);
}
public override Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, System.Net.TransportContext transportContext)
{
return writeStream.WriteAsJson(value, Serializer);
}
当使用以下模型调用api操作时:
application/json
{
"Name":"ACME",
"Phone":"0123456"
}
(内容无关)
我得到一个Unexpected token while deserializing object: EndObject. Path '', line 4, position 2.
我在序列化器配置中缺少什么?
谢谢
JSON.net在Web Api中默认使用。NullValueHandling
可在SerializerSettings
中配置:
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
}
我不是在问你为什么要实现你自己的媒体类型格式化程序,我想你有你自己的原因。你能告诉我你在哪里得到ReadAsJson扩展方法吗?
我发现这个实现StreamExtension,我认为有一个小错误在obj.GetType(). issubclassof (instanceType)。这个表达式永远不会为真,并且第二次反序列化使用流,该流将被消耗到最后…
我做了一个小测试,与你面临的相同的例外…
class Foo
{
public string Test { get; set; }
}
public static Stream ToStream(string str)
{
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
writer.Write(str);
writer.Flush();
stream.Position = 0;
return stream;
}
static void Main(string[] args)
{
var stream = Program.ToStream(@"{ ""Test"" : ""TesT"" }");
using (var reader = new JsonTextReader(new StreamReader(stream)))
{
var serializer = new JsonSerializer
{
TypeNameHandling = TypeNameHandling.Objects,
NullValueHandling = NullValueHandling.Ignore
};
var obj = serializer.Deserialize(reader);
// We want to try deserialization without specifying an explicit type first,
// then see if the resulting type is compatible with the type that is expected
// from the Web API stack stream.
// If not, then we try to read it again using an explicit type
// (although it probably won't work anyway still :p)
var test = obj.GetType().IsSubclassOf(typeof(Foo)) ? obj : serializer.Deserialize(reader, typeof(Foo));
}
所以解决方法是实现你自己的反序列化方法,你可以用我的例子作为开始,简单地将预期类型添加到反序列化方法中,并删除finall test当然…
var obj = serializer.Deserialize(reader, TYPE);