У меня есть устаревший клиент .Net Framework с множеством установок, которые нельзя изменить.Мне нужно обработать http-запросы, которые он использует для загрузки файлов на сервер.
Ранее мы могли использовать HttpContext.Request.Files.Но так как мы сейчас используем ядро dotnet, мы должны использовать HttpContext.Request.Form.Files.Что вызывает исключение
«Значение не может быть нулевым. Имя параметра: заголовок» трассировки стека выглядит следующим образом
в Microsoft.Net.Http.Headers.ContentDispositionHeaderValueIdentityExtensions.IsFileDisposition (Заголовок ContentDispositionHeaderValue) в Microsoft.AspNetCore.Http.Features.FormFeature.InnerReadFormAsync (CancellationToken cancellationToken) в Microsoft.AspNetCore.Http.Features.FormFeature.ReadForm () * в Microsoft.Asptt_FHet.
Глядя на источник ядра asp dotnet на github, я вижу точную проблему здесь в строке 26.
return header.DispositionType.Equals("form-data")
&& (!StringSegment.IsNullOrEmpty(header.FileName) || !StringSegment.IsNullOrEmpty(header.FileNameStar));
Я предположил, что это проблемаклиент добавляет эту информацию заголовка в файлы, а не сам запрос, но когда я добавил немного промежуточного программного обеспечения (см. ниже) для добавления этого заголовка в свой запрос, HttpContext.Request.Form по-прежнему выдает исключение.Я не знаю, генерируется ли это исключение при создании, или я неправильно устанавливаю заголовок, или это ошибка в ядре dotnet.На github были открытые проблемы, чтобы улучшить сообщение об ошибке, но ничто не говорит о том, что проблема заключается в их коде.
Я хочу просто «починить» заголовки, так как знаю, что вызовы к этой конечной точке всегда будут составнымиформировать данные, в идеале используя промежуточное программное обеспечение, чтобы контроллер не сталкивался с ним.
промежуточное программное обеспечение:
public class FormDataHeaderRepair
{
private readonly RequestDelegate _next;
public FormDataHeaderRepair(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
var headers = context.Request.Headers;
if (context.Request.Path.ToString().Equals("/api/MyController/Queue", StringComparison.OrdinalIgnoreCase))
{
if (context.Request.Headers["Content-Disposition"].Count == 0)
{
var cv = new Microsoft.Net.Http.Headers.ContentDispositionHeaderValue("form-data");
cv.FileName = "request.xml";
var stringVersion = cv.ToString();
context.Request.Headers[HeaderNames.ContentDisposition] = stringVersion;
}
}
await _next(context);
}
}
РЕДАКТИРОВАНИЕ / ОБНОВЛЕНИЕ: добавление этого кода в мой контроллер возвращает «true»для 'theResult', который заставляет меня думать, что существует какая-то другая кэшированная коллекция запросов / заголовков, которую использует ContentDispositionHeaderValueIdentityExtensions, поскольку это точный код оценки, который они используют ... либо этот, либо они получают заголовок иначе, чем этот.
var header = HttpContext.Request.GetTypedHeaders().ContentDisposition;
var theResult = header.DispositionType.Equals("form-data") && (!StringSegment.IsNullOrEmpty(header.FileName) || !StringSegment.IsNullOrEmpty(header.FileNameStar));