我正在使用ASP.NET WebForms,这意味着我将通过ASPX或ASHX页面发送Protobuf数据。
我正在尝试构建一个GTFSRT文件,为此它有一个名为GTFSRealTimeBindings的Nuget包。它使用Protobuf和Protobuf-net压缩并发送数据。
我遇到的问题是,在发送数据时,某些东西变得混乱,因此无法在接收端读取它,而且我不确定如何纠正它。我认为它在编码中,但是我没有设置它,所以我不确定如何更改它。
我最终要做的是编写一个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'
如果在点击该页面时运行Fiddler,我注意到从cdn.mbta.com获得的响应与该页面给出的响应是不同的(当然要减去标题)。
例如,fiddler中mbta.com的前两行显示:
2.0] y1601“ T
但是我回复的前两行是: 2.0瓦 y1601“ N
关于导致此问题的原因以及如何纠正的任何想法? 我尝试使用
设置编码content.Response.ContentEncoding=Encoding.Utf8
我和我经历了所有其他编码,以尝试正确设置它。
======更新====== 为了回答Marc的问题,我采用了响应有效负载的Base64字符串,并且一旦我继续转发,来自第一个源的响应就与该响应不匹配。
来自mbta.com的响应(限于前几个字符): Cg0KAzIuMBAAGI / e8eIFEl0KBXkwNzIzIlQKHAoIMzkyNTAwNjcqAjg4MAAaCDIwMTkwMjA3IABCDg
我的服务回复(限制为前几个字符): CgsKAzIuMBiP3vHiBRJXCgV5MDcyMyJOChgKCDM5MjUwMDY3GggyMDE5MDIwNyoCODgSFA3skilCFQ
如您所见,它们是不同的。我将研究一个可以上传以演示该问题的解决方案。再次谢谢你!
答案 0 :(得分:1)
我认为我已经能够提出解决方案。
我的Web代码变成了以下内容:
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服务。删除了身份验证,它现在可以解码消息。我相信这是可行的,就像我逐步浏览Web代码一样,但这是需要注意的事情。 再次谢谢你马克!
答案 1 :(得分:0)
如果您不看二进制文件,在提琴手中的响应看起来会很棘手。最好的选择是在HexView选项卡上查看;绿色的一切都是标题。黑色的一切都是有效载荷。
使用原始的https://cdn.mbta.com/realtime/VehiclePositions.pb
网址,我注意到这大约是26k,但是有效载荷字节为66591,内部使用gzip;因此,您需要确保先接受Fiddler的报价才能对其进行解码-然后我在Fiddler中进行了“ base-64复制”(仅在HexView标签中包含有效负载,而不是标头)并通过{ {3}}(使用base-64选项),并解析到最后。
所以:我的建议是:
这应该有助于您发现问题;或帮助我识别您的身份。