我正在开发一个新的OData项目,并且第一次尝试使用Web API 2进行。OData 源的放置非常简单,与 WCF 相比,这很棒。
我现在遇到的问题是我的 OData 源将在"多租户"环境中使用,我想根据租户对源使用"友好"URL。因此,理想情况下,我需要提要 URL 如下所示:
/store/tenant1/Products
/store/tenant2/Products
这两个 URL 都指向相同的控制器,最终指向相同的数据集,但我想根据租户强制实施一些实体筛选。显然,这将很困难,并且与标准 Web API 路由有些不同,因为我只能指定路由前缀,而不能指定路由模板。
到目前为止,我已经修改了我的 OData 控制器以将租户名称作为参数,这在点击以下 url 时效果很好(这不是我想要的,请参阅上面的目标):
http://mydomainname/odata/Products?tenantName=test
使用此路由定义:
ODataConventionModelBuilder modelBuilder = new ODataConventionModelBuilder();
modelBuilder.EntitySet<Product>("Products");
IEdmModel model = modelBuilder.GetEdmModel();
config.Routes.MapODataRoute(routeName: "OData", routePrefix: "odata", model: model);
这是我的控制器上的示例操作:
[Queryable]
public IQueryable<Product> GetPproducts(string tenantName)
{
return _products.Where(p=>p.TenantName == tenantName);
}
我不太确定这是否可能,我最后的手段是使用 URL 重写规则,但我宁愿避免这种情况并以正确的方式将所有内容都放在代码中。
非常感谢您的帮助!
经过一些调查,我发现它以这种方式工作: 只需将路由前缀名称应用于查询,例如:
public class MoviesController : ODataController
{
private MoviesContext _db = new MoviesContext();
public IHttpActionResult Get()
{
var routeName=Request.ODataProperties().RouteName;
ODataRoute odataRoute=Configuration.Routes[routeName] as ODataRoute;
var prefixName = odataRoute.RoutePrefix;
return Ok(_db.Movies.Where(m=>m.Title.StartsWith(prefixName)));
}
// Other methods here
}
注意:上面的代码基于 ODataActionsSample in https://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/OData/v4/现在OData v4已经成为OASIS的标准,但v3不是,所以v4似乎是一个很好的起点。