如何在odata控制器中阻止HTTP 404进行自定义操作? [英] How to prevent HTTP 404 for a custom action in an odata controller?
问题描述
我有一个ASP.Net
WebApi2
项目,该项目同时托管ApiController
和ODataController
的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.
这是我尝试过的:
-
在MyCustomAction上设置[HttpPost]属性
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¶meterB=123
My query url is as follow:
http://localhost:9292/myProject/odata/SomeModels/MyCustomAction?parameterA=123¶meterB=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:
-
创建一个新的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屋!