我正在使用带有webapi 2.2的asp.net的OData V3端点。我用它成功实现了CRUD操作。现在,我想添加一些自定义操作以及CRUD操作。我已经按照文章(http://www.asp.net/web-api/overview/odata-support-in-aspnet-web-api/odata-v3/odata-actions)创建了带有web api的OData V3的动作。
当我输入
URI:
http://localhost:55351/odata/Courses(1101)/AlterCredits
它会抛出以下错误:
<m:error><m:code/><m:message xml:lang="en-US">No HTTP resource was found that matches the request URI 'http://localhost:55351/odata/Courses(1101)/AlterCredits'.</m:message><m:innererror><m:message>No routing convention was found to select an action for the OData path with template '~/entityset/key/unresolved'.</m:message><m:type/><m:stacktrace/></m:innererror></m:error>
我还尝试为不可绑定的操作添加自定义路由会话。 (https://aspnet.codeplex.com/SourceControl/latest#Samples/WebApi/OData/v3/ODataActionsSample/ODataActionsSample/App_Start/WebApiConfig.cs)不确定我是否必须使用它。
这是我的代码:
WebApiConfig.cs:---
namespace ODataV3Service
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
IList<IODataRoutingConvention> conventions = ODataRoutingConventions.CreateDefault(); //Do I need this?
//conventions.Insert(0, new NonBindableActionRoutingConvention("NonBindableActions"));
// Web API routes
config.Routes.MapODataRoute("ODataRoute","odata", GetModel(), new DefaultODataPathHandler(), conventions);
}
private static IEdmModel GetModel()
{
ODataModelBuilder modelBuilder = new ODataConventionModelBuilder();
modelBuilder.ContainerName = "CollegeContainer";
modelBuilder.EntitySet<Course>("Courses");
modelBuilder.EntitySet<Department>("Departments");
//URI: ~/odata/Course/AlterCredits
ActionConfiguration atlerCredits = modelBuilder.Entity<Course>().Collection.Action("AlterCredits");
atlerCredits.Parameter<int>("Credit");
atlerCredits.Returns<int>();
return modelBuilder.GetEdmModel();
}
}
}
CoursesController.cs:----
[HttpPost]
//[ODataRoute("AlterCredits(key={key},credit={credit})")]
public async Task<IHttpActionResult> AlterCredits([FromODataUri] int key, ODataActionParameters parameters)
{
if (!ModelState.IsValid)
return BadRequest();
Course course = await db.Courses.FindAsync(key);
if (course == null)
{
return NotFound();
}
int credits = course.Credits + 3;
return Ok(credits);
}
的Global.asax:----
namespace ODataV3Service
{
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
}
}
}
我在网上做过研究并找到了这个链接。 Web API and OData- Pass Multiple Parameters但这个是OData V4。我正在使用OData V3和Action。
谢谢,
答案 0 :(得分:1)
首先,您的操作AlterCredits
定义为:
ActionConfiguration atlerCredits = modelBuilder.Entity<Course>().Collection.Action("AlterCredits");
这意味着AlterCredits
绑定到Course
的集合。
第二次,您控制器中的方法AlterCredits
定义为:
public async Task<IHttpActionResult> AlterCredits([FromODataUri] int key, ODataActionParameters parameters)
{
...
}
这意味着AlterCredits
听取Course
实体的电话。
因此,您获得了未找到HTTP资源错误消息。
根据您的示例代码,我创建了一个示例方法供您参考:
[HttpPost]
public async Task<IHttpActionResult> AlterCredits(ODataActionParameters parameters)
{
if (!ModelState.IsValid)
return BadRequest();
object value;
if (parameters.TryGetValue("Credit", out value))
{
int credits = (int)value;
credits = credits + 3;
return Ok(credits);
}
return NotFound();
}
然后,如果您发送请求:
POST ~/odata/Courses/AlterCredits
Content-Type: application/json;odata=verbose
Content: {"Credit":9}
你可以得到这样的回复:
{
"d":{
"AlterCredits":12
}
}
对于你的问题:
IList convention = ODataRoutingConventions.CreateDefault(); //我需要这个吗?
回答:不,你不需要。只需使用默认值:
config.Routes.MapODataServiceRoute(“ODataRoute”,“odata”,GetModel());
// [ODataRoute( “AlterCredits(键= {}键,信用= {信用})”)]
回答:不,您不需要ODataRouteAttribute进行绑定操作。
感谢。