// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System.Buffers; using System.IO; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Formatters; using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc.Internal; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; using Newtonsoft.Json; using Xunit; namespace System.Web.Http { public class InvalidModelStateResultTest { [Fact] public async Task InvalidModelStateResult_SetsStatusCode() { // Arrange var httpContext = new DefaultHttpContext(); httpContext.RequestServices = CreateServices(); var stream = new MemoryStream(); httpContext.Response.Body = stream; var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); var modelState = new ModelStateDictionary(); modelState.AddModelError("product.Name", "Name is required."); var result = new InvalidModelStateResult(modelState, includeErrorDetail: false); // Act await result.ExecuteResultAsync(context); // Assert Assert.Equal(StatusCodes.Status400BadRequest, context.HttpContext.Response.StatusCode); } [Fact] public async Task InvalidModelStateResult_WritesHttpError() { // Arrange var httpContext = new DefaultHttpContext(); httpContext.RequestServices = CreateServices(); var stream = new MemoryStream(); httpContext.Response.Body = stream; var context = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); var modelState = new ModelStateDictionary(); modelState.AddModelError("product.Name", "Name is required."); var expected = "{\"Message\":\"The request is invalid.\"," + "\"ModelState\":{\"product.Name\":[\"Name is required.\"]}}"; var result = new InvalidModelStateResult(modelState, includeErrorDetail: false); // Act await result.ExecuteResultAsync(context); // Assert using (var reader = new StreamReader(stream)) { stream.Seek(0, SeekOrigin.Begin); var content = reader.ReadToEnd(); Assert.Equal(expected, content); } } private static IServiceProvider CreateServices() { var options = Options.Create(new MvcOptions()); options.Value.OutputFormatters.Add(new StringOutputFormatter()); options.Value.OutputFormatters.Add(new JsonOutputFormatter( new JsonSerializerSettings(), ArrayPool.Shared)); var services = new ServiceCollection(); services.AddSingleton>(new ObjectResultExecutor( new DefaultOutputFormatterSelector(options, NullLoggerFactory.Instance), new TestHttpResponseStreamWriterFactory(), NullLoggerFactory.Instance)); return services.BuildServiceProvider(); } } }