我有一个 POCO 类,它继承自几个类以提供 INotifyPropertyChanged 和 DataAnnotations 支持。当 WebApi 返回 Court 的实例时,JSON.NET 序列化程序在 ModelPropertyAnnotationsValidation 中的匿名方法委托(delegate)上阻塞并出现异常(显示来自 Fiddler 的 RAW 响应):
{"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":"Error getting value from 'CS$<>9_CachedAnonymousMethodDelegate5' on 'Sample.Data.Models.Court'.","ExceptionType":"Newtonsoft.Json.JsonSerializationException","StackTrace":" at Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)\r\n at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.CalculatePropertyValues(JsonWriter writer, Object value, JsonContainerContract contract, JsonProperty member, JsonProperty property, JsonContract& memberContract, Object& memberValue)\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)\r\n at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value)\r\n at System.Net.Http.Formatting.JsonMediaTypeFormatter.<>c_DisplayClassd.b_c()\r\n at System.Threading.Tasks.TaskHelpers.RunSynchronously(Action action, CancellationToken token)","InnerException":{"Message":"An error has occurred.","ExceptionMessage":"Common Language Runtime detected an invalid program.","ExceptionType":"System.InvalidProgramException","StackTrace":" at GetCS$<>9_CachedAnonymousMethodDelegate5(Object )\r\n at Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)"}}}
法院类(为简洁起见已编辑):
using System;
using System.Collections.Generic;
using Sample.Data.Models.Infrastructure;
namespace Sample.Data.Models
{
[Serializable]
public partial class Court : ModelPropertyAnnotationsValidation
{
public Court()
{
}
private int _courtID;
public int CourtID
{
get { return _courtID; }
set
{
_courtID = value;
OnPropertyChanged(() => CourtID);
}
}
}
}
这是问题所在的继承抽象类(如果我将 public string this[string columnName]
上的 getter 更改为返回一个空字符串,它会起作用:
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
namespace Sample.Data.Models.Infrastructure
{
public abstract class ModelPropertyAnnotationsValidation : ModelBase
{
public string this[string columnName]
{
get
{
var type = GetType();
var modelProperties = TypeDescriptor.GetProperties(type).Cast<PropertyDescriptor>();
var enumerable = from modelProperty in modelProperties.Where(modelProp => modelProp.Name == columnName)
from attribute in modelProperty.Attributes.OfType<ValidationAttribute>().Where(attribute => !attribute.IsValid(modelProperty.GetValue(this)))
select attribute.ErrorMessage;
return enumerable.FirstOrDefault();
}
private set { ; } //http://developerstreasure.blogspot.com/2010/05/systemruntimeserializationinvaliddataco.html
}
public string Error
{
get { return null; }
private set { ; } //http://developerstreasure.blogspot.com/2010/05/systemruntimeserializationinvaliddataco.html
}
public virtual bool IsValid
{
get
{
var validationContext = new ValidationContext(this, null, null);
var valid = Validator.TryValidateObject(this, validationContext, null, validateAllProperties: true);
return valid;
}
private set { ; } //http://developerstreasure.blogspot.com/2010/05/systemruntimeserializationinvaliddataco.html
}
}
}
为了完整起见,这里是 ModelBase:
using System;
using System.ComponentModel;
using System.Linq.Expressions;
namespace Sample.Data.Models.Infrastructure
{
public abstract class ModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(Expression<Func<object>> property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(BindingHelper.Name(property)));
}
}
}
}
和 WebApi Controller (为此目的非常简单):
using System.Web.Http;
using Sample.Data.Models;
namespace Sample.Services.Api.Controllers
{
public class CourtsController : ApiController
{
// GET api/values
public Court Get()
{
return new Court {Abbreviation = "TEST", FullName = "Test Court", Active = true};
}
}
}
我怎样才能得到我认为匿名委托(delegate)通过序列化的内容...被忽略或以其他方式传递?
最佳答案
您使用的是什么版本的 Json.NET?如果您使用的不是最新版本 (5.0.8),请升级到它并再次运行您的应用程序。
关于c# - WebApi 中的 JSON.NET 序列化错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20509337/