使用Razor读取XML网页时出现Bad Request 400错误的求助
400错误核心诱因
- 你的接口需要登录授权才能访问,浏览器访问时已经带了登录态的Cookie/凭证,但
WebClient发起的服务端请求没有携带任何身份信息,被接口拦截返回错误。 - 接口要求请求头携带特定标识,比如
Accept指定返回格式为XML,WebClient默认发起的请求没有对应头信息,不符合接口要求触发400。
现有代码错误点
- 你用
Html.Raw()包裹DownloadString的返回完全多余,Html.Raw是用来把字符串原样输出到前端视图的工具方法,你要解析XML直接用DownloadString返回的原始字符串即可。 - 返回的XML带有默认命名空间,直接用
node1["UserId"]无法匹配到节点,需要引入命名空间管理器才能正确解析。
优化建议
你是服务端调用本站点的接口,完全可以直接调用查询订单的业务逻辑代码获取OrderViewModel对象,不需要走HTTP请求,既能绕开身份验证问题,性能也比发起HTTP请求高得多。
修正后代码示例
@using System.Xml; @{ string CurrentURL = Request.Url.AbsoluteUri; } @if (CurrentURL.Contains("/a/ordercomplete/")) { string googleOrderID = CurrentURL.Substring(CurrentURL.IndexOf("/a/ordercomplete/") + 17); string CurrentWebsite = CurrentURL.Substring(0, CurrentURL.IndexOf("/a/ordercomplete/")); string googleUserID = ""; string googleOrderEmail = ""; string googleOrderCountry = ""; string googleOrderCountryCode = "US"; string errormessage = ""; try { string orderWebLink = CurrentWebsite + "/api/order/" + googleOrderID; using (System.Net.WebClient webClient = new System.Net.WebClient()) { // 新增Accept头,指定接受XML格式 webClient.Headers.Add("Accept", "application/xml"); // 携带当前用户的登录Cookie,适配需要登录的接口 webClient.Headers.Add(System.Net.HttpRequestHeader.Cookie, Request.Headers["Cookie"]); // 去掉多余的Html.Raw调用 string xmlContent = webClient.DownloadString(orderWebLink); XmlDocument order = new XmlDocument(); order.LoadXml(xmlContent); // 新增命名空间处理,适配XML的命名空间规则 XmlNamespaceManager nsmgr = new XmlNamespaceManager(order.NameTable); nsmgr.AddNamespace("ns", "http://schemas.datacontract.org/2004/07/NashWrap.Web.Models"); XmlNode userIdNode = order.SelectSingleNode("//ns:UserId", nsmgr); if (userIdNode != null) { googleUserID = userIdNode.InnerText; } } } catch (Exception e) { errormessage = e.ToString(); } @Html.Label("lblName", errormessage) <!-- GCR相关代码保持不变 --> <script src="https://apis.google.com/js/platform.js?onload=renderOptIn" async defer> </script> <script type="text/javascript"> window.renderOptIn = function () { window.gapi.load('surveyoptin', function () { window.gapi.surveyoptin.render( { "merchant_id": 6316095, "order_id": "@googleOrderID", "email": "@googleOrderEmail", "delivery_country": "@googleOrderCountryCode", "estimated_delivery_date": "2021-09-20", "opt_in_style": "OPT_IN_STYLE", "products": [{ "gtin": "123456789123" }, { "gtin": "123456789124" }] }); }); } </script> <script> window.___gcfg = { lang: 'en_US' }; </script> }
如果调整后仍有400错误,可对比浏览器发起请求和WebClient请求的头信息差异,把缺少的头字段补到WebClient的Headers集合中即可。
内容的提问来源于stack exchange,提问作者Dizy
相关产品推荐
相关产品推荐

