Closed
Description
Asp.Versioning.Mvc.ApiExplorer:6.0.0-preview.3
netcore:net6
After the UseExceptionHandler
is enabled, an "NullReferenceException" is thrown when the interface exception occurs.
Program.cs:
using Asp.Versioning;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
builder.Services.AddExceptionHandler(options => options.ExceptionHandler= async(http)=> {
http.Response.StatusCode = 200;
await http.Response.WriteAsync("111"); });
builder.Services.AddApiVersioning(option =>
{
option.ReportApiVersions = true;
option.AssumeDefaultVersionWhenUnspecified = true;
option.DefaultApiVersion = new ApiVersion(1, 0);
}).AddMvc().AddApiExplorer(o =>
{
o.GroupNameFormat = "'v'VVV";
o.SubstituteApiVersionInUrl = true;
o.DefaultApiVersion = new ApiVersion(1, 0);
});
var app = builder.Build();
app.UseExceptionHandler();
app.MapControllers();
app.Run();
TestController.cs
using Asp.Versioning;
using Microsoft.AspNetCore.Mvc;
namespace WebApplication2
{
[Route("api/v1/[controller]")]
[ApiController]
[ApiVersion("1.0")]
public class TestController : ControllerBase
{
private readonly ILogger<TestController> _logger;
public TestController(ILogger<TestController> logger, ILoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<TestController>();
}
[HttpGet]
public async Task<object> Get()
{
throw new Exception();
return new { test = "1.0" };
}
}
}
error:
System.ObjectDisposedException: The response has been aborted due to an unhandled application exception.
---> System.NullReferenceException: Object reference not set to an instance of an object.
at Asp.Versioning.DefaultApiVersionReporter.Report(HttpResponse response, ApiVersionModel apiVersionModel)
at Asp.Versioning.ReportApiVersionsAttribute.ReportApiVersions(Object state)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.<FireOnStarting>g__ProcessEvents|226_0(HttpProtocol protocol, Stack`1 events)
--- End of inner exception stack trace ---
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.InitializeResponseAsync(Int32 firstWriteByteCount)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.FlushPipeAsync(CancellationToken cancellationToken)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpResponseStream.FlushAsync(CancellationToken cancellationToken)
at Microsoft.AspNetCore.Watch.BrowserRefresh.ResponseStreamWrapper.FlushAsync(CancellationToken cancellationToken)
at System.IO.Stream.FlushAsync()
at Microsoft.WebTools.BrowserLink.Net.ScriptInjectionFilterStream.FlushAsync(CancellationToken cancellationToken)
at Microsoft.WebTools.BrowserLink.Net.SendFilesWrapper.StartAsync(CancellationToken cancellationToken)
at Microsoft.AspNetCore.Http.HttpResponseWritingExtensions.StartAndWriteAsyncAwaited(HttpResponse response, String text, Encoding encoding, CancellationToken cancellationToken, Task startAsyncTask)
The possible cause is the following code in "ExceptionHandlerMiddleware"
private static void ClearHttpContext(HttpContext context)
{
context.Response.Clear();
// An endpoint may have already been set. Since we're going to re-invoke the middleware pipeline we need to reset
// the endpoint and route values to ensure things are re-calculated.
context.SetEndpoint(endpoint: null);
var routeValuesFeature = context.Features.Get<IRouteValuesFeature>();
if (routeValuesFeature != null)
{
routeValuesFeature.RouteValues = null!;
}
}