Web API:无法序列化内容类型的响应正文

Posted

技术标签:

【中文标题】Web API:无法序列化内容类型的响应正文【英文标题】:Web API: Failed to serialize the response body for content type 【发布时间】:2016-02-07 03:28:36 【问题描述】:

我正在使用 ASP.NET MVC 5 Web Api。

我有许多 api 的现有应用程序。 最近我实现了自定义 JsonConverter,它将根据时区转换日期。

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



在实现这个自定义 JsonConverter 之后,所有 api 都在工作,除了一个 api,它抛出异常

"Message":"发生错误。","ExceptionMessage":"The “ObjectContent`1”类型无法序列化响应正文 内容类型'应用程序/json; charset=utf-8'.","ExceptionType":"System.InvalidOperationException","StackTrace":null,"InnerException":"Message":"An 发生错误。","ExceptionMessage":"Token PropertyName 处于状态 属性将导致无效的 JSON 对象。小路 'Data.Forms[0]'.","ExceptionType":"Newtonsoft.Json.JsonWriterException","StackTrace":" 在 Newtonsoft.Json.JsonWriter.AutoComplete(JsonToken tokenBeingWritten)\r\n 在 Newtonsoft.Json.JsonWriter.InternalWritePropertyName(字符串名称)\r\n 在 Newtonsoft.Json.JsonTextWriter.WritePropertyName(字符串名称, 布尔转义)\r\n at Newtonsoft.Json.Serialization.JsonProperty.WritePropertyName(JsonWriter 作家)\r\n 在 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer,对象值,JsonObjectContract 合约,JsonProperty 成员,JsonContainerContract 集合合同,JsonProperty containerProperty)\r\n 在 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer,对象值,JsonContract valueContract,JsonProperty 成员, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n 在 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter writer,IEnumerable 值,JsonArrayContract 合同,JsonProperty 成员,JsonContainerContract 集合合同,JsonProperty containerProperty)\r\n 在 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer,对象值,JsonContract valueContract,JsonProperty 成员, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n 在 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer,对象值,JsonObjectContract 合约,JsonProperty 成员,JsonContainerContract 集合合同,JsonProperty containerProperty)\r\n 在 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer,对象值,JsonContract valueContract,JsonProperty 成员, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n 在 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer,对象值,JsonObjectContract 合约,JsonProperty 成员,JsonContainerContract 集合合同,JsonProperty containerProperty)\r\n 在 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer,对象值,JsonContract valueContract,JsonProperty 成员, JsonContainerContract containerContract, JsonProperty containerProperty)\r\n 在 Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter,对象值,类型 objectType)\r\n at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter,对象值,类型 objectType)\r\n at Newtonsoft.Json.JsonSerializer.Serialize(JsonWriter jsonWriter, Object 值)\r\n 在 System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(类型 类型、对象值、流 writeStream、编码 有效编码)\r\n 在 System.Net.Http.Formatting.JsonMediaTypeFormatter.WriteToStream(类型 类型、对象值、流 writeStream、编码 有效编码)\r\n 在 System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(类型 类型、对象值、流 writeStream、HttpContent 内容)\r\n at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStreamAsync(类型 类型、对象值、流 writeStream、HttpContent 内容、 TransportContext transportContext, CancellationToken cancelToken)\r\n--- 来自先前位置的堆栈跟踪结束 抛出异常的地方 ---\r\n 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务 任务)\r\n 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务 任务)\r\n 在 System.Runtime.CompilerServices.TaskAwaiter.GetResult()\r\n at System.Web.Http.WebHost.HttpControllerHandler.d__1b.MoveNext()"

您可以参考这个link了解更多详情。

【问题讨论】:

【参考方案1】:

问题看起来是,在某些情况下,您从WriteJson() 返回而没有写任何东西,特别是当customType.TimeZone == null

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

这样做会导致 JSON 对象无效,因为属性 name 已经被调用者写入,导致:


    "customType":

尝试执行此操作会导致您看到的异常。

相反,您需要防止属性本身被序列化。然而,这在转换器中是不可能的,它需要在包含类型中完成。

为避免使用 null 值序列化属性,您应该在 serializer settings 或属性本身上设置 NullValueHandling = NullValueHandling.Ignore

public class ContainerClass

    [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
    public CustomType CustomType  get; set; 

为防止在其TimeZone 属性为空时序列化您的属性,您应该通过将ShouldSerializeXXX() 方法添加到包含类型来使用conditional property serialization,其中XXX 与您的属性名称完全匹配:

public class ContainerClass

    public CustomType CustomType  get; set; 

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

【讨论】:

以上是关于Web API:无法序列化内容类型的响应正文的主要内容,如果未能解决你的问题,请参考以下文章

无法序列化 Web API 中的响应

无法使用Json在Web API中序列化响应

无法使用 Json 序列化 Web API 中的响应

Asp.Net Web API错误:'ObjectContent`1'类型无法序列化内容类型'application / xml的响应主体;字符集= UTF-8'(代码

WebAPI OData错误ObjectContent类型无法序列化内容类型'application / json ...'的响应正文

C# WebApi Xml序列化问题解决方法:“ObjectContent`1”类型未能序列化内容类型“application/xml;charset=utf-8"的响应正文。...