如何为WebApi 2和OData控制器设置IIS TransferRequestHandler路径?

时间:2017-08-09 09:32:01

标签: c# asp.net asp.net-web-api asp.net-web-api2

我希望正确配置System.Web.Handlers.TransferRequestHandler path属性以处理两个路由到WebApi REST操作 ODataController 自定义< / strong> ASP.NET WebApi 2项目中的函数。

我的web.config文件处理程序配置如下,以支持自定义ODataController函数调用(see my related question here):

    <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>

请注意,在/*

上访问自定义 OData函数时,路径设置为ODataControllers 效果正常

尽管如此,我们还有一个ApiController,当我们访问它时,IIS无法正确处理请求并失败并显示以下详细信息:

  

HTTP错误500.0 - 内部服务器错误
  内部服务器错误

     

详细错误信息:
  模块 ManagedPipelineHandler
  通知 ExecuteRequestHandler
  处理程序 ExtensionlessUrlHandler-Integrated-4.0
  错误代码 0x800703e9

如果我将TransferRequestHandler path设置为*. as suggested here,则WebApi请求会得到正确解析,但ODataController请求最终无法通过HTTP 400找到:

  

HTTP错误404.4 - 未找到
  您要查找的资源没有与之关联的处理程序。

     

详细错误信息:
  模块 IIS Web核心
  通知 MapRequestHandler
  处理程序尚未确定
  错误代码 0x80070002

如何正确配置它以处理这两种情况?

++++编辑:++++
为了清楚起见,这里是我用来测试我的控制器的查询:

  • 自定义odata函数调用: http://localhost:xxxx/myProject/odata/SomeModels/MyNamespace.MyCustomFunction(parameterA=123,parameterB=123)
  • 原生odata GET致电: http://localhost:xxxx/myProject/odata/SomeModels
  • 原生网页api GET致电: 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 */);
        }
}

我的odata控制器:

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");

2 个答案:

答案 0 :(得分:1)

可能的解决方案as proposed here是将<modules runAllManagedModulesForAllRequests="true" />添加到<system.webServer>文件中的web.config

 <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" />的影响。

答案 1 :(得分:0)

从我之前的answer开始,我创建了一个新模型(AnotherModel)和一个新的ApiController(AnotherModelsController)

AnotherModel.cs

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

        public int MyInt { get; set; }

        public string MyString { get; set; }
    }
}

AnotherModelsController.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)

我也试过改变&#34;路径&#34;将web.config设置为*但是没关系。 我建议你从头开始创建一个新项目并与你的项目进行比较。