首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >使用自定义路由实现ODataController返回“从OData路径找不到相关实体集”错误

使用自定义路由实现ODataController返回“从OData路径找不到相关实体集”错误
EN

Stack Overflow用户
提问于 2013-09-03 05:15:10
回答 1查看 7.2K关注 0票数 2

我正在尝试从当前的ApiController实现转移到ODataController,因为这是我找到的唯一可能的方法,可以返回OData Json格式的数据。( 这里的问题也是如此,但这个解决方案对我不起作用)

我一直在努力锻炼ODataController,我发现它在之后运行得很好。但是,我的项目实现了与简单“~/ OData /odata”的默认路由不同的路由。我需要将我的控制器分组到各个区域,因为有些控制器在名称上是重复的。

之后,我实现了定制的路由和运行--它似乎到达了正确的控制器,并成功地通过了它。然而,我仍然在Fiddler中得到了一个错误

“'ObjectContent`1‘1’类型未能序列化内容类型的响应主体‘application/json;odata=极小元数据;streaming=true;charset=utf-8’。”

但内在的例外是

在OData路径中找不到相关的实体集。序列化有效负载需要相关的实体集。

现在我被困在里面好几个小时了。没有路由处理程序,只需通过"~/odata/Entity“访问数据,我的代码就能工作得很好。只有当我实现自定义路由时,它才会在通过我的控制器代码之后失败。

任何帮助都将不胜感激。

下面是一些代码:

Global.asax:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
            //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);

主计长:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
        [HttpGet]
        [Queryable(AllowedQueryOptions = AllowedQueryOptions.All)]
        public IQueryable<Entity> Get()
        {
            EntitySet entitySet = new EntitySet();
            return entitySet.Entities;
        }

CustomHttpControllerSelector:

出发。基本上,这只是解析请求以获得特定的控制器描述符。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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;
        }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-09-11 20:38:11

最终,只要删除routePrefix的{routePrefix}部分并实现一个自定义的控制器值,当路由的初始解析没有检测到控制器值时,就可以输入默认的控制器值来解决这个问题。守则如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public string SelectController(ODataPath odataPath, HttpRequestMessage request)
{
     string controllerName = ""

     //do stuff here to select controller

     return controllerName;
}

我猜这是ApiController地图路由中默认参数和禁忌参数的长替代

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
RouteTable.Routes.MapHttpRoute(
    name: "RouteName",
    routeTemplate: "{version}/{area}/{controller}",
    defaults: new { controller = controllerName },
    constraints: new { version = v1 }
);

备注:现在发布了这个答案,但是如果有人有更好的解释,我会检查的。:)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18593314

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文