У меня есть конечная точка веб-API asp.net core 2 вместе с пользовательским промежуточным ПО.Чтобы выполнить централизованную обработку исключений и проверку запросов для проекта, я сослался на ссылку: https://www.strathweb.com/2018/07/centralized-exception-handling-and-request-validation-in-asp-net-core/
На основе ссылки я реализовал следующий код:
// Startup
public class Startup
{
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseGraphiQl();
app.UseHttpsRedirection();
app.UseExceptionHandler(errorApp =>
{
errorApp.Run(async context =>
{
var errorFeature = context.Features.Get<IExceptionHandlerFeature>();
var exception = errorFeature.Error;
// the IsTrusted() extension method doesn't exist and
// you should implement your own as you may want to interpret it differently
// i.e. based on the current principal
var problemDetails = new ProblemDetails{Instance = $"urn:myorganization:error:{Guid.NewGuid()}"};
if (exception is BadHttpRequestException badHttpRequestException)
{
problemDetails.Title = "Invalid request";
problemDetails.Status = (int)typeof (BadHttpRequestException).GetProperty("StatusCode", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(badHttpRequestException);
problemDetails.Detail = badHttpRequestException.Message;
}
else
{
problemDetails.Title = "An unexpected error occurred!";
problemDetails.Status = 500;
problemDetails.Detail = "Testing"; //exception.Demystify().ToString();
}
// log the exception etc..
context.Response.StatusCode = problemDetails.Status.Value;
context.Response.WriteJson(problemDetails, "application/problem+json");
}
);
}
);
app.UseCommonResponser();
app.UseMvc();
}
}
// CommonResponseMiddleware
public class CommonResponseMiddleware
{
private readonly RequestDelegate _next;
private ICommonService _commonService;
public CommonResponseMiddleware(RequestDelegate next, ICommonService commonService)
{
_next = next;
_commonService = commonService;
}
public async Task Invoke(HttpContext context)
{
var currentBody = context.Response.Body;
using (var memoryStream = new MemoryStream())
{
context.Response.Body = memoryStream;
await _next.Invoke(context);
context.Response.Body = currentBody;
memoryStream.Seek(0, SeekOrigin.Begin);
var readToEnd = new StreamReader(memoryStream).ReadToEnd();
}
}
}
// GraphQLController
[Route("[controller]")]
[ApiController]
public class GraphQLController : Controller
{
private readonly IDocumentExecuter _documentExecuter;
private readonly ISchema _schema;
public GraphQLController(ISchema schema, IDocumentExecuter documentExecuter)
{
_schema = schema;
_documentExecuter = documentExecuter;
}
[HttpPost]
public async Task<IActionResult> Post([FromBody] GraphQLQuery query)
{
if (query == null)
{
throw new ArgumentNullException(nameof(query));
}
var inputs = query.Variables.ToInputs();
var executionOptions = new ExecutionOptions{Schema = _schema, Query = query.Query, Inputs = inputs, UserContext = Request.Headers, //UserContext = new GraphQLUserContext { Headers = Request.Headers }
};
throw new Exception("Exception while fetching all the students from the storage.");
var result = await _documentExecuter.ExecuteAsync(executionOptions).ConfigureAwait(false);
if (result.Errors?.Count > 0)
{
return BadRequest(result);
}
return Ok(result);
}
}
// HttpExtensions
public static class HttpExtensions
{
private static readonly JsonSerializer Serializer = new JsonSerializer{NullValueHandling = NullValueHandling.Ignore};
public static void WriteJson<T>(this HttpResponse response, T obj, string contentType = null)
{
response.ContentType = contentType ?? "application/json";
using (var writer = new HttpResponseStreamWriter(response.Body, Encoding.UTF8))
{
using (var jsonWriter = new JsonTextWriter(writer))
{
jsonWriter.CloseOutput = false;
jsonWriter.AutoCompleteOnClose = false;
Serializer.Serialize(jsonWriter, obj);
}
}
}
}
Теперь при вызовеконечная точка graphqlcontroller, я намеренно выдаю ошибку, которую пытаюсь уловить в глобальной логике исключений, в которой я пытаюсь настроить ее, прежде чем передать ее клиенту.
Я получаю исключение: поток сейчасДоступное для записи имя параметра: поток, обрабатывая его в классе HttpExtensions в строке ниже:
using (var writer = new HttpResponseStreamWriter(response.Body, Encoding.UTF8))
Может кто-нибудь помочь мне решить эту проблему?