网页API:无法序列化响应正文内容类型 [英] Web API: Failed to serialize the response body for content type

查看:909
本文介绍了网页API:无法序列化响应正文内容类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我与ASP.NET MVC 5网页API的工作。

我有很多的API现有的应用程序。
最近,我已实施的自定义JsonConverter将日期转换为每个时区。

 公共类CustomInfoConverter:JsonConverter
{    公众覆盖布尔CanConvert(类型的objectType)
    {
        返回的objectType == typeof运算(CustomType);
    }
    公众覆盖布尔的CanRead
    {
        得到
        {
            返回false;
        }
    }
    公众覆盖布尔CanWrite
    {
        得到
        {
            返回true;
        }
    }
    公共覆盖无效WriteJson(JsonWriter作家,对象的值,JsonSerializer串行)
    {
        VAR customType =(CustomType)值;
        如果(customType == NULL ||空== customType.TimeZone)回报;
        //日期时间currentDateTime = customType.Date??DateTime.Now;
        日期时间currentDateTime = DateTime.SpecifyKind(customType.Date ?? DateTime.Now,DateTimeKind.Unspecified);        日期时间userDateTime = TimeZoneInfo.ConvertTimeFromUtc(currentDateTime,customType.TimeZone);
        customType.Date = userDateTime;
        JsonSerializer innerSerializer =新JsonSerializer();
        的foreach(!(c是CustomInfoConverter))在serializer.Converters.Where(C =&GT VAR转换器)
        {
            innerSerializer.Converters.Add(转换器);
        }
        innerSerializer.Serialize(作家,customType);
    }    公众覆盖对象ReadJson(JsonReader读者,类型的objectType,对象existingValue,JsonSerializer串行)
    {
        抛出新NotImplementedException();
    }
}

实现这个自定义JsonConverter所有的API都除了一个API的工作,这是引发异常后,下方


  

{消息:发生错误,ExceptionMessage:其
  ObjectContent`1式未能序列化的响应机构
  内容类型应用/ JSON的;
  charset=utf-8'.\",\"ExceptionType\":\"System.InvalidOperationException\",\"StackTrace\":null,\"InnerException\":{\"Message\":\"An
  发生错误,ExceptionMessage:令牌属性名状态
  物业会导致一个无效的JSON对象。路径
  'Data.Forms [0]',ExceptionType。:Newtonsoft.Json.JsonWriterException,堆栈跟踪:
  在Newtonsoft.Json.JsonWriter.AutoComplete(JsonToken
  tokenBeingWritten)\\ r \\ n在
  Newtonsoft.Json.JsonWriter.InternalWritePropertyName(字符串名)\\ r \\ n
  在Newtonsoft.Json.JsonTextWriter.WritePropertyName(字符串名称,
  布尔逃生个)\\ r \\ n在
  Newtonsoft.Json.Serialization.JsonProperty.WritePropertyName(JsonWriter
  作家)\\ r \\ n在
  Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter
  作家,对象的值,JsonObjectContract合同,JsonProperty
  成员,JsonContainerContract collectionContract,JsonProperty
  containerProperty)\\ r \\ n在
  Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter
  作家,对象的值,JsonContract valueContract,JsonProperty成员,
  JsonContainerContract containerContract,JsonProperty
  containerProperty)\\ r \\ n在
  Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter
  作家,IEnumerable的值,JsonArrayContract合同,JsonProperty
  成员,JsonContainerContract collectionContract,JsonProperty
  containerProperty)\\ r \\ n在
  Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter
  作家,对象的值,JsonContract valueContract,JsonProperty成员,
  JsonContainerContract containerContract,JsonProperty
  containerProperty)\\ r \\ n在
  Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter
  作家,对象的值,JsonObjectContract合同,JsonProperty
  成员,JsonContainerContract collectionContract,JsonProperty
  containerProperty)\\ r \\ n在
  Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter
  作家,对象的值,JsonContract valueContract,JsonProperty成员,
  JsonContainerContract containerContract,JsonProperty
  containerProperty)\\ r \\ n在
  Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter
  作家,对象的值,JsonObjectContract合同,JsonProperty
  成员,JsonContainerContract collectionContract,JsonProperty
  containerProperty)\\ r \\ n在
  Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter
  作家,对象的值,JsonContract valueContract,JsonProperty成员,
  JsonContainerContract containerContract,JsonProperty
  containerProperty)\\ r \\ n在
  Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter
  jsonWriter,对象的值,类型的objectType)\\ r \\ n在
  Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter
  jsonWriter,对象的值,类型的objectType)\\ r \\ n在
  Newtonsoft.Json.JsonSerializer.Serialize(JsonWriter jsonWriter,对象
  值)\\ r \\ n在
  System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(类型
  类型,对象的值,流writeStream,编码
  effectiveEncoding)\\ r \\ n在
  System.Net.Http.Formatting.JsonMediaTypeFormatter.WriteToStream(类型
  类型,对象的值,流writeStream,编码
  effectiveEncoding)\\ r \\ n在
  System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(类型
  类型,对象的值,流writeStream,HttpContent内容)\\ r \\ n在
  System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStreamAsync(类型
  类型,对象的值,流writeStream,HttpContent内容,
  TransportContext transportContext,的CancellationToken
  的CancellationToken)\\ r \\ n ---从previous位置堆栈跟踪结束
  其中,引发异常--- \\ r \\ n在
  System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务
  任务)\\ r \\ n在
  System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务
  任务)\\ r \\ n在
  System.Runtime.CompilerServices.TaskAwaiter.GetResult(个)\\ r \\ n在
  System.Web.Http.WebHost.HttpControllerHandler.d__1b.MoveNext()}}


您可以参考这篇<一个href=\"http://stackoverflow.com/questions/33524379/json-serializer-adding-extra-character-as-in-response-while-serializing-custo\">link了解更多详情。


解决方案

这个问题看起来是,在某些情况下,您从 WriteJson()无需编写返回任何事情,特别是当 customType.TimeZone == NULL

  VAR customType =(CustomType)值;
    如果(customType == NULL ||空== customType.TimeZone)回报;

这样做会导致一个无效的JSON对象,因为属性的名称的将已经写入调用者,从而导致:


  {
    customType:
}


尝试这样做会导致您所看到的除外。

相反,你需要prevent被序列化的属性本身。这是不可能的,不过转换器,它需要包含类型做。

要避免序列化的属性用null值,你应该设置 NullValueHandling = NullValueHandling.Ignore 中的串行器设置,或对物业本身:

 公共类ContainerClass
{
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)
    公共CustomType CustomType {搞定;组; }
}

要prevent序列化你的财产时,其时区属性为空,你应该使用的加入了 ShouldSerializeXXX()方法包含类型,其中<$条件属性系列化 C $ C> XXX 完全匹配您的属性名称:

 公共类ContainerClass
{
    公共CustomType CustomType {搞定;组; }    公共BOOL ShouldSerializeCustomType()
    {
        返回CustomType = NULL&放大器;!&安培; CustomType.TimeZone!= NULL;
    }
}

I am working with ASP.NET MVC 5 Web Api.

I am having existing application with many api's. Recently I have implemented custom JsonConverter which will convert Date as per timezone.

public class CustomInfoConverter : JsonConverter
{

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(CustomType);
    }
    public override bool CanRead
    {
        get
        {
            return false;
        }
    }
    public override bool CanWrite
    {
        get
        {
            return true;
        }
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var customType = (CustomType)value;
        if (customType == null || null== customType.TimeZone) return;
        //DateTime currentDateTime = customType.Date??DateTime.Now;
        DateTime currentDateTime = DateTime.SpecifyKind(customType.Date ?? DateTime.Now, DateTimeKind.Unspecified);

        DateTime userDateTime = TimeZoneInfo.ConvertTimeFromUtc(currentDateTime, customType.TimeZone);
        customType.Date = userDateTime;
        JsonSerializer innerSerializer = new JsonSerializer();
        foreach (var converter in serializer.Converters.Where(c => !(c is CustomInfoConverter)))
        {
            innerSerializer.Converters.Add(converter);
        }
        innerSerializer.Serialize(writer, customType);


    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }


}

After implementing this custom JsonConverter all api are working except one api, which is throwing below exception

{"Message":"An error has occurred.","ExceptionMessage":"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'.","ExceptionType":"System.InvalidOperationException","StackTrace":null,"InnerException":{"Message":"An error has occurred.","ExceptionMessage":"Token PropertyName in state Property would result in an invalid JSON object. Path 'Data.Forms[0]'.","ExceptionType":"Newtonsoft.Json.JsonWriterException","StackTrace":" at Newtonsoft.Json.JsonWriter.AutoComplete(JsonToken tokenBeingWritten)\r\n at Newtonsoft.Json.JsonWriter.InternalWritePropertyName(String name)\r\n at Newtonsoft.Json.JsonTextWriter.WritePropertyName(String name, Boolean escape)\r\n at Newtonsoft.Json.Serialization.JsonProperty.WritePropertyName(JsonWriter writer)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter writer, IEnumerable values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value, Type objectType)\r\n at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)\r\n at Newtonsoft.Json.JsonSerializer.Serialize(JsonWriter jsonWriter, Object value)\r\n at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding)\r\n at System.Net.Http.Formatting.JsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding)\r\n at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content)\r\n at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n at System.Runtime.CompilerServices.TaskAwaiter.GetResult()\r\n at System.Web.Http.WebHost.HttpControllerHandler.d__1b.MoveNext()"}}

You can refer to this link for more details.

解决方案

The problem looks to be that, in certain situations, you are returning from WriteJson() without writing anything, specifically when customType.TimeZone == null:

    var customType = (CustomType)value;
    if (customType == null || null== customType.TimeZone) return;

Doing so will result in an invalid JSON object, because the property name will already have been written by the caller, resulting in:

{
    "customType":
}

Trying to do this results in the exception you are seeing.

Instead, you need to prevent the property itself from being serialized. That's not possible in the converter however, it needs to be done in the containing type.

To avoid serializing a property with a null value, you should set NullValueHandling = NullValueHandling.Ignore in serializer settings, or on the property itself:

public class ContainerClass
{
    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public CustomType CustomType { get; set; }
}

To prevent serializing your property when its TimeZone property is null, you should use conditional property serialization by adding a ShouldSerializeXXX() method to the containing type, where XXX exactly matches your property name:

public class ContainerClass
{
    public CustomType CustomType { get; set; }

    public bool ShouldSerializeCustomType()
    {
        return CustomType != null && CustomType.TimeZone != null;
    }
}

这篇关于网页API:无法序列化响应正文内容类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆