【问题标题】:WebAPI2 + Angular http GET - returning IEnumerable<Categories>. failed to serialize the response body for content type 'application/jsonWebAPI2 + Angular http GET - 返回 IEnumerable<Categories>。未能序列化内容类型“application/json”的响应正文
【发布时间】:2014-06-26 13:13:13
【问题描述】:

当我们说话时我正在学习这个,发现其中一些非常奇怪和困难;)

这是 Angular 中的其余服务调用:

$scope.categories = [];
    $scope.selectedCategory = null;

    $http({
            method: 'GET',
            url: './api/file/GetCategories',
            accept: 'application/json'
        })
        .success(function(result) {
        $scope.categories = result;
    });

这是我要获取的服务:(C# - FileController.cs)

public IEnumerable<Category> GetCategories()
    {
        return FileServices.GetCategoriesForUser();

    }

文件服务方法:

public static IEnumerable<Category> GetCategoriesForUser()
    {
        User currentUser = UserServices.GetLoggedInUser();
        IEnumerable<Category> userCategories;
        using (var context = new PhotoEntities())
        {
            userCategories = context.Categories.Where(c => c.UserId == currentUser.Id);
        }
        return userCategories;
    }

问题在于它可能根本无法将其识别为 JSON,但是,唉!这是整个响应错误消息:

{"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 'Categories' on 'System.Data.Entity.DynamicProxies.User_523AFE24D26493BB74E43EAA23AAEBFD40D7EABFCAA3A6105EB951B365E60A04'.","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, Type objectType)\r\n   at Newtonsoft.Json.JsonSerializer.SerializeInternal(JsonWriter jsonWriter, Object value, Type objectType)\r\n   at Newtonsoft.Json.JsonSerializer.Serialize(JsonWriter jsonWriter, Object value)\r\n   at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding)\r\n   at System.Net.Http.Formatting.JsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, Encoding effectiveEncoding)\r\n   at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content)\r\n   at System.Net.Http.Formatting.BaseJsonMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.GetResult()\r\n   at System.Web.Http.WebHost.HttpControllerHandler.<WriteBufferedResponseContentAsync>d__1b.MoveNext()","InnerException":{"Message":"An error has occurred.","ExceptionMessage":"The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.","ExceptionType":"System.ObjectDisposedException","StackTrace":"   at System.Data.Entity.Core.Objects.ObjectContext.get_Connection()\r\n   at System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption)\r\n   at System.Data.Entity.Core.Objects.ObjectQuery`1.Execute(MergeOption mergeOption)\r\n   at System.Data.Entity.Core.Objects.DataClasses.EntityCollection`1.Load(List`1 collection, MergeOption mergeOption)\r\n   at System.Data.Entity.Core.Objects.DataClasses.EntityCollection`1.Load(MergeOption mergeOption)\r\n   at System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.Load()\r\n   at System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.DeferredLoad()\r\n   at System.Data.Entity.Core.Objects.Internal.LazyLoadBehavior.LoadProperty[TItem](TItem propertyValue, String relationshipName, String targetRoleName, Boolean mustBeNull, Object wrapperObject)\r\n   at System.Data.Entity.Core.Objects.Internal.LazyLoadBehavior.<>c__DisplayClass7`2.<GetInterceptorDelegate>b__1(TProxy proxy, TItem item)\r\n   at System.Data.Entity.DynamicProxies.User_523AFE24D26493BB74E43EAA23AAEBFD40D7EABFCAA3A6105EB951B365E60A04.get_Categories()\r\n   at GetCategories(Object )\r\n   at Newtonsoft.Json.Serialization.DynamicValueProvider.GetValue(Object target)"}}}

【问题讨论】:

    标签: c# angularjs rest asp.net-web-api2


    【解决方案1】:

    尝试将此添加到 App_Start 文件夹中配置文件中的 Register() 函数中:

    var json = config.Formatters.JsonFormatter;
    json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
    config.Formatters.Remove(config.Formatters.XmlFormatter);
    

    我遇到了类似的问题,这为我解决了问题。摘自:http://social.msdn.microsoft.com/Forums/vstudio/en-US/a5adf07b-e622-4a12-872d-40c753417645/

    【讨论】:

    • 嘿,Rob,感谢您的快速回复:) 刚刚在 webapiconfig.cs 中添加了代码行,但恐怕没有区别.... {"$id":"1", "Message":"发生错误。","ExceptionMessage":"'ObjectContent`1' 类型未能序列化内容类型 'application/json; charset=utf-8' 的响应正文。","ExceptionType" :"System.InvalidOperationException","StackTrace":null,"InnerException":{"$id":"2","Message":"发生错误。","ExceptionMessage":"从 'Categories 获取值时出错'
    • 我把这一行“GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;”并且数据变得更有条理
    【解决方案2】:

    我已经养成了返回 HttpResponseMessage 的习惯,这样我就可以直接控制状态和内容类型。这里有一些代码可以为你做到这一点。

    public class StuffController : ApiController
    {
        public HttpResponseMessage Get()
        {
            List<SomeModel> models = ReadModels();
            return GetJsonResponse(models);
        }
    }
    
    public static HttpResponseMessage GetJsonResponse(object serializableObject)
    {
        string jsonText = JsonConvert.SerializeObject(serializableObject, Formatting.Indented);
        HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK);
        response.Content = new StringContent(jsonText, Encoding.UTF8, "text/plain");
    
        return response;
    }
    

    【讨论】:

    • 谢谢 :) 但是......只是一个新手的后续问题......它如何知道调用了哪个 get 方法?而且..您的 Get() 会发送 JSON 吗?公共静态 IEnumerable GetCategoriesForUser()
    • 我自己还是 WebApi 的菜鸟。如果您不修改路由,它将基于 HTTP 动词和您传入的参数。我知道它还有很多。您可以在 WebApiConfig.cs 中修改默认路由。
    【解决方案3】:

    只需使用列表:

    public static List<Category> GetCategoriesForUser()
        {
            User currentUser = UserServices.GetLoggedInUser();
            IEnumerable<Category> userCategories = new List<Category>();
            using (var context = new PhotoEntities())
            {
                userCategories.addRange(context.Categories.Where(c => c.UserId == currentUser.Id).toList());
            }
            return userCategories;
        }
    

    IEnumerable 是一个接口,不能创建接口实例。

    编辑:更改为 addRange 方法。 并将您的服务从 IEnumerable 更改为 List:

    public List<Category> GetCategories()
    

    【讨论】:

      猜你喜欢
      • 2012-12-12
      • 2017-07-17
      • 1970-01-01
      • 2017-02-01
      • 2013-10-01
      • 1970-01-01
      • 2013-03-28
      • 2015-06-27
      • 1970-01-01
      相关资源
      最近更新 更多