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总是报告JSON最后一个字符之后的行和字符(在本例中,第4行== "}")

我在序列化器配置中缺少什么?

谢谢

JSON.NET Serialiser for Web API (mvc5)

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);