我添加了一个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总是在JSON的最后一个字符之后报告行和字符(在这种情况下第4行==&#34;}&#34;)
我在serialiser配置中缺少什么?
感谢
答案 0 :(得分:2)
默认情况下,Web Api中使用JSON.net。可以在NullValueHandling
:
SerializerSettings
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Formatters.JsonFormatter.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
}
答案 1 :(得分:1)
我不是在问你为什么要实现自己的媒体类型格式化程序,我有你自己的理由。你能告诉我你在哪里获得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));
}
所以解决方案就是实现你自己的反序列化方法,你可以使用我的例子作为start并简单地将期望的类型添加到反序列化方法,并删除finall测试当然...
var obj = serializer.Deserialize(reader, TYPE);