Как ответить телом JSON на 415 (неподдерживаемый тип носителя) в минимальных API ASP .NET Core? ⇐ C#
Как ответить телом JSON на 415 (неподдерживаемый тип носителя) в минимальных API ASP .NET Core?
Если вы вызываете конечную точку минимальных API ASP .NET Core без заголовка Content-Type, вы получаете пустой ответ тела с кодом состояния 415. Мне нужно обработать эту ошибку и ответить с некоторой ошибкой JSON. Я не могу заставить конечную точку ответить чем-либо, кроме пустой строки. Кроме того, обработчик исключений ничего не перехватывает.
Вот пример приложения и тесты, объясняющие проблему.
API
использование System.Runtime.CompilerServices; использование Microsoft.AspNetCore.Mvc; [сборка: InternalsVisibleTo("TestProject1")] вар строитель = WebApplication.CreateBuilder(args); builder.Services.Configure(o => o.ThrowOnBadRequest = true); вар приложение = builder.Build(); app.MapPost("/hi", ([FromBody] Request request) => "Hello World!"); app.MapPost("/throwerror", (запрос запроса [FromBody]) => true ? throw new Exception("Ouch") : ""); app.UseExceptionHandler(handlerApp => handlerApp.Run(асинхронный контекст => { context.Response.StatusCode = 400; await context.Response.WriteAsync("Выбросила ошибку"); })); приложение.Выполнить(); Запрос записи (int Id); Тесты
с использованием System.Text; использование Microsoft.AspNetCore.Mvc.Testing; пространство имен TestProject1; [ТестКласс] публичный класс UnitTest1 { //Этот тест не проходит. Я думаю, что он должен попасть в обработчик исключений и установить для тела значение «Выбросила ошибку». // Чего мне нужно добиться, так это способности выдавать значимое сообщение об ошибке в теле, если потребитель //не указывает заголовок Content-Type [Метод испытания] общедоступная асинхронная задача TestHiRespondsWithTextFromExceptionHandlerOnNoContentType() { var Factory = новый WebApplicationFactory().WithWebHostBuilder(builder => {}); вар клиент = фабрика.CreateClient(); var ответ = ожидайте client.PostAsync(new Uri("http://localhost/hi"), //Нет типа контента new StringContent( "{ \"Id\": \"123\" }", Encoding.UTF8)); var body = ждут ответа.Content.ReadAsStringAsync(); //это докажет, что обработчик исключений обрабатывает это Assert.AreEqual("Выброс ошибки", тело); } [Метод испытания] общедоступная асинхронная задача TestSuccessRespondsWithHelloWorld() { var Factory = новый WebApplicationFactory().WithWebHostBuilder(builder => {}); вар клиент = фабрика.CreateClient(); var ответ = ожидайте client.PostAsync(new Uri("http://localhost/hi"), new StringContent( "{ \"Id\": \"123\" }", Encoding.UTF8,"application/json"); var body = ждут ответа.Content.ReadAsStringAsync(); Assert.AreEqual("Привет, мир!", тело); } [Метод испытания] общедоступная асинхронная задача TestThrowErrorRespondsWithTextFromExceptionHandler() { var Factory = новый WebApplicationFactory().WithWebHostBuilder(builder => {}); вар клиент = фабрика.CreateClient(); var ответ = ожидайте client.PostAsync(new Uri("http://localhost/throwerror"), new StringContent( "{ \"Id\": \"123\" }", Encoding.UTF8,"application/json"); var body = ждут ответа.Content.ReadAsStringAsync(); //это доказывает, что обработчик исключений обрабатывает это Assert.AreEqual("Выброс ошибки", тело); } } Обратите внимание, что первый тест не пройден, поскольку он никогда не достигает обработчика исключений. Это как если бы какое-то промежуточное программное обеспечение выполнялось раньше любого другого промежуточного программного обеспечения и никогда не вызывало исключений. Он просто отвечает 415 Неподдерживаемый тип носителя, прежде чем дать мне возможность что-либо сделать. Как мне подключиться к этому промежуточному программному обеспечению, чтобы ответить телом?
Два нижних теста пройдены.
Если вы вызываете конечную точку минимальных API ASP .NET Core без заголовка Content-Type, вы получаете пустой ответ тела с кодом состояния 415. Мне нужно обработать эту ошибку и ответить с некоторой ошибкой JSON. Я не могу заставить конечную точку ответить чем-либо, кроме пустой строки. Кроме того, обработчик исключений ничего не перехватывает.
Вот пример приложения и тесты, объясняющие проблему.
API
использование System.Runtime.CompilerServices; использование Microsoft.AspNetCore.Mvc; [сборка: InternalsVisibleTo("TestProject1")] вар строитель = WebApplication.CreateBuilder(args); builder.Services.Configure(o => o.ThrowOnBadRequest = true); вар приложение = builder.Build(); app.MapPost("/hi", ([FromBody] Request request) => "Hello World!"); app.MapPost("/throwerror", (запрос запроса [FromBody]) => true ? throw new Exception("Ouch") : ""); app.UseExceptionHandler(handlerApp => handlerApp.Run(асинхронный контекст => { context.Response.StatusCode = 400; await context.Response.WriteAsync("Выбросила ошибку"); })); приложение.Выполнить(); Запрос записи (int Id); Тесты
с использованием System.Text; использование Microsoft.AspNetCore.Mvc.Testing; пространство имен TestProject1; [ТестКласс] публичный класс UnitTest1 { //Этот тест не проходит. Я думаю, что он должен попасть в обработчик исключений и установить для тела значение «Выбросила ошибку». // Чего мне нужно добиться, так это способности выдавать значимое сообщение об ошибке в теле, если потребитель //не указывает заголовок Content-Type [Метод испытания] общедоступная асинхронная задача TestHiRespondsWithTextFromExceptionHandlerOnNoContentType() { var Factory = новый WebApplicationFactory().WithWebHostBuilder(builder => {}); вар клиент = фабрика.CreateClient(); var ответ = ожидайте client.PostAsync(new Uri("http://localhost/hi"), //Нет типа контента new StringContent( "{ \"Id\": \"123\" }", Encoding.UTF8)); var body = ждут ответа.Content.ReadAsStringAsync(); //это докажет, что обработчик исключений обрабатывает это Assert.AreEqual("Выброс ошибки", тело); } [Метод испытания] общедоступная асинхронная задача TestSuccessRespondsWithHelloWorld() { var Factory = новый WebApplicationFactory().WithWebHostBuilder(builder => {}); вар клиент = фабрика.CreateClient(); var ответ = ожидайте client.PostAsync(new Uri("http://localhost/hi"), new StringContent( "{ \"Id\": \"123\" }", Encoding.UTF8,"application/json"); var body = ждут ответа.Content.ReadAsStringAsync(); Assert.AreEqual("Привет, мир!", тело); } [Метод испытания] общедоступная асинхронная задача TestThrowErrorRespondsWithTextFromExceptionHandler() { var Factory = новый WebApplicationFactory().WithWebHostBuilder(builder => {}); вар клиент = фабрика.CreateClient(); var ответ = ожидайте client.PostAsync(new Uri("http://localhost/throwerror"), new StringContent( "{ \"Id\": \"123\" }", Encoding.UTF8,"application/json"); var body = ждут ответа.Content.ReadAsStringAsync(); //это доказывает, что обработчик исключений обрабатывает это Assert.AreEqual("Выброс ошибки", тело); } } Обратите внимание, что первый тест не пройден, поскольку он никогда не достигает обработчика исключений. Это как если бы какое-то промежуточное программное обеспечение выполнялось раньше любого другого промежуточного программного обеспечения и никогда не вызывало исключений. Он просто отвечает 415 Неподдерживаемый тип носителя, прежде чем дать мне возможность что-либо сделать. Как мне подключиться к этому промежуточному программному обеспечению, чтобы ответить телом?
Два нижних теста пройдены.
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение