通过序列化的IHttpHandler产生的Protobuf结果无效

问题描述 投票:1回答:2

我使用ASP.NET Web窗体,这意味着我将通过ASPX或ASHX页面中发送的Protobuf数据。

我试图建立一个GTFSRT文件,其中有一个NuGet包称为GTFSRealTimeBindings。这里使用的Protobuf和protobuf网压缩和发送数据。

那我遇到的问题是,当被发送的数据,什么是越来越混乱,因此它不能在接收端进行阅读,我不知道如何纠正它。我认为这是在编码,但我不认为设置,所以我不知道如何去改变它。

我落得这样做是书面方式HTTP处理程序(ashx的页面),将来自其他来源下载一个GTFS文件,然后简单地尝试着它。我知道GTFS文件进行读取,并从其他来源去编码。但每一次我尝试服务器上的文件从我的ashx的网页的时候,我不能解码protbuf对象。

这里是一个非常基本的代码集:

public class Vehicles : IHttpHandler
{

  public void ProcessRequest(HttpContext context)
  {

      WebRequest req = HttpWebRequest.Create("https://cdn.mbta.com/realtime/VehiclePositions.pb");
      FeedMessage feed = Serializer.Deserialize<FeedMessage>(req.GetResponse().GetResponseStream());

      Serializer.Serialize(context.Response.OutputStream, feed);
  }
}

在这个片段中,你会注意到,我下载从cdn.mbta.com一个的Protobuf文件,然后简单地试图把我得到的结果,并通过它背下来。

当我尝试读取到我的示例应用程序如下:

WebRequest req = HttpWebRequest.Create("http://localhost:54988/Secure/Admin/Reports/GtfsRt/Vehicles.ashx");
FeedMessage feed = Serializer.Deserialize<FeedMessage>(req.GetResponse().GetResponseStream());

我得到的消息是:“无效的导线型;这通常意味着你已经过书面文件不截断或设置的长度;看到http://stackoverflow.com/q/2152978/23354

如果我跑提琴手,而这个页面被击中,我注意到,我从cdn.mbta.com得到的回应比本页面给出了回应(当然要去掉头)不同。

例如,从mbta.com前两行中的Fiddler显示:

2.0] y1601" T

但是从我响应的前两行是:为2.0W y1601" N

什么任何想法是造成这一点,我怎么能纠正呢?我已经尝试设置使用的编码

content.Response.ContentEncoding=Encoding.Utf8

我和我的经历,并尝试了所有的其他编码的尝试正确设置。

====== UPDATE ======针对Marc的问题,我已经采取了应对有效载荷的Base64编码字符串,并且从第一源的响应,一旦我转发给他人不响应匹配。

从mbta.com响应(限于前几个字符):Cg0KAzIuMBAAGI / e8eIFEl0KBXkwNzIzIlQKHAoIMzkyNTAwNjcqAjg4MAAaCDIwMTkwMjA3IABCDg

从我的服务响应(仅限于前几个字符):CgsKAzIuMBiP3vHiBRJXCgV5MDcyMyJOChgKCDM5MjUwMDY3GggyMDE5MDIwNyoCODgSFA3skilCFQ

正如你所看到的,它们是不同的。我会努力寻找解决方案,我可以上传演示问题。再次感谢你!

c# protobuf-net gtfs
2个回答
1
投票

我想我已经能够拿出一个解决方案。

我的网页代码变成如下:

    public void ProcessRequest(HttpContext context)
    {
        context.Response.Clear();
        context.Response.Buffer = true;
        context.Response.AddHeader("content-disposition", "attachment;filename=VehiclePositions.pb");
        context.Response.ContentType = "application/x-protobuf";
        WebRequest req = HttpWebRequest.Create("https://cdn.mbta.com/realtime/VehiclePositions.pb");
        FeedMessage feed = Serializer.Deserialize<FeedMessage>(req.GetResponse().GetResponseStream());
        using (MemoryStream ms = new MemoryStream())
        {
            Serializer.Serialize(ms, feed);
            context.Response.BinaryWrite(ms.ToArray());
            context.Response.End();
        }
    }

不知道这是相关或不相关的,但因为我调试我注意到,有时要求会打不中的Web服务。删除认证,现在可以对该消息进行解码。我相信这是以前的工作,因为我是通过网络的单步执行代码,但它是一个需要注意的。再次感谢您马克!


0
投票

如果你不看二元什么反应看起来像小提琴手变得棘手;在这里你最好的办法是看HexView选项卡;一切都在绿色的头;一切都在黑色的有效载荷。

使用你原来的https://cdn.mbta.com/realtime/VehiclePositions.pb的网址,我注意到,这是〜26K,但与66591个有效载荷字节,使用gzip内部;所以你需要确保你接受提琴手的报价进行解码,首先 - 然后我在提琴手“复制为基础-64”(只是有效载荷,而不是头,在HexView标签),并运行它通过https://protogen.marcgravell.com/decode (使用碱-64选择),并且它通过解析到结束。

所以:我的建议是:

  • 做了类似的请求到您的处理
  • 检查长度 - 是66K?或26K?或者是其他东西?如果是26K,是它标记为gzip压缩?
  • 当复制为每个有效载荷基-64(gzip的解码,如果必要的话):是基-64相同的?
  • 是什么https://protogen.marcgravell.com/decode说的基础-64从你的处理器?它接受它,并通过解析结束了吗?

这会帮助你找出问题所在;或者帮我跟你识别它。

© www.soinside.com 2019 - 2024. All rights reserved.