我正在使用 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 均正常工作,该 api 抛出以下异常
{“Message”:“发生错误。”,“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(JsonToken
tokenBeingWritten)\r\n at
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 集合Contract、JsonProperty
容器属性)\r\n at
Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter
writer、对象值、JsonContract valueContract、JsonProperty 成员、
JsonContainerContract 容器Contract、JsonProperty
容器属性)\r\n at
Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter
writer、IEnumerable 值、JsonArrayContract 合约、JsonProperty
成员、JsonContainerContract 集合Contract、JsonProperty
容器属性)\r\n at
Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter
writer、对象值、JsonContract valueContract、JsonProperty 成员、
JsonContainerContract 容器Contract、JsonProperty
容器属性)\r\n at
Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter
writer、对象值、JsonObjectContract 合约、JsonProperty
成员、JsonContainerContract 集合Contract、JsonProperty
容器属性)\r\n at
Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter
writer、对象值、JsonContract valueContract、JsonProperty 成员、
JsonContainerContract 容器Contract、JsonProperty
容器属性)\r\n at
Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter
writer、对象值、JsonObjectContract 合约、JsonProperty
成员、JsonContainerContract 集合Contract、JsonProperty
容器属性)\r\n at
Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter
writer、对象值、JsonContract valueContract、JsonProperty 成员、
JsonContainerContract 容器Contract、JsonProperty
容器属性)\r\n at
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, 对象
值)\r\n 位于
System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(类型
类型、对象值、流 writeStream、编码
有效编码)\r\n at
System.Net.Http.Formatting.JsonMediaTypeFormatter.WriteToStream(类型
类型、对象值、流 writeStream、编码
有效编码)\r\n at
System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(类型
类型、对象值、流 writeStream、HttpContent 内容)\r\n at
System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStreamAsync(类型
类型、对象值、Stream writeStream、HttpContent 内容、
TransportContext TransportContext、CancellationToken
cancelToken)\r\n--- 前一位置的堆栈跟踪结束
抛出异常的地方 ---\r\n at
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()"}}
你可以参考这个link更多细节。
问题似乎是,在某些情况下,您将从WriteJson()
不写任何东西,特别是当customType.TimeZone == null
:
var customType = (CustomType)value;
if (customType == null || null== customType.TimeZone) return;
这样做将导致无效的 JSON 对象,因为该属性name调用者已经写入,结果是:
{
"customType":
}
尝试执行此操作会导致您看到的异常。
相反,您需要防止属性本身被序列化。然而,这在转换器中是不可能的,它需要在包含类型中完成。
为了避免序列化具有空值的属性,您应该设置NullValueHandling = NullValueHandling.Ignore
in 串行器设置,或财产本身:
public class ContainerClass
{
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public CustomType CustomType { get; set; }
}
为了防止序列化你的财产TimeZone
属性为空,你应该使用条件属性序列化通过添加一个ShouldSerializeXXX()
包含类型的方法,其中XXX
与您的财产名称完全匹配:
public class ContainerClass
{
public CustomType CustomType { get; set; }
public bool ShouldSerializeCustomType()
{
return CustomType != null && CustomType.TimeZone != null;
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)