![](/img/trans.png)
[英]ASP.NET Core 5 Web API, POST return CreatedAtAction error
[英]ASP.NET 5 Web API CreatedAtAction: POST returns 500
我有一个简单的 ASP.NET 5 Web API,带有一个用于上传/下载文件的控制器,例如:
[Authorize(Roles = "admin,browser,writer")]
[HttpPost("api/contents/{id}")]
public IActionResult UploadContent(IFormFile file,
[FromForm] string mimeType,
[FromForm] string id)
{
// store...
return CreatedAtAction(nameof(DownloadContent), new
{
id = id
});
}
[Authorize]
[HttpGet("api/contents/{id}")]
public FileResult DownloadContent([FromRoute] string id)
{
// fetch into item...
return File(item.Content, item.MimeType);
}
上传操作正常工作,直到该方法返回:此时,当框架处理 201 返回对象的序列化(应将其位置设置为相应的下载操作)时,我得到一个InvalidOperationException
告诉我No route matches the supplied values
.
我发现 这个问题是关于一个类似的问题,但提到的解决方案似乎都不起作用。 我试过了:
[ActionName("DownloadContent")]
显式命名下载操作,即使这应该没有任何区别; 这似乎仅在操作名称以Async
结尾时才相关(请参阅此帖子和官方问题)。CreatedAtRoute
代替,通过加入相应的Name="DownloadContent"
中的属性HTTPGET DownloadContent
。CreatedAtActionResult
像:return new CreatedAtActionResult(nameof(DownloadContent),
nameof(ItemContentController), new { id = id }, null);
CreatedResult
对象:string url = Url.Action(new UrlActionContext
{
Protocol = Request.Scheme,
Host = Request.Host.Value,
Action = nameof(DownloadContent)
});
return new CreatedResult(url, null);
现在,这就是重点:上面的代码为url
返回null
,然后这使CreatedResult
抛出,因为 201 标头的Location
的url
为 null。 如果我通过选择不同的操作来更改此代码,例如Action = nameof(UploadContent)
,它会起作用,并且我会获得该操作的 URL。
为了完整Startup.cs
,我的Startup.cs
Configure
方法是这样的:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseForwardedHeaders(new ForwardedHeadersOptions
{
ForwardedHeaders = ForwardedHeaders.XForwardedFor
| ForwardedHeaders.XForwardedProto
});
if (env.IsDevelopment()) app.UseDeveloperExceptionPage();
else
{
app.UseExceptionHandler("/Error");
if (Configuration.GetValue<bool>("Server:UseHSTS")) app.UseHsts();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors("CorsPolicy");
app.UseAuthentication();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
// ... Swagger stuff ...
}
使用重载CreatedAtAction(string, object)
,param object
不是您假设的路由参数,而是正文内容。 因此,代码正在寻找一条不存在的 GET api/contents路线。
您需要使用重载CreatedAtAction(string, object, object)
其中 param #2 包含路由参数,而 param #3 包含正文内容。 所以在你的情况下, return CreatedAtAction(nameof(DownloadContent), new { id = id }, null);
将工作。
我能够使用此控制器和邮递员重现您的问题:
public class MyContentController : ControllerBase
{
[HttpGet("api/contents/{id}")]
public IActionResult DownloadContent(int id)
{
return Ok(1);
}
[HttpPost("api/contents/{id}")]
public IActionResult UploadContent(int id)
{
return CreatedAtAction(nameof(DownloadContent), new { id = id });
}
}
更换时我得到了预期的响应
return CreatedAtAction(nameof(DownloadContent), new { id = id });
和
return CreatedAtAction(nameof(DownloadContent), new { id = id }, null);
文档: https : //docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.controllerbase.createdataction? view = aspnetcore-5.0# Microsoft_AspNetCore_Mvc_ControllerBase_CreatedAtAction_System_String_System_Object _
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.