ASP.NET Core无法读取请求正文

Fre*_*Dev 9 c# asp.net-core-mvc asp.net-core asp.net-core-1.0

几个星期以来,我一直在研究ASP.NET Core.我试图在此基础上博客实现的东西: 微服务

我的project.json情况如下:

{
  "version": "1.0.0-*",
  "compilationOptions": {
    "emitEntryPoint": true
  },

  "dependencies": {

    "Microsoft.AspNet.IISPlatformHandler": "1.0.0-rc1-final",
    "Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
    "Microsoft.AspNet.Diagnostics": "1.0.0-rc1-*",
    "Microsoft.AspNet.Mvc": "6.0.0-rc1-final",
    "EntityFramework.Core": "7.0.0-rc1-final",
    "EntityFramework.Commands": "7.0.0-rc1-final",
    "EntityFramework.MicrosoftSqlServer": "7.0.0-rc1-final",
    "EntityFramework.MicrosoftSqlServer.Design": "7.0.0-rc1-final",
    "Microsoft.AspNet.Mvc.Formatters.Json": "6.0.0-rc1-final",
    "Microsoft.AspNet.Mvc.Formatters.Xml": "6.0.0-rc1-final",
    "System.Security.Cryptography.Algorithms": "4.0.0-beta-23516"

  },

  "commands": {
    "web": "Microsoft.AspNet.Server.Kestrel",
    "ef": "EntityFramework.Commands"
  },

  "frameworks": {

    "dnxcore50": {
      "dependencies": {


      }

    }
  },

  "exclude": [
    "wwwroot",
    "node_modules"
  ],
  "publishExclude": [
    "**.user",
    "**.vspscc"
  ]
}
Run Code Online (Sandbox Code Playgroud)

ConfigureServices在方法Startup.cs如下:

public void ConfigureServices(IServiceCollection services)
{
    //Registering Authorization Database
    AutorizationAccessRegisteration.RegisterComponents(services, Configuration);

    services.AddMvcCore()
        .AddJsonFormatters(a => a.ContractResolver = new CamelCasePropertyNamesContractResolver());

    //Add cors built in support.
    services.AddCors();

    services.AddMvcCore().AddApiExplorer();

    //Add MVC for supporting WebApi requests
    #region MVC Add

    services.AddMvc();

    services.AddMvc().AddMvcOptions(options =>
    {
        options.RespectBrowserAcceptHeader = true;

        // Input Formatters.
        options.InputFormatters.Clear();

        var jsonInputFormatter = new JsonInputFormatter()
        {
            SerializerSettings = new JsonSerializerSettings()
            {
                ContractResolver = new CamelCasePropertyNamesContractResolver()
                ,
                DefaultValueHandling = DefaultValueHandling.IgnoreAndPopulate,
                NullValueHandling = NullValueHandling.Ignore
            }
        };


        options.InputFormatters.Add(jsonInputFormatter);

        //Output formater
        //as part of get/post request, set the header Accept = application/json or application/xml
        var jsonOutputFormatter = new JsonOutputFormatter();
        jsonOutputFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
        jsonOutputFormatter.SerializerSettings.DefaultValueHandling = Newtonsoft.Json.DefaultValueHandling.Ignore;
        options.OutputFormatters.Insert(0, jsonOutputFormatter);

        options.OutputFormatters.Insert(1, new XmlDataContractSerializerOutputFormatter());

    });

    #endregion
}
Run Code Online (Sandbox Code Playgroud)

这是我Confiure在Startup.cs中的方法:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {

    }
    else if (env.IsStaging())
    {

    }
    else if (env.IsProduction())
    {

    }

    app.UseIISPlatformHandler();

    app.UseCors(builder =>
            builder.WithOrigins("*").AllowAnyHeader().AllowAnyMethod());

    //Middlewares addition to the pipelines:
    /// We add the middlewares in the following fashion:
    /// - Exception Handler
    /// - Logger
    /// - Authorization Handler
    /// There is a big reason of doing that.
    ///
    app.UseExceptionHandler();
    app.UseLoggerHandler();
    app.UseAuthorizationHandler();

    app.UseMvc();
}
Run Code Online (Sandbox Code Playgroud)

AuthorizationController如下:

[Route("api/Authorization")]
public class AuthorizationController : Controller
{
 .
     [HttpPost]
     public void Post([FromBody]string value)
     {
     }
 .
}
Run Code Online (Sandbox Code Playgroud)

Post方法最初有[FromBody]string[] value.我把它简化为一种简单的string类型.我在Chrome上使用Advance Rest Client发送HTTP request.string[]类型I 何时是正文中的以下值:

{

  ["value","sdjklgsdjlg"]

}
Run Code Online (Sandbox Code Playgroud)

简化参数后,我尝试使用以下正文发送请求:

{"sdjklgsdjlg"}
Run Code Online (Sandbox Code Playgroud)

尝试过这个:

{"value":"sdjklgsdjlg"}
Run Code Online (Sandbox Code Playgroud)

我错过了什么吗?我之前读过,旧WebApi用于处理与复杂对象和普通参数的JSON映射的方式,它在.NET Core中以类似的方式工作.

此外,我应该详细说明断点在所有中间件和控制器上正常命中.但是没有一个中间件似乎能够读取Request的流相关内容:

context.Request变量问题

context.Request.Body错误

请告诉我我在哪里遇到问题.非常感谢!

bc3*_*ech 5

这对我有用:

[HttpPost]
public async Task<IActionResult> CreateApp([FromQuery]string userId)
{
    string appDefinition = await new StreamReader(Request.Body).ReadToEndAsync();
    var newAppJson = JObject.Parse(appDefinition);
...
Run Code Online (Sandbox Code Playgroud)


Mar*_*hes 4

[FromBody]使用注册的格式化程序将提交的数据的整个正文解码为它所应用的单个参数 - 默认情况下,唯一注册的格式化程序接受 JSON。

在 JSON 中,没有有效的方法来直接表示字符串 -{"sdjklgsdjlg"}不是有效的 JSON,{"value":"sdjklgsdjlg"}是,但不会反序列化为简单的字符串参数。编辑:请参阅@tmg的答案,这可以使用语法来完成{ "": "sdjklgsdjlg" }

因此,您需要某种特定的模型类来表示您尝试从正文获取的输入,例如:

public class AuthRequest {
    public string Value { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

那么你应该能够成功地做到:

[Route("api/Authorization")]
public class AuthorizationController : Controller
{
    [HttpPost]
    public void Post([FromBody]AuthRequest authReq)
    {
        // authReq.Value should have your value in
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,如果您发布{ "Value": "some value" }到此,它应该会执行您所期望的操作。