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



我正在使用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都在工作

{"消息":"发生错误。","ExceptionMessage":"ObjectContent"1"类型未能序列化的响应正文内容类型‘application/json;charset=utf-8'。","ExceptionType":"System.InvalidOperationException","StackTrace":null,"InnerException":{"Message":"An出现错误。","ExceptionMessage":"令牌PropertyName处于状态属性将导致无效的JSON对象。路径"Data.Forms[0]".","ExceptionType":"Newtonsoft.Json.JsonWriterException","StackTrace":"在Newtonsoft.Json.JsonWriter.AutoComplete(JsonTokentokenBeingWritten)\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(JsonWriterwriter,对象值,JsonObjectContract合同,JsonProperty成员,JsonContainerContract集合Contract,JsonPropertycontainerProperty)\r\n位于Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriterwriter,Object value,JsonContract valueContract,JsonProperty成员,JsonContainer合同容器合同,JsonPropertycontainerProperty)\r\n位于Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter作家,IEnumerable值,JsonArrayContract合同,JsonProperty成员,JsonContainerContract集合Contract,JsonPropertycontainerProperty)\r\n位于Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriterwriter,Object value,JsonContract valueContract,JsonProperty成员,JsonContainer合同容器合同,JsonPropertycontainerProperty)\r\n位于Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriterwriter,对象值,JsonObjectContract合同,JsonProperty成员,JsonContainerContract集合Contract,JsonPropertycontainerProperty)\r\n位于Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriterwriter,Object value,JsonContract valueContract,JsonProperty成员,JsonContainer合同容器合同,JsonPropertycontainerProperty)\r\n位于Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriterwriter,对象值,JsonObjectContract合同,JsonProperty成员,JsonContainerContract集合Contract,JsonPropertycontainerProperty)\r\n位于Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriterwriter,Object value,JsonContract valueContract,JsonProperty成员,JsonContainer合同容器合同,JsonPropertycontainerProperty)\r\n位于Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriterjsonWriter,Object value,Type objectType)\r\n位于Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriterjsonWriter,Object value,Type objectType)\r\n位于Newtonsoft.Json.JsonSerializer.Serialize(JsonWriter,对象值)\r\nSystem.Net.Http.Formating.BaseJsonMediaTypeFormatter.WriteToStream(类型类型,对象值,流写入流,编码effectiveEncoding)\r\n在System.Net.Http.Formating.JsonMediaTypeFormatter.WriteToStream(类型类型,对象值,流写入流,编码effectiveEncoding)\r\n在System.Net.Http.Formating.BaseJsonMediaTypeFormatter.WriteToStream(类型type,Object value,Stream writeStream,HttpContent content)\r\nSystem.Net.Http.Formating.BaseJsonMediaTypeFormatter.WriteToStreamAsync(类型type,Object value,Stream writeStream,HttpContent content,TransportContext TransportContext,CancellationTokencancelloToken)\r\n-从上一位置开始的堆栈跟踪结束在何处引发异常---\r\nSystem.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)\r\nSystem.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)\r\n位于的System.Runtime.CompilerServices.TaskAwaiter.GetResult()\r\nSystem.Web.Http.WebHost.HttpControllerHandler.d__1b.MoveNext()"}}

您可以参考此链接了解更多详细信息。

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

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

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

{
    "customType":
}

尝试这样做会导致您看到的异常。

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

为了避免序列化具有null值的属性,您应该在序列化程序设置中或在属性本身上设置NullValueHandling = NullValueHandling.Ignore

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

若要防止在属性的TimeZone属性为null时序列化属性,应通过向包含类型添加ShouldSerializeXXX()方法来使用条件属性序列化,其中XXX与属性名称完全匹配:

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

相关内容

  • 没有找到相关文章

最新更新