我们已经有了一套MVC apis,但我已被要求提供OData版本。我试图在同一个应用程序中共同定位两个集合,以共享自定义角色提供程序之类的东西。我是OData的新手,到目前为止MVC课程似乎没有直接翻译。
使用MVC,我们采用了泛型初始化并使用RouteAttribute管理所有路由,我尝试使用ODataRouteAttribute进行相同的样式,但是我的所有odata路径都出现了404而$元数据查询返回500表示配置没有&# 39;已初始化。
这里是app start配置块(在MVC之后添加了ODataApiConfig):
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
ODataApiConfig.Configure(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
GlobalConfiguration.Configuration.EnsureInitialized();
以及ODataApiConfig中的内容:
// OData v7 replacement for configuration.EnableCaseInsensitive(true);
configuration.MapODataServiceRoute("odata", "odata",
builder =>
builder.AddService<IEnumerable<IODataRoutingConvention>>(ServiceLifetime.Singleton, sp => ODataRoutingConventions.CreateDefaultWithAttributeRouting("odata", configuration))
.AddService<ODataUriResolver>(ServiceLifetime.Singleton, sp => new CaseInsensitiveResolver())
);
ODataModelBuilder modeler = new ODataConventionModelBuilder();
modeler.EntitySet<Task>("Tasks");
configuration.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: "odata",
model: modeler.GetEdmModel()
);
configuration.EnsureInitialized();
这是一个api的例子,我试图联系(获取分配给员工的任务列表):
[HttpGet]
[EnableQuery]
[ODataRoute("v0.1/employee/{userGuid}/tasks")]
[ODataAuthorize(Roles = "Assignee")]
public IHttpActionResult GetMyTasks([FromODataUri]string userGuid)
{
...
}
所以我很困惑为什么 a)对〜/ odata / $ metadata的调用抛出&#34;该对象尚未初始化。确保在所有其他初始化代码之后在应用程序的启动代码中调用HttpConfiguration.EnsureInitialized()。&#34;我尝试在OData / MVC初始化结束时和OData初始化例程内调用EnsureInitialized(),它仍然会抛出相同的错误。
b)我的〜/ odata / employees / {userGuid} / tasks路径出现了404。
任何指针都将受到赞赏。
由于
编辑:〜/ odata / $元数据异常似乎与[ODataRoute]属性的使用有关。这似乎默认启用(并导致异常);当我尝试显式创建路由约定对象并对其进行DI-ing时,$ metadata异常消失了。没有产生很多用处,但例外情况消失了。
异常的堆栈跟踪如下;我尝试打破任何抛出的InvalidOperationExceptions但在调试器中没有中断
{"Message":"An error has occurred.","ExceptionMessage":"The object has not yet been initialized. Ensure that HttpConfiguration.EnsureInitialized() is called in the application's startup code after all other initialization code.","ExceptionType":"System.InvalidOperationException","StackTrace":" at System.Web.OData.Routing.Conventions.AttributeRoutingConvention.get_AttributeMappings()
at System.Web.OData.Routing.Conventions.AttributeRoutingConvention.SelectController(ODataPath odataPath, HttpRequestMessage request)
at System.Web.OData.Routing.ODataPathRouteConstraint.SelectControllerName(ODataPath path, HttpRequestMessage request)
at System.Web.OData.Routing.ODataPathRouteConstraint.Match(HttpRequestMessage request, IHttpRoute route, String parameterName, IDictionary`2 values, HttpRouteDirection routeDirection)
at System.Web.Http.Routing.HttpRoute.ProcessConstraint(HttpRequestMessage request, Object constraint, String parameterName, HttpRouteValueDictionary values, HttpRouteDirection routeDirection)
at System.Web.Http.Routing.HttpRoute.ProcessConstraints(HttpRequestMessage request, HttpRouteValueDictionary values, HttpRouteDirection routeDirection)\r\n at System.Web.Http.Routing.HttpRoute.GetRouteData(String virtualPathRoot, HttpRequestMessage request)
at System.Web.Http.WebHost.Routing.HttpWebRoute.GetRouteData(HttpContextBase httpContext)"}
编辑:至少我在$元数据调用上得到了答案。
本文已通知我的初始化序列:https://blogs.msdn.microsoft.com/davidhardin/2014/12/17/web-api-odata-v4-lessons-learned/
表示你必须首先初始化Web Api调用。我找到了相反的结果。上面的异常是首先初始化Web Api的结果。当我翻转它们时,$ metadata调用开始返回我的Task实体集。
不幸的是,我的TasksController中的[ODataRoute]声明仍然没有被路由。
答案 0 :(得分:0)
好的,问题似乎是这里的一些建议已经过时了: https://blogs.msdn.microsoft.com/davidhardin/2014/12/17/web-api-odata-v4-lessons-learned/
具体来说,$元数据异常是由于在 Web API之后设置OData 引起的(根据上述文章)。您必须在 Web Api之前初始化OData 。
其次,关于控制器发现路由前缀差异的观点是错误的。我做了将我的web api控制器和odata控制器隔离在不同的目录中,我确实使用RoutePrefix / ODataRoutePrefix将它们放在不同的路径上。
但是从github获取AttributeRoutingConvention的源代码并使用它进行调试后,我发现了以下内容:
如果您有2个具有相同类名的控制器(例如两者都称为TaskController),即使它们具有不同的前缀路径并且位于不同的目录中,它们也会发生冲突。两者都从处理中静默删除,因此在请求进入时找不到它们。因此404。
因此,无论前缀和路由属性如何,都需要以不同的方式命名类以包含它们。