如何防止 odata 控制器中的自定义操作出现 HTTP 404?

约翰-菲利普

我有一个ASP.Net WebApi2项目同时托管 odataApiControllerODataController.

我想在ODataController.

我看到这似乎可以通过[HttpPost]在所需操作上添加属性来实现,或者通过在使用MapODataServiceRoute时使用特定的FunctionConfiguration配置ODataConventionModelBuilder实现

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

我尝试了这两种解决方案都没有成功,这都导致获得HTTP 404结果。

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

public class SomeModelsController : ODataController
{
    //...

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

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

    //...
}

因此,正如您所猜到的,控制器上的 Get 调用与 odata 完美配合。然而,正确设置 MyCustomAction 有点困难。

这是我尝试过的:

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

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

    我还尝试使用该[EnableQuery]属性装饰 MyCustomAction
    另外,我尝试[AcceptVerbs("GET", "POST")]在没有更改的情况下在方法上添加属性。

  2. 配置 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

我仍然得到HTTP 404结果。

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

我还尝试http://localhost:9292/myProject/odata/SomeModels/MyCustomAction使用相同的结果POST 参数实际上无论有没有参数,我都会得到HTTP 404状态。

弗朗西斯科·博齐

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

https://docs.microsoft.com/en-us/aspnet/web-api/overview/odata-support-in-aspnet-web-api/odata-v4/odata-actions-and-functions

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

  • 选择 WebApi 模板

  • 从 NuGet 安装 Microsoft.AspNet.OData 包(我使用过 6.0.0 版)

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

测试模型.cs

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

        public int MyProperty { get; set; }

        public string MyString { get; set; }
    }
}
  • 配置 WebApiConfig

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()
                );
        }
    }
}
  • 在 Controllers 文件夹中创建控制器 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 中的处理程序部分

网页配置

<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 的请求:

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

这是对 MyFunction 的请求:

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在http 404 ASP.NET Web API中返回自定义Json

不同控制器中的OData自定义路由约定

如何禁用oData API的HTTP POST REQUEST?

如何在自定义控制器操作中显示本机 DNN 弹出窗口?

如何在自定义控制器操作中呈现jsonapi-resources响应?

Laravel 5自定义404控制器

如何在SAP UI中的控制器中定义自定义控制器?

Web API 2:OData 4:操作返回404

将CreateRef方法迁移到.Net Core会导致404,如何使用.Net Core在OData中实现创建关系

如何为我的网站创建自定义的“找不到文件(404、500)[http 错误代码]”

从Web API控制器获取angular $ http中的自定义标头

OData路由返回404 Not Found

发送http-404响应但不发送在IIS服务器中设置的自定义错误页面 的PHP

混合使用Odata会使自定义System.Web.Http.AuthorizeAttribute混乱

如何从不同的控制器访问变量以使自定义下载操作起作用

如何在OData中的控制器中调用不同的方法

如何在odata控制器中实现与常规PUT相同的POST以更新实体

如何在控制器动作中添加缺少的OData查询选项

如何制作自定义 404 页面?

在Azure Logic应用中使用HTTP操作时,如何在JSON主体中使用“ @ odata.id”?

Jenkins中HTTP 404页面URL的自定义页面

无法为ASP.NET中的自定义错误页面返回HTTP状态404

在Vue单页应用程序中,如何防止刷新时出现404

如何防止对 AngularJS 中失败的 $http.post 采取行动

如何防止Android中捕获HTTP数据包?

如何防止我的HTTP Get请求被缓存在Swift中?

如何在PHP中防止CRLF注入(Http响应拆分)

如何防止Apache httpd(MAMP)中的HTTP文件缓存

如何防止HTTP 1.1请求中的保持活动状态?