Не удается прочитать необработанные данные как actionContext.Request.Content, всегда пустой в атрибуте Action в веб-API. - PullRequest
0 голосов
/ 08 ноября 2019

Мне нужно прочитать контент, отправленный через post / put в мой Web API через атрибут, чтобы выполнить дополнительную проверку, но значение контента всегда пусто, даже при том, что я вижу, что context-size установлено значение, т.е. 2067 иcontent-type установлен на application/json

Я пробовал разные вещи, но, похоже, ничего не работает:

  • ReadAsync
  • ReadAsByteArrayAsync
  • ReadAsStringAsync
  • и т.д ...

Моя последняя попытка выглядит следующим образом:

public async override void OnActionExecuting(HttpActionContext actionContext)
{
    using (MemoryStream ms = new MemoryStream())
    {
        await actionContext.Request.Content.CopyToAsync(ms)
                           .ConfigureAwait(false);
        var str = System.Text.UTF8Encoding.
                  UTF8.GetString(ms.GetBuffer(), 0, (int)ms.Length);
    }
}

Причина, по которой я пытался использовать CopyTo, заключается в том, что я заметил, чтокогда я вызывал некоторые из вышеперечисленных функций, что, хотя они возвращали пустую строку, я мог сделать этот вызов один раз после некоторого поиска в Google, я считаю, что это сделано специально.

Суть в том, что мне нужно получить доступтело / содержание моего запроса, чтобы я мог проверить отправленный JSON.

Спасибо.

1 Ответ

0 голосов
/ 08 ноября 2019

Проблема здесь в том, что промежуточное программное обеспечение, которое выполняет действие контроллера, считывает тело запроса и, таким образом, использует его в процессе, что лишает возможности любого последующего промежуточного программного обеспечения получать к нему доступ. Вот почему вы возвращаете пустую строку при попытке проанализировать поток, поскольку вы фактически читаете поток с нулевой длиной.

Похоже, что промежуточное ПО фильтра действий запускается после промежуточное ПО контроллера, которое уже слишком поздно в процессе конвейера. Решением было бы настроить пользовательское промежуточное программное обеспечение, которое выполняет до промежуточного программного обеспечения контроллера, и анализировать поток тела запроса только , если текущая конечная точка действия помечена данным атрибутом.

Представленное здесь решение написано для ASP.NET Core 3.0, поэтому вам, возможно, придется внести некоторые изменения, чтобы оно работало в вашем конкретном проекте.

In Startup.cs :

public void Configure(IApplicationBuilder app)
{
   app.UseRouting();   // Routes middleware


   // Request body-reading middleware must be put after UseRouting()

   app.Use(async (ctx, next) =>
   {
      var endpoint = ctx.GetEndpoint();

      if (endpoint != null)
      {
         var attribute = endpoint.Metadata.GetMetadata<ThierryAttribute>();

         if (attribute != null)
         {
            ctx.Request.EnableBuffering();

            using (var sr = new StreamReader(ctx.Request.Body, Encoding.UTF8, false, 1024, true))
            {
               var str = await sr.ReadToEndAsync();   // Store request body JSON string
            }

            ctx.Request.Body.Position = 0;
         }
      }

      await next();
   });

   app.UseEndpoints(erb => erb.MapControllers());   // Controller middleware
}

И превратить ваш атрибут в пустой атрибут маркера:

[AttributeUsage(AttributeTargets.Method)]
public class ThierryAttribute : Attribute { }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...