我希望正确配置System.Web.Handlers.TransferRequestHandler
path
属性,以便在 ASP.NET WebApi 2项目中处理WebApi REST操作和ODataController自定义函数的路由。
我的web.config
文件处理程序配置如下,以支持自定义 ODataController 函数调用(在此处查看我的相关问题(:
<handlers>
<clear/>
<remove name="ExtensionlessUrlHandler-Integrated-4.0"/>
<remove name="OPTIONSVerbHandler"/>
<remove name="TRACEVerbHandler"/>
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="/*" verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0"/>
</handlers>
</system.webServer>
请注意,路径设置为/*
,并且在访问我们ODataControllers
上的自定义OData 函数时效果很好
尽管如此,我们还有一个 ApiController 并且当我们访问它时,IIS 无法正确处理请求并失败并显示以下详细信息:
HTTP 错误 500.0 - 内部服务器错误 内部服务器错误
详细错误信息:
模块托管管道处理程序通知执行请求处理程序
处理程序扩展无 urlHandler-集成-4.0
错误代码0x800703e9
如果我按照此处的建议将TransferRequestHandler
path
设置为*.
,则WebApi请求将得到正确解析,但是ODataController请求最终无法在HTTP 400中找到:
HTTP 错误 404.4 - 未找到
您要查找的资源没有与之关联的处理程序。详细错误信息:
模块IIS Web 核心
通知映射请求处理程序
处理程序尚未确定
错误代码0x80070002
如何正确配置它以处理这两种情况?
++++ 编辑:++++为了
清楚起见,这是我用来测试控制器的查询:
- 自定义 odata 函数调用 :
http://localhost:xxxx/myProject/odata/SomeModels/MyNamespace.MyCustomFunction(parameterA=123,parameterB=123)
- 本机 odata GET 调用 :
http://localhost:xxxx/myProject/odata/SomeModels
- 原生网页 API 获取调用:
http://localhost:xxxx/myProject/api/SomeOtherModel?parameterC=123
我的网络 api 控制器 :
public class SomeOtherModelsController : ApiController
{
public IHttpActionResult Get(int parameterC)
{
// ...
return Ok(/* some result */);
}
[HttpPost]
public IHttpActionResult Post(SomeOtherModel model)
{
// ...
return Ok(/* some result */);
}
}
我的数据控制器:
public class SomeModelController : ODataController
{
[EnableQuery]
public IHttpActionResult Get()
{
// ...
return Ok(/* some result*/);
}
[HttpGet]
[EnableQuery]
public IHttpActionResult MyCustomFunction(int parameterA, int parameterB)
{
// ...
return Ok(/* some result */);
}
[HttpGet]
[EnableQuery]
public IHttpActionResult AnotherCustomFunction()
{
// ...
return Ok(/* some result */);
}
}
下面是 Web API 配置:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
和 OData 配置:
var builder = new ODataConventionModelBuilder
{
Namespace = "MyNamespace"
};
builder.EntitySet<SomeModelModel>("SomeModels");
var anotherCustomFunction = builder.EntityType<SomeModelModel>().Collection.Function("AnotherCustomFunction");
anotherCustomFunction.Returns<SomeResultValue>();
var myCustomFunction = builder.EntityType<SomeModel>().Collection.Function("MyCustomFunction");
myCustomFunction.Parameter<int>("parameterA");
myCustomFunction.Parameter<int>("parameterB");
myCustomFunction.ReturnsFromEntitySet<SomeModelModel>("SomeModels");
这里提出的一个可能的解决方案是将<modules runAllManagedModulesForAllRequests="true" />
添加到web.config
文件中的<system.webServer>
:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
事实证明,添加此模块使得不需要System.Web.Handlers.TransferRequestHandler
处理程序的存在。
因此,以下 system.webServer 配置足以处理 api 查询和自定义 OData 函数查询:
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<handlers>
<remove name="OPTIONSVerbHandler"/>
<remove name="TRACEVerbHandler"/>
</handlers>
</system.webServer>
尽管如此,我对这个解决方案并不满意,因为我不太确切地知道<modules runAllManagedModulesForAllRequests="true" />
的影响。
从我之前的回答开始,我创建了一个新模型(AnotherModel(和一个新的ApiController(OtherModelsController(。
另一个模型.cs
namespace DemoOdataFunction.Models
{
public class AnotherModel
{
public int Id { get; set; }
public int MyInt { get; set; }
public string MyString { get; set; }
}
}
另一个模型控制器.cs
namespace DemoOdataFunction.Controllers
{
public class AnotherModelsController : ApiController
{
public IHttpActionResult Get(int parameterC)
{
// ...
return Ok();
}
public IHttpActionResult Get()
{
// ...
return Ok("Ok");
}
[HttpPost]
public IHttpActionResult Post(AnotherModel model)
{
// ...
return Ok();
}
}
}
无需任何其他更改,API 和 OData 控制器都可以工作。
GET
http://localhost:4186/api/AnotherModels?parameterC=1
GET
http://localhost:4186/api/AnotherModels
Post
http://localhost:4186/api/AnotherModels
{
"Id" : 1,
"MyInt" : 2,
"MyString" : "Hello"
}
GET
http://localhost:4186/odata/TestModels/MyNamespace.MyFunction(parA=1,parB=2)
我也尝试将 web.config 的"路径"设置更改为 *,但这没关系。 我建议您从头开始创建一个新项目并将其与您的项目进行比较。