覆盖MVC POST请求的内容标头

时间:2016-12-12 09:11:06

标签: .net http model-view-controller asp.net-web-api content-type

我对MVC很新,所以我希望能解决我的问题。我正在使用第三方硬件与我的MVC Web API进行通信。硬件以JSON格式发送请求,我可以完全提取。但是,由于冲突,我正在将这些请求的参数更改为绑定模型对象。

E.G。

        Public Function POSTRequest(Action As String, Stamp As String) As HttpResponseMessage
           ...
        End Function

        Public Function POSTRequest(Action As String, OpStamp As String) As HttpResponseMessage
           ...
        End Function

因此,这两种方法共享同一张电话卡,因此它们不能存在于同一个控制器中。

由于这个原因,我创建了模型绑定对象来代替这些参数。问题是,一旦我这样做,Web API会抱怨请求说“Content-Type”没有定义。看一下,第三方硬件不会向请求发送内容类型。在网上看,我发现这导致浏览器将其视为内容类型“application / octet-stream”。然后,这不能将其转换为定义为参数的绑定对象。

我们无法控制第三方硬件,因此我们无法为这些请求定义内容类型。所以,我的问题是,有没有办法拦截这些请求并为它们添加内容类型?或者甚至是另一种方式?

2 个答案:

答案 0 :(得分:5)

我认为你可以使用ActionFilterAttribute。请参阅文档:Creating Custom Action Filters

在您的情况下,您可以使用以下示例(在C#中,因为我的VB技能已过时)。它使用 application / json 值覆盖任何请求Content-Type标头。请注意,为了支持各种HttpContent,您可能需要对其进行增强(例如,我不认为这应该用于MultiPart请求)。

public class UpdateRequestAttribute: ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        actionContext.Request.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
        base.OnActionExecuting(actionContext);
    }
}

然后将此属性添加到控制器类,例如:

[UpdateRequest]
public class HomeController : ApiController
{
    //[...]
}

在这种情况下,对Home控制器的所有请求都将覆盖Content-Type

或者,您也可以编写一个自定义HTTP Message Handlers,它在管道中很早就被调用,并且不会局限于特定的控制器。请查看以下图片,了解服务器如何处理请求。

ASP.net Server Side handlers

例如,如果请求Content-Type当前为空,则此消息处理程序会将请求public class CustomMessageHandler : DelegatingHandler { protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) { if (request.Content.Headers.ContentType == null) { request.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json"); } return base.SendAsync(request, cancellationToken); } } 设置为 application / json

WebApiConfig

最后,以下是如何更新public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.MessageHandlers.Add(new CustomMessageHandler()); // Other configuration not shown... } } 以便将消息处理程序添加到管道中:

Verification in order failure
Wanted but not invoked:
commandExecutor.execute(
    src/test/resources,
    isNull(),
    "pdflatex",
    ["-interaction=nonstopmode", "-synctex=1", "-src-specials", "-recorder", "-shell-escape", "-output-format=pdf", "test.tex"],
    src/test/resources/test.pdf
);
-> at         org.m2latex.core.LatexProcessorTest.verifyRunLatex(LatexProcessorTest.java:700)
Wanted anywhere AFTER following interaction:
commandExecutor.execute(
    src/test/resources,
    null,
    "pdflatex",
    ["-interaction=nonstopmode", "-synctex=1", "-src-specials", "-recorder", "-shell-escape", "-output-format=pdf", "test.tex"],
    src/test/resources/test.pdf
);
-> at    org.m2latex.core.LatexProcessor.runLatex2dev(LatexProcessor.java:1304)

答案 1 :(得分:1)

通过定义Route属性,可以在同一个控制器中同时使用这两种方法。这样就可以避免使用模型绑定属性。

[inet_http_server]
port = *:9001

不要忘记通过在webapiconfig.vb文件中添加MapHttpAttributeRoutes来启用属性路由

[Route("Request1")]
Public Function POSTRequest(Action As String, Stamp As String) As HttpResponseMessage
           ...
        End Function
        [Route("Request2")]
        Public Function POSTRequest(Action As String, OpStamp As String) As HttpResponseMessage
           ...
        End Function