/// <summary> /// Writes the specified problem details object to the HTTP response stream. /// </summary> /// <param name="problemDetails"> /// The problem details. /// </param> /// <param name="response"> /// The HTTP response. /// </param> /// <param name="stream"> /// The destination response stream. /// </param> /// <returns> /// A <see cref="Task"/> that will perform the write. /// </returns> private async Task WriteProblemDetailsToStream(ProblemDetails problemDetails, IOwinResponse response, Stream stream) { // Set response status code if (problemDetails.Status.HasValue) { response.StatusCode = problemDetails.Status.Value; } ; // Create a new buffer, and then create and serialize a problem details object // into the new buffer. using (var ms = new MemoryStream()) { var content = new ObjectContent( problemDetails.GetType(), problemDetails, new JsonMediaTypeFormatter(), ClientErrorDataDefaults.MediaType ); await content.CopyToAsync(ms).ConfigureAwait(false); // Now set the content type and content length on the response, and copy // the content of the new buffer into the original response stream. response.ContentType = content.Headers.ContentType.ToString(); response.ContentLength = ms.Length; ms.Position = 0; await ms.CopyToAsync(stream).ConfigureAwait(false); } }
private static async Task WriteResponseAsync(IWebHostEnvironment env, HttpContext context, ProblemDetails problemDetails, HttpStatusCode statusCode) { context.Response.StatusCode = (int)statusCode; context.Response.ContentType = "application/problem+json"; var options = new JsonSerializerOptions { PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = env.IsDevelopment() }; var json = JsonSerializer.Serialize(problemDetails, problemDetails.GetType(), options); await context.Response.WriteAsync(json); }
public void GetProvider_ReturnsWrapper_ForProblemDetails() { // Arrange var providerFactory = new ProblemDetailsWrapperProviderFactory(); var instance = new ProblemDetails(); var context = new WrapperProviderContext(instance.GetType(), isSerialization: true); // Act var provider = providerFactory.GetProvider(context); // Assert var result = provider.Wrap(instance); var wrapper = Assert.IsType <ProblemDetailsWrapper>(result); Assert.Same(instance, wrapper.ProblemDetails); }
public void TestWrite() { JsonSerializerOptions options = new JsonSerializerOptions(); options.SetupExtensions(); object value = new ProblemDetails() { Status = 400 }; const string json = @"{""type"":null,""title"":null,""status"":400,""detail"":null,""instance"":null}"; string result = JsonSerializer.Serialize(value, value.GetType(), options); Assert.Equal(json, result); }
private Task WriteProblemDetails(HttpContext context, ProblemDetails details) { var routeData = context.GetRouteData() ?? _emptyRouteData; var actionContext = new ActionContext(context, routeData, _emptyActionDescriptor); var result = new ObjectResult(details) { StatusCode = details.Status ?? context.Response.StatusCode, DeclaredType = details.GetType(), }; result.ContentTypes.Add("application/problem+json"); result.ContentTypes.Add("application/problem+xml"); return(_executor.ExecuteAsync(actionContext, result)); }
public static Task WriteProblemDetailsAsync(this HttpContext context, ProblemDetails details) { if (String.IsNullOrWhiteSpace(details.Instance)) { details.Instance = context.Request.Path; } var result = new ObjectResult(details) { StatusCode = details.Status ?? context.Response.StatusCode, DeclaredType = details.GetType(), }; result.ContentTypes.Add("application/problem+json"); result.ContentTypes.Add("application/problem+xml"); return(context.ExecuteResultAsync(result)); }
public void GetProvider_Returns21CompatibleWrapper_ForProblemDetails() { // Arrange var xmlOptions = new MvcXmlOptions(); var providerFactory = new ProblemDetailsWrapperProviderFactory(xmlOptions); var instance = new ProblemDetails(); var context = new WrapperProviderContext(instance.GetType(), isSerialization: true); // Act var provider = providerFactory.GetProvider(context); // Assert var result = provider.Wrap(instance); #pragma warning disable CS0618 // Type or member is obsolete var wrapper = Assert.IsType <ProblemDetails21Wrapper>(result); #pragma warning restore CS0618 // Type or member is obsolete Assert.Same(instance, wrapper.ProblemDetails); }
public static RequestDelegate CreateExceptionHandler(IWebHostEnvironment env) { return(async context => { var exceptionHandlerFeature = context.Features.Get <IExceptionHandlerFeature>(); var state = new Dictionary <string, object>(); var logger = context.RequestServices.GetRequiredService <ILogger <ExceptionHandler> >(); var problem = new ProblemDetails { Status = 500, Title = exceptionHandlerFeature.Error.Message, Detail = env.IsDevelopment() ? exceptionHandlerFeature.Error.ToString() : null, Type = exceptionHandlerFeature.Error.GetType().Name ?? string.Empty }; switch (exceptionHandlerFeature.Error) { case ValidationException ve: var validationProblemDetails = new ValidationProblemDetails(); validationProblemDetails.Status = 400; validationProblemDetails.Type = ve.GetType().Name; // or just use ValidationException constant if (ve.ValidationResult is ValidationResult failure) { validationProblemDetails.Errors.Add(failure.MemberNames.FirstOrDefault() ?? "_", new[] { failure.ErrorMessage }); state.Add("ValidationErrors", JsonSerializer.Serialize(validationProblemDetails.Errors)); } using (logger.BeginScope(state)) { logger.LogInformation("Validation problem with status {response_status}", 400); } problem = validationProblemDetails; break; case ServiceException se: state.Add("ServiceException", se.InnerException?.GetType().FullName ?? string.Empty); state.Add("ServiceMessage", se.InnerException?.Message ?? string.Empty); using (logger.BeginScope(state)) { logger.LogError(se, "External Service returned error"); } break; default: logger.LogError(exceptionHandlerFeature.Error, "Unexpected Exception"); break; } var traceId = Activity.Current?.TraceId.ToString() ?? context?.TraceIdentifier; if (traceId != null) { problem.Extensions["traceId"] = traceId; } context !.Response.StatusCode = problem.Status ?? 500; context.Response.ContentType = ApplicationProblemJson; var stream = context.Response.Body; await JsonSerializer.SerializeAsync(stream, problem, problem.GetType()).ConfigureAwait(false); }); }