如何在odata控制器中阻止HTTP 404进行自定义操作? [英] How to prevent HTTP 404 for a custom action in an odata controller?

查看:72
本文介绍了如何在odata控制器中阻止HTTP 404进行自定义操作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ASP.Net WebApi2项目,该项目同时托管ApiControllerODataController的odata.

I have an ASP.Net WebApi2 project hosting odata both ApiController and ODataController.

我想在ODataController中添加自定义操作.

And I want to add a custom action in an ODataController.

我看到这似乎可以通过在所需操作上添加[HttpPost]属性或通过配置 FunctionConfiguration .com/en-us/library/system.web.odata.extensions.httpconfigurationextensions.mapodataserviceroute(v = vs.118).aspx"rel =" nofollow noreferrer> MapODataServiceRoute .

I saw this seems to be achievable by either adding [HttpPost] attribute on the desired action, or by configuring the ODataConventionModelBuilder with a specific FunctionConfiguration when using the MapODataServiceRoute.

要区分odata路由和webapi路由,我们使用以下方案:

To distinguish between odata routes and webapi routes we use the following scheme :

  • odata : http://localhost:9292/myProject/odata
  • webapi : http://localhost:9292/myProject/api

我尝试了这两种解决方案,均未成功,均导致获得 HTTP 404 结果.

I tried both these solution without success which all led to get an HTTP 404 result.

我的自定义操作定义如下:

My custom action is defined as following:

public class SomeModelsController : ODataController
{
    //...

    [EnableQuery]
    public IHttpActionResult Get()
    {
        //...
        return Ok(data);
    }

    public IHttpActionResult MyCustomAction(int parameterA, int parameterB)
    {
        //...
        return Json(data);
    }

    //...
}

因此,正如您猜到的那样,控制器上的Get调用与odata完美配合.但是,正确设置MyCustomAction有点困难.

So as you guessed it, the Get call on the controller perfectly work with odata. However the MyCustomAction is a bit more difficult to setup properly.

这是我尝试过的:

  1. 在MyCustomAction上设置[HttpPost]属性

  1. Setting an [HttpPost] attribute on MyCustomAction

[HttpPost]
public IHttpActionResult MyCustomAction(int parameterA, int parameterB)
{
    //...
    return Json(data);
}

我还尝试使用[EnableQuery]属性装饰MyCustomAction.
另外,我尝试在方法上添加[AcceptVerbs("GET", "POST")]属性,而不进行任何更改.

I also tried decorating MyCustomAction with the [EnableQuery] attribute.
Also, I tried adding the [AcceptVerbs("GET", "POST")] attribute on the method without changes.

配置ODataConventionModelBuilder

Configuring the ODataConventionModelBuilder

  private static IEdmModel GetEdmModel()
  {
      var builder = new ODataConventionModelBuilder
      {
          Namespace = "MyApp",
          ContainerName = "DefaultContainer"
      };
      // List of entities exposed and their controller name
      // ...
      FunctionConfiguration function = builder.Function("MyCustomAction ").ReturnsFromEntitySet<MyModel>("SomeModels");
      function.Parameter<int>("parameterA");
      function.Parameter<int>("parameterB");
      function.Returns<MyModel>();

      return builder.GetEdmModel();
  }

还尝试使用[EnableQuery]HttpPost[AcceptVerbs("GET", "POST")]属性装饰MyCustomAction.

Also tried decoration of MyCustomAction with [EnableQuery], HttpPost and [AcceptVerbs("GET", "POST")] attributes.

我仍然得到 HTTP 404 结果.

我的查询网址如下:
http://localhost:9292/myProject/odata/SomeModels/MyCustomAction?parameterA=123&parameterB=123

My query url is as follow:
http://localhost:9292/myProject/odata/SomeModels/MyCustomAction?parameterA=123&parameterB=123

我也尝试过在POST参数 http://localhost:9292/myProject/odata/SomeModels/MyCustomAction具有相同的结果.实际上,无论是否带有参数,我都会获得 HTTP 404 状态.

I also tried to POST parameters on http://localhost:9292/myProject/odata/SomeModels/MyCustomAction with the same result. Actually with or without parameters I get HTTP 404 status.

推荐答案

我已经使用Visual Studio 2017从头开始创建了一个工作示例. 如果您想了解更多信息,可以阅读本教程:

I've created a working example from scratch with Visual Studio 2017. If you want more info you can read this tutorial:

https://docs.microsoft.com/zh-CN/aspnet/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/odata动作和功能

  • 创建一个新的ASP.Net Web应用程序(无.Net Core)

选择WebApi模板

从Nu获取安装包Microsoft.AspNet.OData(我已经使用6.0.0版)

在模型"文件夹中创建一个简单的模型类

TestModel.cs

TestModel.cs

namespace DemoOdataFunction.Models
{
    public class TestModel
    {
        public int Id { get; set; }

        public int MyProperty { get; set; }

        public string MyString { get; set; }
    }
}

  • 配置WebApiConfig
    • Configure WebApiConfig
    • WebApiConfig.cs

      WebApiConfig.cs

      using DemoOdataFunction.Models;
      using System.Web.Http;
      using System.Web.OData.Builder;
      using System.Web.OData.Extensions;
      
      
      namespace DemoOdataFunction
      {
          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}/{id}",
                      defaults: new { id = RouteParameter.Optional }
                  );
      
                  ODataModelBuilder builder = new ODataConventionModelBuilder();
                  builder.Namespace = "MyNamespace";
      
                  builder.EntitySet<TestModel>("TestModels");
      
                  ActionConfiguration myAction = builder.EntityType<TestModel>().Action("MyAction");
                  myAction.Parameter<string>("stringPar");
      
      
                  FunctionConfiguration myFunction = builder.EntityType<TestModel>().Collection.Function("MyFunction");
                  myFunction.Parameter<int>("parA");
                  myFunction.Parameter<int>("parB");
                  myFunction.ReturnsFromEntitySet<TestModel>("TestModels");
      
      
                  config.MapODataServiceRoute(
                      routeName: "ODataRoute",
                      routePrefix: "odata",
                      model: builder.GetEdmModel()
                      );
              }
          }
      }
      

      • 将控制器TestModelsController创建到Controllers文件夹中
        • Create the controller TestModelsController into Controllers folder
        • TestModelsController.cs

          TestModelsController.cs

          using DemoOdataFunction.Models;
          using System.Collections.Generic;
          using System.Linq;
          using System.Web.Http;
          using System.Web.OData;
          using System.Web.OData.Query;
          
          namespace DemoOdataFunction.Controllers
          {
              public class TestModelsController : ODataController
              {
                  IQueryable<TestModel> testModelList = new List<TestModel>()
                      {
                          new TestModel{
                          MyProperty = 1,
                          MyString = "Hello"
                          }
                      }.AsQueryable();
          
                  [EnableQuery]
                  public IQueryable<TestModel> Get()
                  {
                      return testModelList;
                  }
          
                  [EnableQuery]
                  public SingleResult<TestModel> Get([FromODataUri] int key)
                  {
          
                      IQueryable<TestModel> result = testModelList.Where(t => t.MyProperty == 1);
                      return SingleResult.Create(result);
                  }
          
                  [HttpPost]
                  public IHttpActionResult MyAction([FromODataUri] int key, ODataActionParameters parameters)
                  {
                      string stringPar = parameters["stringPar"] as string;
          
                      return Ok();
                  }
          
                  [HttpGet]
                  [EnableQuery(AllowedQueryOptions = AllowedQueryOptions.All, MaxExpansionDepth = 2)]
                  public  IHttpActionResult MyFunction(int parA, int parB)
                  {
                      return Ok(testModelList);
                  }
              }
          }
          

          • 编辑Web.config,更改system.webServer中的处理程序部分
            • Edit Web.config changing the handlers section in system.webServer
            • web.config

              web.config

              <system.webServer>
                  <handlers>
                    <clear/>
                    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="/*" 
                        verb="*" type="System.Web.Handlers.TransferRequestHandler" 
                        preCondition="integratedMode,runtimeVersionv4.0" />
                  </handlers>
                  [...]
              </system.webServer>
              

              仅此而已.

              这是对MyAction的请求:

              This is the request for MyAction:

              POST
              http://localhost:xxxx/odata/TestModels(1)/MyNamespace.MyAction
              {
                "stringPar":"hello"
              }
              

              这是对MyFunction的请求:

              This is the request for MyFunction:

              GET
              http://localhost:xxxx/odata/TestModels/MyNamespace.MyFunction(parA=1,parB=2)
              

              这篇关于如何在odata控制器中阻止HTTP 404进行自定义操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆