Asp.net web api OData按ID和名称获取资源
我有一个代码示例,我正在尝试使第三个Get方法工作,还有Asp.net web api OData按ID和名称获取资源,asp.net-web-api,odata,Asp.net Web Api,Odata,我有一个代码示例,我正在尝试使第三个Get方法工作,还有$expand工作,如下所述 如果我只有方法Get()和Get([FromODataUri]int key),我可以使用这些各自的路由/odata/Products和/odata/Products(1)?$expand=Vendor调用它们。 但是,当我进行以下更改时,我会遇到以下问题 如果我只将参数名key更改为id或方法Get([FromODataUri]int key)中的任何其他内容,则不再调用该方法。/odata/Products
$expand
工作,如下所述
如果我只有方法Get()
和Get([FromODataUri]int key)
,我可以使用这些各自的路由/odata/Products
和/odata/Products(1)?$expand=Vendor
调用它们。
但是,当我进行以下更改时,我会遇到以下问题
key
更改为id
或方法Get([FromODataUri]int key)
中的任何其他内容,则不再调用该方法。/odata/Products(1)
的路由调用转到总是返回所有集合的Get()
方法key
,但将方法更改为其他方法,例如GetByKey([FromODataUri]int key)
,则上述相同问题再次发生/odata/Products?key=1?$expand=Vendor
进行调用,则调用将转到GetByKey([FromODataUri]int key)
,但我不会扩展供应商GetByName([FromODataUri]string name)
,使用此路由调用时,我会得到“error 404 not found”,即/odata/Products('Product 1')
。如果使用/odata/Products?name='Product 1'
或/odata/Products?name='Product 1'$expand=Vendor
调用,则会触发Get()
方法,并且Vendor不会再次展开public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Product ("Products");
config.MapODataServiceRoute("ODataRoute", "odata", builder.GetEdmModel());
}
}
public class ProductsController : ODataController
{
#region
ProductsContext db = new ProductsContext();
private bool ProductExists(int key)
{
return db.Products.Any(p = p.Id == key);
}
protected override void Dispose(bool disposing)
{
db.Dispose();
base.Dispose(disposing);
}
#endregion
[HttpGet]
[EnableQuery]
public IQueryable<Product Get()
{
return db.Products.AsQueryable();
}
[HttpGet]
[EnableQuery]
public SingleResult<Product Get([FromODataUri] int key)
{
IQueryable<Product result = db.Products.Where(p = p.Id == key).AsQueryable();
return SingleResult.Create(result);
}
[HttpGet]
[EnableQuery]
public SingleResult<Product GetByName([FromODataUri] string name)
{
IQueryable<Product result = db.Products.Where(p = p.Name == name).AsQueryable();
return SingleResult.Create(result);
}
}
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
public string Category { get; set; }
public Vendor Vendor { get; set; }
}
public class Vendor
{
public int Id { get; set; }
public string Name { get; set; }
}
public class ProductsContext : IDisposable
{
public ICollection<Product Products = new List<Product ()
{
new Product()
{
Category = "A",
Id = 1,
Name = "Product 1",
Price = 10,
Vendor = new Vendor()
{
Id = 1,
Name = "Vendor 1"
}
},
new Product()
{
Category = "A",
Id = 2,
Name = "Product 2",
Price = 15,
Vendor = new Vendor()
{
Id = 1,
Name = "Vendor 1"
}
},
new Product()
{
Category = "B",
Id = 3,
Name = "Product 3",
Price = 10,
Vendor = new Vendor()
{
Id = 2,
Name = "Vendor 2"
}
},
};
public void Dispose()
{
}
}
公共静态类WebApiConfig
{
公共静态无效寄存器(HttpConfiguration配置)
{
//Web API配置和服务
//Web API路由
config.maphttpAttribute路由();
config.Routes.MapHttpRoute(
名称:“DefaultApi”,
routeTemplate:“api/{controller}/{action}/{id}”,
默认值:新建{id=RouteParameter.Optional}
);
ODataModelBuilder=新ODataConventionModelBuilder();
#1、#2、#4的builder.EntitySet不起作用,因为操作名称或参数不遵循Web API OData路由约定。约定是开发人员应遵循的一组默认设置,以确保Web API OData可以将请求路由到控制器中的正确方法
对于#3,因为它使用Web API路由,所以
api/{controller}/{action}/{id}
不要使用Web API OData路由
希望这些资料能帮助您理解Web API OData中的路由。谢谢。对于、#1、#2、#4,它们不起作用,因为操作名称或参数不遵循Web API OData路由约定。约定是开发人员应该遵循的一组默认设置,以确保Web API OData可以将请求路由到中的正确方法控制器
对于#3,因为它使用Web API路由,所以
api/{controller}/{action}/{id}
不要使用Web API OData路由
希望本资料能帮助您理解Web API OData中的路由。谢谢。您的代码使用的是OData的ASP.NET实现,您遇到的问题是这些约定的结果
在URI路径/odata/Products(1)
中
部分称为键段。按照惯例,key
是用于保存键段值的参数的名称。不幸的是,这与将模型的键属性命名为Id
的惯例不匹配。您可以使用来覆盖此路由约定,但这不值得在我的opin中付出努力离子
GetProduct
或只是Get
的方法。同样,您可以使用ODataRouteAttribute
覆盖常规行为/odata/Products(id)
。在我的测试环境中,GET/odata/Products?key=1&$expand=Vendor
没有路由到GetByKey
。相反,它被路由到无参数的GET
方法,因为它应该符合路由约定(因为请求URI中没有键段)Name
属性是备用密钥,则您可以利用ASP.NET OData中的。您可以按名称检索产品,如下所示:GET/OData/Products(Name='Name')
。有关如何在控制器中实现备用密钥的说明,请参阅前面的问题/odata/Products(1)
中部分称为键段。按照惯例,key
是用于保存键段值的参数的名称。不幸的是,这与将模型的键属性命名为Id
的惯例不匹配。您可以使用来覆盖此路由约定,但这不值得在我的opin中付出努力离子GetProduct
或只是Get
的方法。同样,您可以使用ODataRouteAttribute
覆盖常规行为/odata/Products(id)
。在我的测试环境中,GET/odata/Products?key=1&$expand=Vendor
没有路由到GetByKey
。相反,它被路由到无参数的GET
方法,因为它应该符合路由约定(因为请求URI中没有键段)Name
属性是备用键,则可以使用advantag