无法序列化内容类型的响应正文 [英] Failed to serialize the response body for content type

查看:30
本文介绍了无法序列化内容类型的响应正文的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个同时使用控制器和 ApiController 的 MVC4 应用程序.我修改了默认的 Web API 路由以包含操作名称.当我尝试获取基准列表时,收到以下错误消息:

I'm building a MVC4 application that uses both Controllers and ApiControllers. I modified the default Web API route to include action names. When I try to get a list of Benchmarks, I'm getting this error message:

'ObjectContent`1' 类型未能序列化响应正文内容类型'应用程序/json;字符集=utf-8'

The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; charset=utf-8'

InnerException 是这样的(在这种情况下我将返回 JSON,XML 也是如此):

The InnerException is this (I'm returning JSON in that case, same happens with XML):

"InnerException": {
"Message": "An error has occurred.",
"ExceptionMessage": "Error getting value from 'IdentityEqualityComparer' on 'NHibernate.Proxy.DefaultLazyInitializer'.",
"ExceptionType": "Newtonsoft.Json.JsonSerializationException",
"StackTrace": " at Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target) at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty) at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeISerializable(JsonWriter writer, ISerializable value, JsonISerializableContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty) at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(JsonWriter writer, Object value, JsonObjectContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty) at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeList(JsonWriter writer, IWrappedCollection values, JsonArrayContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty) at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeValue(JsonWriter writer, Object value, JsonContract valueContract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerProperty) at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.Serialize(JsonWriter jsonWriter, Object value) at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value) at System.Net.Http.Formatting.JsonMediaTypeFormatter.<>c__DisplayClassd.<WriteToStreamAsync>b__c() 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 GetIdentityEqualityComparer(Object ) at Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)"
}

这是我运行的代码:

// GET api/benchmark/getincomplete
        [HttpGet]
        public IList<Benchmark> GetIncomplete()
        {
            var s = HibernateModule.CurrentSession;
            var benchList = s.QueryOver<Benchmark>()
                                .Where(b => !b.Completed)
                                .Where(b => !b.Deleted)
                                .OrderBy(b => b.Id).Asc
                                .List<Benchmark>();

            return benchList;
        }

这是基准模型:

public class Benchmark
    {
        public virtual int Id { get; set; }
        [Required]
        [DataType(DataType.Date)]
        public virtual DateTime Date { get; set; }
        [Required, ScriptIgnore]
        public virtual IList<TestResult> Results { get; set; }
        [Required]
        public virtual IList<TestCase> TestCases { get; set; }
        [AllowHtml]
        public virtual string Description { get; set; }
        public virtual Device Device { get; set; }        
        public virtual bool Published { get; set; }
        [Display(Name = "Deleted"), ScriptIgnore]
        public virtual bool Deleted { get; set; }
        public virtual bool Completed { get; set; }

        public Benchmark() 
        {
            Results = new List<TestResult>();
            TestCases = new List<TestCase>();
            Published = false;
            Deleted = false;
            Completed = false;
        }
    }

我不太确定问题出在哪里.可能是 NHibernate 代理(我使用 Fluent NHibernate)?奇怪的是,如果我不使用 ApiController,并手动返回 JSON,这将完美运行!

I'm not quite sure where the problem lies. Could it be the NHibernate Proxy (I use Fluent NHibernate)? The odd thing is that if I don't use an ApiController, and manually return JSON, this works just perfectly!

更新:

根据下面的答案,这是我必须在 Application_Start() 中添加的代码:

As per the answer below, this is the code I had to add in Application_Start() :

HttpConfiguration config = GlobalConfiguration.Configuration;
((DefaultContractResolver)config.Formatters.JsonFormatter.SerializerSettings.ContractResolver).IgnoreSerializableAttribute = true;

推荐答案

IdentityEqualityCompairer 在 NHibernate 框架中似乎有 [SerializableAttribute] 注释.

取自对此处答案的评论 为什么Web API 不会反序列化它,但 JSON.Net 会吗?看起来 JSON.NET 在 WebApi 使用和它的独立使用之间的配置有点不同.

Taken from a comment on an answer here Why won't Web API deserialize this but JSON.Net will? it looks like JSON.NET is configured a little differently between WebApi usage and it's standalone usage.

Json.NET 序列化程序默认将 IgnoreSerializableAttribute 设置为 true.在 WebAPI 中,我们将其设置为 false.

Json.NET serializer by default set the IgnoreSerializableAttribute to true. In WebAPI, we set that to false.

因此,鉴于您无法取消 [SerializableAttribute](因为它不在您的代码中),您可以尝试使用此答案更改默认的 WebApi JSON.NET 设置以忽略它这里:

So given you cannot take the [SerializableAttribute] off (as it is not within your code) you could try changing the default WebApi JSON.NET setting to ignore it using this answer here:

((DefaultContractResolver)config.Formatters.JsonFormatter.SerializerSettings.ContractResolver).IgnoreSerializableAttribute = true;

也许还可以考虑对在响应中发送的结果使用 DTO - 这将使您完全控制通过网络发送的对象.

Perhaps also consider Using a DTO for your results being sent over in the response - this will give you full control over the object being sent over the wire.

这篇关于无法序列化内容类型的响应正文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆