2013-09-25 40 views
9

这一个正在杀死我。这里的文章和网络都没有帮助。WebAPI OData错误ObjectContent类型无法序列化内容类型'appliation/json ...'的响应正文''

首先,我正在使用.Net 4.5开发ASP.Net WebForms(而不是MVC)。我发现一个great article可帮助您将OData供稿添加到您的WebForms网站。它像一个冠军一样工作。我能够创建一个EMPTY Web应用程序并使其运行。但是,我注意到它没有使用我通过this article创建的最新(并且更容易)EntitySetController。两者都分开工作。然后,我按摩了原始文章,看它是否可以处理EntitySetController,它可以。建议使用Fiddler来测试OData及其过滤。哦,快乐的一天。

我的下一步是将其添加到我现有的ASP.Net 4.5 WebForms应用程序中。有点工作。编译的一切,我可以打电话给locallhost:55777/kid和它的预期收益Products

<workspace> 
    <atom:title type="text">Default</atom:title> 
    <collection href="Products"> 
    <atom:title type="text">Products</atom:title> 
    </collection> 
</workspace> 

我再试试GetGetEntityByKey方法和它们运行和回馈他们应该。不过,我得到了以下错误消息:

{ 
    "odata.error":{ 
    "code":"","message":{ 
     "lang":"en-US","value":"An error has occurred." 
    }, 
    "innererror":{ 
     "message":"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; odata=minimalmetadata; streaming=true; charset=utf-8'.", 
     "type":"System.InvalidOperationException", 
     "stacktrace":"", 
     "internalexception":{ 
     "message":"No IdLink factory was found. Try calling HasIdLink on the EntitySetConfiguration for 'Products'.", 
     "type":"System.InvalidOperationException", 
     "stacktrace":" at System.Web.Http.OData.Builder.EntitySetLinkBuilderAnnotation.BuildIdLink(EntityInstanceContext instanceContext, ODataMetadataLevel metadataLevel)\r\n 
         at System.Web.Http.OData.Builder.EntitySetLinkBuilderAnnotation.BuildEntitySelfLinks(EntityInstanceContext instanceContext, ODataMetadataLevel metadataLevel)\r\n 
         at System.Web.Http.OData.Formatter.Serialization.ODataEntityTypeSerializer.CreateEntry(SelectExpandNode selectExpandNode, EntityInstanceContext entityInstanceContext)\r\n 
         at System.Web.Http.OData.Formatter.Serialization.ODataEntityTypeSerializer.WriteEntry(Object graph, ODataWriter writer, ODataSerializerContext writeContext)\r\n 
         at System.Web.Http.OData.Formatter.Serialization.ODataEntityTypeSerializer.WriteObjectInline(Object graph, IEdmTypeReference expectedType, ODataWriter writer, ODataSerializerContext writeContext)\r\n 
         at System.Web.Http.OData.Formatter.Serialization.ODataEntityTypeSerializer.WriteObject(Object graph, Type type, ODataMessageWriter messageWriter, ODataSerializerContext writeContext)\r\n 
         at System.Web.Http.OData.Formatter.ODataMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content, HttpContentHeaders contentHeaders)\r\n 
         at System.Web.Http.OData.Formatter.ODataMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext)\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__10.MoveNext()" 
     } 
    } 
    } 
} 

控制器是:

using System.Collections.Generic; 
using System.Linq; 
using System.Web.Http.OData; 

namespace BOR.InternalWebsite.Controllers { 

    public class ProductsController : EntitySetController<Product, int> { 

     static List<Product> products = new List<Product>() { 
      new Product() { ID = 1, Name = "Hat", Price = 15, Category = "Apparel" }, 
      new Product() { ID = 2, Name = "Socks", Price = 5, Category = "Apparel" }, 
      new Product() { ID = 3, Name = "Scarf", Price = 12, Category = "Apparel" }, 
      new Product() { ID = 4, Name = "Yo-yo", Price = 4.95M, Category = "Toys" }, 
      new Product() { ID = 5, Name = "Puzzle", Price = 8, Category = "Toys" }, 
     }; 

     public override IQueryable<Product> Get() { 
      return products.AsQueryable(); 
     } 

     protected override Product GetEntityByKey(int key) { 
      return products.FirstOrDefault(p => p.ID == key); 
     } 

    } 
} 

的WebApiConfig是:

using Microsoft.Data.Edm; 
using System.Web.Http; 
using System.Web.Http.OData.Builder; 

namespace BOR.InternalWebsite { 

    public static class WebApiConfig { 

     public static void Register(HttpConfiguration config) { 
      config.EnableQuerySupport(); 

      ODataModelBuilder modelBuilder = new ODataModelBuilder(); 
      var products = modelBuilder.EntitySet<Product>("Products"); 

      IEdmModel model = modelBuilder.GetEdmModel(); 
      config.Routes.MapODataRoute("ODataRoute", "kid", model); 
     } 

    } 
} 

Global.asax.cs文件的Application_Start无关,但以下几点:

WebApiConfig.Register(GlobalConfiguration.Configuration); 

只是为了向您展示我在该项目中拥有的软件包,这里是我的Packages.config文件。我知道Microsoft.AspNet.WebApi.*项目是预发布的。我在目前的稳定版中拥有它们,没有什么不同,所以我想我会试着看看预发布版是否能解决它。

<?xml version="1.0" encoding="utf-8"?> 
<packages> 
    <package id="DynamicDataTemplatesCS" version="1.0.1" targetFramework="net45" /> 
    <package id="elmah" version="1.2.2" targetFramework="net45" /> 
    <package id="elmah.corelibrary" version="1.2.2" targetFramework="net45" /> 
    <package id="EntityFramework" version="5.0.0" targetFramework="net45" /> 
    <package id="jQuery" version="2.0.3" targetFramework="net45" /> 
    <package id="jquery.mobile" version="1.3.2" targetFramework="net45" /> 
    <package id="jQuery.UI.Combined" version="1.10.3" targetFramework="net45" /> 
    <package id="knockoutjs" version="2.3.0" targetFramework="net45" /> 
    <package id="Microsoft.AspNet.WebApi" version="5.0.0-rc1" targetFramework="net45" /> 
    <package id="Microsoft.AspNet.WebApi.Client" version="5.0.0-rc1" targetFramework="net45" /> 
    <package id="Microsoft.AspNet.WebApi.Core" version="5.0.0-rc1" targetFramework="net45" /> 
    <package id="Microsoft.AspNet.WebApi.OData" version="5.0.0-rc1" targetFramework="net45" /> 
    <package id="Microsoft.AspNet.WebApi.WebHost" version="5.0.0-rc1" targetFramework="net45" /> 
    <package id="Microsoft.Bcl" version="1.1.3" targetFramework="net45" /> 
    <package id="Microsoft.Bcl.Build" version="1.0.10" targetFramework="net45" /> 
    <package id="Microsoft.Data.Edm" version="5.6.0" targetFramework="net45" /> 
    <package id="Microsoft.Data.OData" version="5.6.0" targetFramework="net45" /> 
    <package id="Microsoft.Net.Http" version="2.2.15" targetFramework="net45" /> 
    <package id="Newtonsoft.Json" version="5.0.6" targetFramework="net45" /> 
    <package id="System.Spatial" version="5.6.0" targetFramework="net45" /> 
    <package id="Twitter.Bootstrap" version="3.0.0" targetFramework="net45" /> 
</packages> 

因为我可以独立工作,所以我认为有些事情会变得越来越困难。任何有用的帮助将不胜感激! TIA!

编辑==解决方案

由于@RaghuRam一个需要改变是WebApiConfig的注册方法的唯一的事情。更新后的工作版本如下:

config.EnableQuerySupport(); 

ODataConventionModelBuilder modelBuilder = new ODataConventionModelBuilder(); 
var products = modelBuilder.EntitySet<Product>("Products"); 

IEdmModel model = modelBuilder.GetEdmModel(); 
config.Routes.MapODataRoute("ODataRoute", "kid", model); 

太棒了!

回答

10

取而代之的是ODataModelBuilder的,使用ODataConventionModelBuilder这样,

var modelBuilder = new ODataConventionModelBuilder(); 
var products = modelBuilder.EntitySet<Product>("Products"); 

IEdmModel model = modelBuilder.GetEdmModel(); 

是打算用来当你要明确配置整个模型非常低的水平一流。你需要告诉它每一个属性,每一个导航属性,然后自我链接(id,编辑和阅读)和导航链接。

,另一方面ODataConventionModelBuilder,有一定的约定,自动推断这些东西。只有当您偏离惯例时,您才需要明确配置ODataConventionModelBuilder

如果您仍然希望使用ODataModelBuilder类,你应该这样写代码,

ODataModelBuilder modelBuilder = new ODataModelBuilder(); 
var products = modelBuilder.EntitySet<Product>("Products"); 
var product = products.EntityType; 

product.HasKey(p => p.ID); 
product.Property(p => p.Name); 
product.Property(p => p.Price); 
product.Property(p => p.Category); 

products.HasIdLink((ctxt) => ctxt.Url.ODataLink(new EntitySetPathSegment("Products"), new KeyValuePathSegment(ctxt.EntityInstance.ID))); 

IEdmModel model = modelBuilder.GetEdmModel(); 

事情变得更加复杂,一旦你有导航属性和相关entitysets等

+0

请更新你的答案,你在第一个例子中使用了旧的 –

相关问题