Iva*_*ono 33 c# odata asp.net-web-api
在将OData添加到我的项目之前,我的路由设置如下:
config.Routes.MapHttpRoute(
name: "ApiById",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: new { id = @"^[0-9]+$" },
handler: sessionHandler
);
config.Routes.MapHttpRoute(
name: "ApiByAction",
routeTemplate: "api/{controller}/{action}",
defaults: new { action = "Get" },
constraints: null,
handler: sessionHandler
);
config.Routes.MapHttpRoute(
name: "ApiByIdAction",
routeTemplate: "api/{controller}/{id}/{action}",
defaults: new { id = RouteParameter.Optional },
constraints: new { id = @"^[0-9]+$" },
handler: sessionHandler
Run Code Online (Sandbox Code Playgroud)
所有控制器都提供Get,Put(操作名称为Create),Patch(操作名称为Update)和Delete.例如,客户端使用这些各种标准URL来表示CustomerType请求:
string getUrl = "api/CustomerType/{0}";
string findUrl = "api/CustomerType/Find?param={0}";
string createUrl = "api/CustomerType/Create";
string updateUrl = "api/CustomerType/Update";
string deleteUrl = "api/CustomerType/{0}/Delete";
Run Code Online (Sandbox Code Playgroud)
然后我添加了一个OData控制器,其动作名称与我的其他Api控制器相同.我还添加了一条新路线:
ODataConfig odataConfig = new ODataConfig();
config.MapODataServiceRoute(
routeName: "ODataRoute",
routePrefix: null,
model: odataConfig.GetEdmModel()
);
Run Code Online (Sandbox Code Playgroud)
到目前为止,我在客户端没有任何改变.当我发送请求时,我收到406 Not Available错误.
路线混乱了吗?我怎么解决这个问题?
Jee*_*Lee 73
如果您使用的是OData V4,请替换 using System.Web.Http.OData;
同 using System.Web.OData;
在ODataController为我工作.
Jer*_*her 18
配置路由的顺序具有影响.就我而言,我也有一些标准的MVC控制器和帮助页面.所以在Global.asax:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(config =>
{
ODataConfig.Register(config); //this has to be before WebApi
WebApiConfig.Register(config);
});
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
Run Code Online (Sandbox Code Playgroud)
当我启动项目并且需要时,过滤器和routeTable部件不存在.
ODataConfig.cs:
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes(); //This has to be called before the following OData mapping, so also before WebApi mapping
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Site>("Sites");
//Moar!
config.MapODataServiceRoute("ODataRoute", "api", builder.GetEdmModel());
}
Run Code Online (Sandbox Code Playgroud)
WebApiConfig.cs:
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute( //MapHTTPRoute for controllers inheriting ApiController
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
Run Code Online (Sandbox Code Playgroud)
作为奖励,这是我的RouteConfig.cs:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute( //MapRoute for controllers inheriting from standard Controller
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
}
Run Code Online (Sandbox Code Playgroud)
这必须是那个确切的顺序.我尝试移动调用并最终导致MVC,Api或Odata因404或406错误而中断.
所以我可以打电话:
localhost:xxx/ - >导致帮助页面(家庭控制器,索引页面)
localhost:xxx/api/ - >导致OData $元数据
localhost:xxx/api/Sites - >导致我的SitesController的Get方法继承自ODataController
localhost:xxx/api/Test - >导致我继承自ApiController的TestController的Get方法.
mar*_*oss 11
将routePrefix设置为"api".
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<CustomerType>("CustomerType");
config.MapODataServiceRoute(routeName: "ODataRoute", routePrefix: "api", model: builder.GetEdmModel());
Run Code Online (Sandbox Code Playgroud)
你使用哪个OData版本?System.Web.OData对于V3 ,检查OData V4使用的正确名称空间System.Web.Http.OData.控制器中使用的命名空间必须与WebApiConfig中使用的命名空间一致.
另一件需要考虑的事情是URL区分大小写,因此:
localhost:xxx/api/Sites -> OK
localhost:xxx/api/sites -> HTTP 406
我遇到的问题是我已将我的实体集命名为“产品”,并且具有一个ProductController。原来,实体集的名称必须与您的控制器名称匹配。
所以
builder.EntitySet<Product>("Products");
Run Code Online (Sandbox Code Playgroud)
使用名为ProductController的控制器将给出错误。
/ api /产品将给出406
/ api /产品将给出404
因此,使用某些新的C#6功能,我们可以改为:
builder.EntitySet<Product>(nameof(ProductsController).Replace("Controller", string.Empty));
Run Code Online (Sandbox Code Playgroud)
此页面上的所有优秀解决方案都不适合我。通过调试,我可以看到路由被选中并且 OData 查询正在正确运行。但是,在控制器退出后,它们被破坏了,这表明是格式导致了 OData 全能错误:406 Not Acceptable。
我通过添加一个基于 Json.NET 库的自定义格式化程序来解决这个问题:
public class JsonDotNetFormatter : MediaTypeFormatter
{
public JsonDotNetFormatter()
{
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/json"));
}
public override bool CanReadType(Type type)
{
return true;
}
public override bool CanWriteType(Type type)
{
return true;
}
public override async Task<object> ReadFromStreamAsync(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)
{
using (var reader = new StreamReader(readStream))
{
return JsonConvert.DeserializeObject(await reader.ReadToEndAsync(), type);
}
}
public override async Task WriteToStreamAsync(Type type, object value, Stream writeStream, HttpContent content, TransportContext transportContext)
{
if (value == null) return;
using (var writer = new StreamWriter(writeStream))
{
await writer.WriteAsync(JsonConvert.SerializeObject(value, new JsonSerializerSettings {ReferenceLoopHandling = ReferenceLoopHandling.Ignore}));
}
}
Run Code Online (Sandbox Code Playgroud)
然后在WebApiConfig.cs,我添加了这一行config.Formatters.Insert(0, new JsonDotNetFormatter())。请注意,我严格遵守 Jerther 的回答中描述的顺序。
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
ConfigureODataRoutes(config);
ConfigureWebApiRoutes(config);
}
private static void ConfigureWebApiRoutes(HttpConfiguration config)
{
config.Routes.MapHttpRoute("DefaultApi", "api/{controller}/{id}", new { id = RouteParameter.Optional });
}
private static void ConfigureODataRoutes(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Formatters.Insert(0, new JsonDotNetFormatter());
var builder = new ODataConventionModelBuilder();
builder.EntitySet<...>("<myendpoint>");
...
config.MapODataServiceRoute("ODataRoute", "odata", builder.GetEdmModel());
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
33579 次 |
| 最近记录: |