C# 如何防止odata控制器中自定义操作的HTTP 404?
我有一个C# 如何防止odata控制器中自定义操作的HTTP 404?,c#,asp.net,asp.net-mvc,asp.net-web-api2,odata,C#,Asp.net,Asp.net Mvc,Asp.net Web Api2,Odata,我有一个ASP.NetWebApi2项目托管了odataApiController和ODataController 我想在ODataController中添加一个自定义操作 我看到,这似乎可以通过在所需操作上添加[HttpPost]属性来实现,或者在使用时使用特定的配置来实现 为了区分odata路由和webapi路由,我们使用以下方案: 小田: webapi: 我尝试了这两种解决方案,但都没有成功,都得到了HTTP404的结果 我的自定义操作定义如下: public class SomeMo
ASP.Net
WebApi2
项目托管了odataApiController
和ODataController
我想在ODataController
中添加一个自定义操作
我看到,这似乎可以通过在所需操作上添加[HttpPost]
属性来实现,或者在使用时使用特定的配置来实现
为了区分odata路由和webapi路由,我们使用以下方案:
- 小田:
- webapi:
public class SomeModelsController : ODataController
{
//...
[EnableQuery]
public IHttpActionResult Get()
{
//...
return Ok(data);
}
public IHttpActionResult MyCustomAction(int parameterA, int parameterB)
{
//...
return Json(data);
}
//...
}
因此,正如您所猜测的,控制器上的Get调用与odata完美配合。但是,正确设置MyCustomAction有点困难
以下是我尝试过的:
[HttpPost]
public IHttpActionResult MyCustomAction(int parameterA, int parameterB)
{
//...
return Json(data);
}
我还尝试用[EnableQuery]
属性装饰MyCustomAction。此外,我还尝试在方法上添加
[AcceptVerbs(“GET”、“POST”)]
属性,没有任何更改 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();
}
private静态IEdmModel GetedModel()
{
var builder=新ODataConventionModelBuilder
{
Namespace=“MyApp”,
ContainerName=“DefaultContainer”
};
//公开的实体及其控制器名称的列表
// ...
FunctionConfiguration function=builder.function(“MyCustomAction”).ReturnsFromEntitySet(“SomeModels”);
函数参数(“参数”);
函数参数(“参数B”);
函数返回();
返回builder.GetEdmModel();
}
还尝试使用[EnableQuery]
、HttpPost
和[AcceptVerbs(“GET”、“POST”)]
属性装饰MyCustomActionhttp://localhost:9292/myProject/odata/SomeModels/MyCustomAction?parameterA=123¶meterB=123
我还试着将参数发布到
http://localhost:9292/myProject/odata/SomeModels/MyCustomAction
具有相同的结果。实际上,无论有无参数,我都会获得HTTP 404的状态。我已经用Visual Studio 2017从头开始创建了一个工作示例。
如果您想了解更多信息,可以阅读本教程:
- 创建新的ASP.Net Web应用程序(无.Net核心)
- 选择WebApi模板
- 从NuGet安装软件包Microsoft.AspNet.OData(我使用的是6.0.0版)
- 在模型文件夹中创建一个简单的模型类
namespace DemoOdataFunction.Models
{
public class TestModel
{
public int Id { get; set; }
public int MyProperty { get; set; }
public string MyString { get; set; }
}
}
- 配置WebApiConfig
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()
);
}
}
}
这是对MyFunction的请求:
GET
http://localhost:xxxx/odata/TestModels/MyNamespace.MyFunction(parA=1,parB=2)
我在控制器上使用HTTP POST和路由功能,如下所示:
[HttpPost]
[Route("{application}/{envName}/date/{offset}")]
[ResponseType(typeof(DateInfo))]
public async Task<IHttpActionResult> SetDateOffsetForEnvironmentName(string application, string envName, string offset)
{
}
[HttpPost]
[路由(“{application}/{envName}/date/{offset}”)]
[响应类型(类型(日期信息))]
公共异步任务setDateOffsetForenEnvironmentName(字符串应用程序、字符串环境名称、字符串偏移量)
{
}
您是否可以尝试在函数上设置路由,然后对其调用post方法,如下所示:
POST/status/ENVICES/ATONLINE/PTH/date/0
还可以尝试通过Fiddler捕获请求,并查看传递的内容 请求URL是什么?是这样吗?@FrancescoBozzi,我编辑了我的问题以添加查询url(在末尾)。我无法让它工作。我在URL中尝试了使用和不使用名称空间,您是否仍然得到HTTP 404结果?是的,仍然是HTTP 404您是否尝试了带有[HttpGet]修饰的函数的get请求?如果这对自定义OData函数很有效,似乎将
Web.config
文件中的System.Web.Handlers.TransferRequestHandler
的路径设置为/*
,而不是*。
会阻止访问WebApiController,如果你有任何想法,这将是很大的帮助!
POST
http://localhost:xxxx/odata/TestModels(1)/MyNamespace.MyAction
{
"stringPar":"hello"
}
GET
http://localhost:xxxx/odata/TestModels/MyNamespace.MyFunction(parA=1,parB=2)
[HttpPost]
[Route("{application}/{envName}/date/{offset}")]
[ResponseType(typeof(DateInfo))]
public async Task<IHttpActionResult> SetDateOffsetForEnvironmentName(string application, string envName, string offset)
{
}