简体   繁体   English

无法从POST请求反序列化HttpContent

[英]Can not deserialize HttpContent from POST request

I am trying to send a POST request to a server.The request gets into the Middleware 's Invoke method. 我正在尝试向服务器发送POST请求。该请求进入了MiddlewareInvoke方法。

However the Content is always null, no matter the type of the object. 但是,无论对象的类型如何, Content始终为null。

Sender 发件人

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;
    }
}

Server 服务器

The server has no service defined ,just a plain middleware that responds on a route . 服务器没有定义service ,只是一个普通的middlewareroute上做出响应。 ( The request gets in the Invoke method ! ) (请求进入Invoke方法!)

Startup 启动

 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>();
                });
            });
        }
   }

Middleware 中间件

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;
                }
            }
    }
}

I have checked my serialization and the object is serialized just fine. 我已经检查了序列化,并且对象被序列化就好了。

Despite this I am always getting a null on the other side. 尽管如此,我总是在另一侧得到null

PS 聚苯乙烯

I have also tried using no middleware just a plain delegate like below : 我也尝试过不使用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;
                  }
                }
        });
    }

Even without a dedicated middleware the problem persists. 即使没有专用的middleware ,问题仍然存在。

The problem is not the middleware , its the request that is serialized correctly in the client, sent to the server ,and somehow its body shows up as null . 问题不在于middleware ,而是middleware ,它是在客户端中正确序列化的请求,已发送到服务器,并且它的body以某种方式显示为null

I would've understood if it failed to deserialize the object , but the HttpContext.Request.Body as a string is received null and its length is null !! 如果它无法deserialize该对象,我会理解的,但是将HttpContext.Request.Body作为字符串接收为null并且其lengthnull

In your example, the client code calls the route "/mat", but the middleware is configured at "/mid". 在您的示例中,客户端代码将路由称为“ / mat”,但是将中间件配置为“ / mid”。 If the code you're running has the same error, the middleware won't get hit, and you'll always get an empty response that, from the client, looks the same as if the middleware received null . 如果您正在运行的代码具有相同的错误,则中间件将不会受到攻击,并且您始终会收到一个空响应,该响应从客户端看起来就像中间件收到null Make sure you're also using the right port number--mine was :5000 , but it can vary depending on the runtime configuration. 确保您还使用了正确的端口号-mine是:5000 ,但是它会根据运行时配置而有所不同。

Are you testing with a debugger and breakpoints? 您是否正在使用调试器和断点进行测试? If not, I highly recommend trying. 如果没有,我强烈建议尝试。 I was able to find that error pretty quickly because I set a breakpoint in the server-side code, and observed that it wasn't getting hit. 我能够很快找到该错误,因为我在服务器端代码中设置了一个断点,并观察到它没有被命中。 If a debugger isn't an option, consider "failing loudly" by throwing an exception (instead of simply returning) to make it more obvious whether or not you're actually hitting the condition you think you're hitting. 如果不是调试器的选项,请考虑通过抛出异常(而不是简单地返回)来“大声失败”,以使其更明显地知道您是否实际上达到了您认为要达到的条件。

Not sure what's exactly wrong with your code, but this works: 不知道您的代码到底有什么问题,但这可以工作:

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);
    });
  }
}

Running this in chrome dev tools: 在chrome开发工具中运行此代码:

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)

Yields the following in the browser: 在浏览器中产生以下内容:

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

suppose your request is request= @" {"title":"foo","body":"bar","userId":1}"; 假设您的请求是request = @“ {” title“:” foo“,” body“:” bar“,” userId“:1}”;

call RunTestAsync(request); 调用RunTestAsync(request); run just this JsonConvert.SerializeObject(request); 运行这个JsonConvert.SerializeObject(request); I'm sure it fails because its not serializable. 我确定它会失败,因为它无法序列化。 and if it is it should be 如果是这样的话
some object of serializable class 可序列化类的某些对象

(Serializableclass request) (可序列化的类请求)

try this var content = new StringContent(request, Encoding.UTF8, "application/json"); 试试这个var content = new StringContent(request,Encoding.UTF8,“ application / json”);

public async Task RunTestAsync(string request) { try { var content = new StringContent(JsonConvert.SerializeObject(request),Encoding.UTF8,"application/json"); 公共异步任务RunTestAsync(string request){试试{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;
}

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM