Использование `ProblemDetails` с действием, несущим` [Produces ("application / xml")] `в ASP.NET Core 2.2 - PullRequest
0 голосов
/ 23 сентября 2019

Я собираюсь использовать ProblemDetails и унаследованные классы для выражения ошибок 422.

Я создал фиктивный класс контроллера и одно действие в ASP.NET Core 2.2:

[Route("api/v1")]
[ApiController]
public class ValuesController : ControllerBase
{
    [HttpGet("values/json")]
    [Produces("application/json")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status422UnprocessableEntity)]
    public ActionResult JsonGet()
    {
        var problemDetails = new ProblemDetails();
        return UnprocessableEntity(problemDetails);
    }

    [HttpGet("values/xml")]
    [Produces("application/xml")]
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status422UnprocessableEntity)]
    public ActionResult XmlGet()
    {
        var problemDetails = new ProblemDetails();
        return UnprocessableEntity(problemDetails);
    }
}

Но при включении API соответственно:

Конечная точка json:

λ  Invoke-WebRequest -Uri "https://localhost:5001/api/v1/values/json" -Headers @{'Accept' = 'application/json'; }  
Invoke-WebRequest : The remote server returned an error: (422) Unprocessable Entity.                               
At line:1 char:1                                                                                                   
+ Invoke-WebRequest -Uri "https://localhost:5001/api/v1/values/json" -H ...                                        
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                            
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], W  
   ebException                                                                                                     
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand  

и

Конечная точка xml:

λ  Invoke-WebRequest -Uri "https://localhost:5001/api/v1/values/xml" -Headers @{'Accept' = 'application/xml'; }
Invoke-WebRequest : The remote server returned an error: (406) Not Acceptable.
At line:1 char:1
+ Invoke-WebRequest -Uri "https://localhost:5001/api/v1/values/xml" -He ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], W
   ebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

1 Ответ

1 голос
/ 23 сентября 2019

Я обнаружил, что это было довольно глупо ...

Оказывается, я думал, что поддержка XML была из коробки, но это не так: https://andrewlock.net/formatting-response-data-as-xml-or-json-based-on-the-url-in-asp-net-core/

My Startup.cs:

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddSwaggerGen(options =>
        {
            options.SwaggerDoc("v1", new Info {Title = "C# Web API", Version = "v1"});
            var assemblyXmlPath = Assembly.GetExecutingAssembly().GetName().Name + ".xml";
            var xmlPath = Path.Combine(AppContext.BaseDirectory, assemblyXmlPath);
            options.IncludeXmlComments(xmlPath);
        });

        services.AddMvc()
            .SetCompatibilityVersion(CompatibilityVersion.Version_2_2)
            .AddXmlSerializerFormatters(); // <= this was missing...
    }

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseHsts();
        }

        app.UseSwagger()
           .UseSwaggerUI(options => options.SwaggerEndpoint("/swagger/v1/swagger.json", "v1"));

        app.UseHttpsRedirection();
        app.UseMvc();
    }
}

Теперь для обеих конечных точек все в порядке:

λ  Invoke-WebRequest -Uri "https://localhost:5001/api/v1/values/json" -Headers @{'Accept' = 'application/json'; }
Invoke-WebRequest : The remote server returned an error: (422) Unprocessable Entity.
At line:1 char:1
+ Invoke-WebRequest -Uri "https://localhost:5001/api/v1/values/json" -H ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], W
   ebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
λ  Invoke-WebRequest -Uri "https://localhost:5001/api/v1/values/xml" -Headers @{'Accept' = 'application/xml'; }
Invoke-WebRequest : The remote server returned an error: (422) Unprocessable Entity.
At line:1 char:1
+ Invoke-WebRequest -Uri "https://localhost:5001/api/v1/values/xml" -He ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], W
   ebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand

Я думаю, что эта ошибка вводит в заблуждение или вводит в заблуждение, заставляя вас думать, чтопроблема заключается в конфигурации контроллера / действия, а не в конфигурации служб.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...