【问题标题】:ASPNET 5: How to receive request parameter as raw content no matter what the Content-Type header is set to?ASPNET 5:无论 Content-Type 标头设置为什么,如何将请求参数作为原始内容接收?
【发布时间】:2016-04-24 06:07:09
【问题描述】:

我正在构建一个 API,客户端可以在其中向我发送数据块,然后我将其保存在某个地方以供以后检索。我不在乎内容类型是什么。我只想每次都获取原始数据,无论他们将 Content-Type 设置为什么。我知道这可以通过访问 Request 对象在旧版本的 ASPNET 中实现,但是这在 ASPNET 5 中似乎是不可能的,我也不想这样做,因为它会使单元测试变得不可能(请求不是依赖注入)。

我已经看到一些关于 IInputFormatter 和 IOutputFormatter 接口的提及,但它们似乎附加到特定的 Content-Type。我想我正在寻找更像 [FromBody] 属性的东西,但这会给我原始输出。类似 [RawBody] 的东西。我做了很多搜索,似乎找不到任何简单的解决方案。

【问题讨论】:

  • 如果您可以使用 Moq per this answer 对其进行单元测试,也许您可​​以使用 Request 对象。
  • 我认为这不适用于 ASPNET 5,因为控制器不继承任何东西(只是对象)。因此,没有 ControllerContext 或任何东西。我什至不确定是否可以从 ASPNET 5 中的控制器访问请求。我认为类似于 [FromBody] 的属性可能是这样做的唯一方法。

标签: asp.net-mvc asp.net-web-api


【解决方案1】:

您可以创建CustomAttribute 并使用StreamReader 读取Request.InputStream 将流数据保存在您想要的任何位置,然后将 InputStream 位置重置为 0 httpContext.Request.InputStream.Position = 0;

我在自定义AuthorizeAttribute 中使用它,但您可以使用自定义ActionFilter 并使用filterContext 中的Request,您可以在谷歌上搜索“MVC c# 中的自定义属性”,您也可以在ActionResult 中执行此操作。

【讨论】:

  • 谢谢。这听起来对我来说是正确的。你认为你可以提供一个模板来说明它是如何工作的吗?或者可能是相关示例的链接?
  • 这听起来像是 MVC 4(或更早版本)的概念。我认为这不能在 MVC 6 (ASPNET 5) 上完成。这是一个完全不同的架构。不过,我确实认为我的问题需要自定义属性。我一直在研究 InputFormatters 和 ModelBinders。我认为解决方案将与这些有关。
  • @KevinCraft MVC 或 .NET 的架构可能会改变,但 HTTP 协议仍然相同。您想从客户端的 HTTP 请求中获取原始请求(数据 blob),您可以从 Request.InputStream 中获取它,我没有安装 mvc6,但是如果你可以在任何地方访问 Request.InputStream,你就可以实现这个功能。
  • 我明白一旦我可以访问 Request 对象我需要做什么。不过,这就是我面临的问题。 MVC 6 是专门为可单元测试而构建的。一切都被注入。控制器本身甚至没有上下文或任何东西。一切都由依赖注入器处理。我需要弄清楚如何进入 DI 系统和控制器之间。我认为我在 ModelBinders 方面走在了正确的轨道上。
  • @KevinCraft 抱歉,在回答之前没有研究过 mvc 6。 :)
【解决方案2】:

如果您仍在寻找获取请求对象的解决方案,这里就是解决方案

创建MessageHandler

public class MessageHandler1 : DelegatingHandler
    {
        protected async override Task<HttpResponseMessage> SendAsync(
            HttpRequestMessage request, CancellationToken cancellationToken)
        {
            HttpContextWrapper context = (HttpContextWrapper)request.Properties.ElementAt(0).Value;
        // Call the inner handler.
        var response = await base.SendAsync(request, cancellationToken);

        return response;
        }
    }

向 WebApiConfig 添加条目

public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API configuration and services
            config.MessageHandlers.Add(new MessageHandler1());

            // Web API routes
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }

现在您可以在MessageHandler1 中访问行请求

【讨论】:

    猜你喜欢
    • 2012-05-27
    • 1970-01-01
    • 1970-01-01
    • 2011-07-21
    • 2011-12-25
    相关资源
    最近更新 更多