Невозможно десериализовать HttpContent из POST-запроса. - PullRequest
0 голосов
/ 02 февраля 2019

Я пытаюсь отправить запрос POST на сервер. Запрос попадает в метод Middleware Invoke.

Однако Content всегда равен нулю, независимо от того,тип объекта.

Отправитель

public async Task<string> RunTestAsync(string request)
{
    try
    {
        var content = new StringContent(JsonConvert.SerializeObject(request),Encoding.UTF8,"application/json");

       var response=await this.client.PostAsync("http://localhost:8500/mat",
                              content);

        string str=await response.Content.ReadAsStringAsync();
        stringdata = JsonConvert.DeserializeObject<string>(str);
        return data;     
    }
    catch (Exception ex)
    {
        Console.WriteLine("Threw in client" + ex.Message);
        throw;
    }
}

Сервер

На сервере не определено service, простопростой middleware, который отвечает на route.(Запрос получает метод Invoke!)

Запуск

 public class Startup
   {
        public void ConfigureServices(IServiceCollection services) {

        }
        public void Configure(IApplicationBuilder app, IHostingEnvironment env) {

            app.UseDeveloperExceptionPage();
            app.UseBlazor<Client.Startup>();

            app.Map("/mid", a => {
                     a.UseMiddleware<Mware>();
                });
            });
        }
   }

Промежуточное ПО

public class Mware
{
    public RequestDelegate next{get;set;}

    public Mware(RequestDelegate del)
    {
      this.next=del;
    }
    public async Task Invoke(HttpContext context)
    {

            using (var sr = new StreamReader(context.Request.Body))
            {
                string content = await sr.ReadToEndAsync();//null ,tried other types too , still null ,and the ContentLength is null too
                var request=JsonConvert.DeserializeObject<string>(content);
                if (request == null)
                {
                    return;
                }
            }
    }
}

Я проверил свою сериализацию, и объект сериализуется очень хорошо.

Несмотря на это, я всегда получаю null на другой стороне.

PS

Я также пытался использовать не middleware просто простой делегат, как показано ниже:

 public void Configure(IApplicationBuilder app, IHostingEnvironment env) {

        app.UseDeveloperExceptionPage();
        app.UseBlazor<Client.Startup>();

        app.Map("/mid",x=>{
            x.Use(async(context,del)=>{
                using (var sr = new StreamReader(context.Request.Body))
                {
                  string content = await sr.ReadToEndAsync();//null ,tried other types too , still null ,and the ContentLength is null too
                  var request=JsonConvert.DeserializeObject<string>(content);
                  if (request == null)
                  {
                    return;
                  }
                }
        });
    }

Даже без выделенного middleware проблема сохраняется.

Проблема не вmiddleware, это запрос, который правильно сериализован в клиенте, отправлен на сервер, и каким-то образом его body отображается как null.

Я бы понял, если бы не удалось deserialize объект, но HttpContext.Request.Body в виде строки получен null и его length равно null !!

Ответы [ 3 ]

0 голосов
/ 07 февраля 2019

Не уверен, что именно не так с вашим кодом, но это работает:

public class Startup
{
  // This method gets called by the runtime. Use this method to add services to the container.
  // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
  public void ConfigureServices(IServiceCollection services)
  {
  }

  // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
  public void Configure(IApplicationBuilder app, IHostingEnvironment env)
  {
    if (env.IsDevelopment())
    {
      app.UseDeveloperExceptionPage();
    }

    app.Run(async (context) =>
    {
      var request = context.Request;
      var body = request.Body;

      request.EnableRewind();
      var buffer = new byte[Convert.ToInt32(request.ContentLength)];
      await request.Body.ReadAsync(buffer, 0, buffer.Length);
      var bodyAsText = Encoding.UTF8.GetString(buffer);
      request.Body = body;
      await context.Response.WriteAsync(bodyAsText);
    });
  }
}

Запуск этого в инструментах Chrome Dev:

fetch('http://localhost:39538', {
  method: 'POST',
  body: JSON.stringify({
    title: 'foo',
    body: 'bar',
    userId: 1
  }),
  headers: {
    'Content-type': 'application/json; charset=UTF-8'
  }
})
.then(res => res.json())
.then(console.log)

В браузере выдает следующее:

{"title": "foo", "body": "bar", "userId": 1}

0 голосов
/ 09 февраля 2019

предположим, что ваш запрос - request = @ "{" title ":" foo "," body ":" bar "," userId ": 1}";

call RunTestAsync (request);запустить только этот JsonConvert.SerializeObject (запрос);Я уверен, что это терпит неудачу, потому что это не сериализуемо.и если это так, то это должен быть
некоторый объект сериализуемого класса

(запрос Serializableclass)

попробуйте этот var content = new StringContent (запрос, Encoding.UTF8, "application / json");

публичная асинхронная задача RunTestAsync (запрос строки) {try {var content = new StringContent (JsonConvert.SerializeObject (запрос), Encoding.UTF8, "application / json");

   var response=await this.client.PostAsync("http://localhost:8500/mat",
                          content);

    string str=await response.Content.ReadAsStringAsync();
    stringdata = JsonConvert.DeserializeObject<string>(str);
    return data;     
}
catch (Exception ex)
{
    Console.WriteLine("Threw in client" + ex.Message);
    throw;
}

}

0 голосов
/ 07 февраля 2019

В вашем примере код клиента вызывает маршрут "/ mat", но промежуточное ПО настроено на "/ mid".Если в выполняемом вами коде возникает та же ошибка, промежуточное ПО не попадет, и вы всегда получите пустой ответ, который от клиента будет выглядеть так же, как если бы промежуточное ПО получило null.Убедитесь, что вы также используете правильный номер порта - у меня был :5000, но он может варьироваться в зависимости от конфигурации среды выполнения.

Тестируете ли вы с помощью отладчика и точек останова?Если нет, я настоятельно рекомендую попробовать.Мне удалось довольно быстро найти эту ошибку, потому что я установил точку останова в коде на стороне сервера и заметил, что это не получило ошибку.Если отладчик не подходит, рассмотрите возможность «громкого сбоя», выбрасывая исключение (вместо простого возврата), чтобы сделать более очевидным, действительно ли вы выполняете условие, которое, по вашему мнению, вы выполняете.

...