c# - WebApi 中的 JSON.NET 序列化错误

标签 c# json serialization asp.net-web-api json.net

我有一个 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/

相关文章:

javascript - 对 json 数据进行排序

javascript - JSON 通信破坏特殊字符

java - 在 ehcache 中序列化元素时出错

c# - 如何在 Elasticsearch 中使用 Entity Framework

c# - 将枚举值转换为字符串数组

C# 如何暂停我的程序并等待来自 WinForm 的键盘输入

json - 有没有办法快速将 Json<Value> 转换为 bson 以便能够将其保存到 mongo?

.net - JSON 序列化需要很长时间

c# - 使用 XmlSerializer 序列化整数数组

c# - Xamarin Studio c# 空传播运算符