添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
乖乖的芹菜  ·  python ...·  1 年前    · 
心软的芒果  ·  python 变量赋值 逗号 ...·  1 年前    · 

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement . We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account ✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. question Status: Resolved

Describe the bug

When using standard responses such as NotFound() and BadRequest() from an API controller marked with [ApiController] , these will generate an RFC 7807 compliant error, by converting the status based response to a ProblemDetails instance.

However, if you use BadRequest(object ), Conflict(object) , NotFound(object) , Unauthorised(object) or UnprocessableEntity(object) , the object only is serialised to the response and no RFC 7807 response is generated.

This seems inconsistent. I'd wish to have the RFC 7807 data at all times, and extend the data to include the object passed to NotFoundResult(object) as well as the RFC data.

I know I can use BadRequestResult(new ValidationProblemDetails(...)) , but I'd rather not mess up my controllers when I already have a perfectly valid object of my own returned from these methods.

To Reproduce

Create a simple .NET Core website, and add a controller such as the following. The only difference with the methods here is the use of NotFound() or NotFound(object).

[ApiController]
[Route("[controller]")]
public class TestController : ControllerBase
    [HttpGet]
    public IActionResult Get()
        return NotFound();
    [HttpPost]
    public IActionResult Post()
        return NotFound("Hello");

When making the GET /test call, the response will be as follows...

Status Code: 400
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.4",
  "title": "Not Found",
  "status": 404,
  "traceId": "|7488d3fc-4df34ddd6b3b98e8."

When calling the POST /test method, the response does not contain the problem details data, just the object that's returned from the call...

Status Code: 400
Hello

In the former case, the BadRequestResult class derived from StatusCoderesult, which itself implements the marker interface, IClientErrorActionResult. When an error is returned from a call that implements IClientErrorActionResult, it goes through a filter registered in the pipeline which then transforms the error into a ProblemDetails instance. which is what's returned.

If however you use any of the methods that return an ObjectResult derived class, such as BadRequestObjectResult, these do not include this marker interface, and are therefore passed through as usual. Given the work that's gone into the framework to return the ProblemDetails instance, I'd have though that the *ObjectResult classes should follow the same path through the code and, ultimately, be enhanced with the RFC 7807 data.

If a deliberate decision has been made not to make ObjectResult (or derived classes) format on output like the non ObjectResult versions, please could the documentation on ProblemDetails make this abundantly clear? I've spent hours debugging this thinking I'd done something wrong, when this is, as far as I can tell, a deliberate decision.

Ideal Solution

For me, the ideal solution would allow me to return any object from a method using BadRequest(object) (or the other *ObjectResult methods), and have that serialised to the output stream, but also include the additional fields from ProblemDetail, similar to the following...

public class MissingPersonRecord
  public string PersonId { get; set; }
public IActionResult GetPersonn(int personId)
  if (no person exists in the database)
    return NotFound(new MissingPersonRecord { PersonId = personId });
  "PersonId": "12345",
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.4",
  "title": "Not Found",
  "status": 404,
  "traceId": "|7488d3fc-4df34ddd6b3b98e8."

Here I've added the set of properties of the MissingPersonRecord together with those of the ProblemDetails object.

Further technical details

.NET Core SDK (reflecting any global.json):
Version: 3.1.101
Commit: b377529961

Runtime Environment:
OS Name: Windows
OS Version: 10.0.18362
OS Platform: Windows
RID: win10-x64
Base Path: C:\Program Files\dotnet\sdk\3.1.101\

Host (useful for support):
Version: 3.1.1
Commit: a1388f194c

.NET Core SDKs installed:
1.0.0-preview2-003121 [C:\Program Files\dotnet\sdk]
1.0.0-preview2-003131 [C:\Program Files\dotnet\sdk]
1.0.4 [C:\Program Files\dotnet\sdk]
1.1.0 [C:\Program Files\dotnet\sdk]
2.0.0 [C:\Program Files\dotnet\sdk]
2.0.2 [C:\Program Files\dotnet\sdk]
2.1.2 [C:\Program Files\dotnet\sdk]
2.1.104 [C:\Program Files\dotnet\sdk]
2.1.602 [C:\Program Files\dotnet\sdk]
2.1.700 [C:\Program Files\dotnet\sdk]
3.1.101 [C:\Program Files\dotnet\sdk]

.NET Core runtimes installed:
Microsoft.AspNetCore.All 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.All 2.1.15 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All]
Microsoft.AspNetCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 2.1.15 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.AspNetCore.App 3.1.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App]
Microsoft.NETCore.App 1.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 1.0.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 1.0.5 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 1.1.2 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.0.0 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.0.3 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.0.6 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.9 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.11 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 2.1.15 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.NETCore.App 3.1.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App]
Microsoft.WindowsDesktop.App 3.1.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]

To install additional .NET Core runtimes or SDKs:
https://aka.ms/dotnet-download

I'm running on Visual Studio 2019 16.4.4.

@morganski thanks for contacting us.

I believe that might be by design, if you are passing an object directly it is likely that we don't want to interfere with what you explicitly told us to serialize.

@pranavkm Is there anything you want to add?

✔️ Resolution: Answered Resolved because the question asked by the original author has been answered. question Status: Resolved