gpt4 book ai didi

c# - 使用自定义路由实现 ODataController 返回 "The related entity set could not be found from the OData path"错误

转载 作者:太空宇宙 更新时间:2023-11-03 10:58:24 25 4
gpt4 key购买 nike

我正在尝试从我们当前的 ApiController 实现转移到 ODataController,因为这是我发现可以启用返回 OData Json 格式数据的唯一方法。 (与问题 here 相同,但解决方案对我不起作用)

我一直在尝试锻炼 ODataController,我发现它在 this 之后工作得很好.但是,我的项目实现了与简单“~/odata/Entity”的默认 OData 路由不同的路由。我需要将我的 Controller 分组到区域中,因为有些 Controller 名称重复。

正在关注 thisthis ,我能够实现自定义路由并运行它似乎可以到达正确的 Controller 并成功通过它。但是,我在

的 Fiddler 中仍然报错

"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json;odata=minimalmetadata; streaming=true; charset=utf-8'."

有一个内部异常(exception)

The related entity set could not be found from the OData path. The related entity set is required to serialize the payload

现在我已经被它困了几个小时。没有路由处理程序和简单地通过“~/odata/Entity”访问数据,我的代码工作得很好。就在我实现自定义路由时,它在通过我的 Controller 代码后失败了。

如有任何帮助,我们将不胜感激。

这是一些代码:

全局.asax:

            //Added this on App_Start
config.Services.Replace(typeof(IHttpControllerSelector), new CustomHttpControllerSelector(config));

//Snippet from RegisterRoutes
ODataConventionModelBuilder modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntitySet<Entity>("Entities");
IEdmModel model = modelBuilder.GetEdmModel();

config.Routes.MapODataRoute(
routeName: "ODataDefault",
routePrefix: "{version}/{area}/{controller}", //Works since I could reach my controller
model: model);

Controller :

        [HttpGet]
[Queryable(AllowedQueryOptions = AllowedQueryOptions.All)]
public IQueryable<Entity> Get()
{
EntitySet entitySet = new EntitySet();
return entitySet.Entities;
}

CustomHttpControllerSelector:

继承自 this .基本上,这只是解析请求以获取特定的 Controller 描述符。

private HttpControllerDescriptor GetController(HttpRequestMessage request)
{
HttpControllerDescriptor descriptor = null;

IHttpRouteData routeData = request.GetRouteData();

// Get variables from the route data.
string versionName = null;
routeData.Values.TryGetValue("version", out versionName );

string areaName = null;
routeData.Values.TryGetValue("area", out areaName);

string controllerName = null;
routeData.Values.TryGetValue("controller", out controllerName);

string fullName = string.Format(CultureInfo.InvariantCulture, "{0}.{1}.{2}", versionName, areaName, controllerName);

// Search for the controller.
// _controllerTypes is a list of HttpControllerDescriptors
var type = _controllerTypes.Where(t => t.Key.EndsWith(fullName, StringComparison.OrdinalIgnoreCase)).Select(t => t.Value).FirstOrDefault();

if (type != null)
{
descriptor = new HttpControllerDescriptor(_configuration, controllerName, type);
}

return descriptor;
}

最佳答案

最终通过删除 routePrefix 的 {controller} 部分并实现自定义 IODataRoutingConvention 以在路由的初始解析未检测到 Controller 值时输入默认 Controller 值来解决此问题。代码如下:

public string SelectController(ODataPath odataPath, HttpRequestMessage request)
{
string controllerName = ""

//do stuff here to select controller

return controllerName;
}

我猜这是 ApiController 的 map 路由中默认和约束参数的长替代品

RouteTable.Routes.MapHttpRoute(
name: "RouteName",
routeTemplate: "{version}/{area}/{controller}",
defaults: new { controller = controllerName },
constraints: new { version = v1 }
);

注意: 目前将此作为答案发布,但如果有人有更好的解释,我会检查一下。 :)

关于c# - 使用自定义路由实现 ODataController 返回 "The related entity set could not be found from the OData path"错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18593314/

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