我目前正在将项目从ASP.NET WebAPI 5.2.6(OWIN)升级到ASP.NET Core 2.1.1(Kestrel)。
我们的项目是一个单页应用程序,我们通过WebAPI与客户端进行通信。因此,我想用新的ApiController
属性注释控制器。
不幸的是,似乎binding source parameter inference不能按预期工作(至少对我而言)。我根据文档假设,复杂类型(例如我的LoginRequest
)被推断为[FromBody]
。
// AccountController.cs
[Route("/account"), ApiController]
public class AccountController : ControllerBase
{
[HttpPost("backendLogin"), AllowAnonymous]
public async Task<ActionResult<LoginResponse>> BackendLogin(LoginRequest lr)
{
await Task.CompletedTask.ConfigureAwait(false); // do some business logic
return Ok(new LoginResponse {UserId = "123"});
}
// Models
public class LoginRequest {
public string Email { get; set; }
public string Password { get; set; }
}
public class LoginResponse {
public string UserId { get; set; }
}
}
// Startup.cs
public void ConfigureServices(IServiceCollection services) {
services.AddMvcCore()
.AddJsonFormatters(settings => {
settings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
settings.DateFormatHandling = DateFormatHandling.IsoDateFormat;
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
})
.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
services.Configure<ApiBehaviorOptions>(options => {
// options.SuppressConsumesConstraintForFormFileParameters = true;
// options.SuppressInferBindingSourcesForParameters = true;
// options.SuppressModelStateInvalidFilter = true;
});
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
if (env.IsDevelopment()) {
app.UseDeveloperExceptionPage();
}
app.UseMvc();
}
通过Ajax调用(Content-Type: application/x-www-form-urlencoded;
)从客户端调用控制器会导致响应400(错误请求),内容为{"":["The input was not valid."]}
。在服务器上,我得到以下跟踪输出:
Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor: Information: Executing ObjectResult, writing value of type 'Microsoft.AspNetCore.Mvc.SerializableError'.
如果我将options.SuppressInferBindingSourcesForParameters
中的ConfigureServices
更改为true,它似乎可以工作。这很奇怪,因为此设置应禁用绑定推断,或者我是否误解了某些内容?这是ASP.NET核心中的错误还是我遗漏了一些东西?
顺便说一句。如果我省略ApiController
属性,它也可以工作,但是我想这不是解决此问题的真正方法。
此外,如果我不需要在客户端进行任何更改(添加标头,更改内容类型等),我会很高兴,因为那里有很多Ajax调用,而我只想升级服务器端组件。