gpt4 book ai didi

c# - WebAPI OData 错误 ObjectContent 类型无法序列化内容类型 'application/json...' 的响应正文

转载 作者:行者123 更新时间:2023-12-01 23:48:48 25 4
gpt4 key购买 nike

这个简直要杀了我。这里的文章和网络都没有帮助。

首先,我正在使用 .Net 4.5 开发 ASP.Net WebForms(不是 MVC)。我找到了great article它可以帮助您将 OData feed 添加到 WebForms 站点。它的表现就像冠军一样。我能够创建一个空的 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()"
}
}
}
}

Controller 是:

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 的 Register 方法。更新后的工作版本如下:

config.EnableQuerySupport();

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

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

太棒了!

最佳答案

不要使用 ODataModelBuilder,而是像这样使用 ODataConventionModelBuilder,

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

IEdmModel model = modelBuilder.GetEdmModel();

ODataModelBuilder 是一个非常低级别的类,旨在在您想要显式配置整个模型时使用。您需要告诉它每个属性、每个导航属性,然后是自链接(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();

一旦有了导航属性和相关实体集等,事情就会变得更加复杂。

关于c# - WebAPI OData 错误 ObjectContent 类型无法序列化内容类型 'application/json...' 的响应正文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19013651/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com