【问题标题】:OData V3 action in ASP.NET web api doesn't get triggerASP.NET Web api 中的 OData V3 操作未触发
【发布时间】:2014-10-15 14:00:48
【问题描述】:

我正在使用带有 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。

谢谢,

【问题讨论】:

    标签: odata asp.net-web-api-odata


    【解决方案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实体的调用。

    因此,您会收到 No HTTP resource was found 错误消息。


    根据您的示例代码,我创建了一个示例方法供您参考:

    [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
      }
    }
    

    对于您的问题:

    1. IList 约定 = ODataRoutingConventions.CreateDefault(); //我需要这个吗?

      回答:不,你不需要。只需使用默认值:

      config.Routes.MapODataServiceRoute("ODataRoute", "odata", GetModel());

    2. //[ODataRoute("AlterCredits(key={key},credit={credit})")]

      回答:不,绑定操作不需要 ODataRouteAttribute。

    谢谢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-03-25
      • 1970-01-01
      • 2013-03-03
      • 1970-01-01
      • 2017-11-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多