如何解决“路径中包含非法字符”仅在通过移动浏览器查看时
我正在使用传统的WebAPI控制器:
- if: github.repository_owner == 'owner_name'
[Route("api/results/{query}")]
[AcceptVerbs("GET")]
public HttpResponseMessage GetQueryResults(string query)
{
var userAgent = Request.Headers.UserAgent;
var result = _fooService.GetResults(GetUsername(),query);
var response = Request.CreateResponse(HttpStatusCode.OK,result);
return response;
}
返回一个看起来像这样的元素数组:
GetResults
在大多数浏览器上,这都可以正常工作。我的用户代理标头如下所示:
[{
"resultId":2039016,"text":null,"dateCreated":"2020-09-10T02:24:36.003","targetPlatform":"FooBar"
}]
但是,当我使用设备工具栏从Chrome调试时,或者当我在iPhone上的Safari中访问网站时,用户代理会更改。在Chrome的设备工具栏(移动模拟器)中,看起来像这样:
{Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/84.0.4147.125 Safari/537.36}
在这种情况下,{Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/84.0.4147.125 Mobile Safari/537.36}
被调用并针对JSON失败:
“ type”:“ System.ArgumentException”, ↵“消息”:“路径中的非法字符。”, ↵“ stackTrace”:“在 System.IO.Path.GetIntension(字符串路径)\ r \ n上的System.IO.Path.CheckInvalidpathChars(字符串路径,布尔值checkAdditional)\ r \ n 在System.Web.WebPages.DefaultdisplayMode.TransformPath(String virtualPath,字符串后缀)\ r \ n位于 System.Web.WebPages.DefaultdisplayMode.GetdisplayInfo(HttpContextBase httpContext,字符串virtualPath,函数
CheckInvalidpathChars
2 virtualPathExists, IdisplayMode currentdisplayMode,布尔值 requireConsistentdisplayMode)\ r \ n位于 System.Web.WebPages.WebPageRoute.GetRouteLevelMatch(字符串pathValue, String [] supportExtensions,Func2 virtualPathExists)\r\n at System.Web.WebPages.displayModeProvider.GetdisplayInfoForVirtualPath(String virtualPath,HttpContextBase httpContext,Func
2个virtualPathExists, HttpContextBase上下文,displayModeProvider displayModes)\ r \ n位于 System.Web.WebPages.WebPageRoute.DoPostResolveRequestCache(HttpContextBase 上下文)\ r \ n System.Web.WebPages.WebPageHttpModule.OnApplicationPostResolveRequestCache(对象 发送者,EventArgs e)\ r \ n位于 System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()\ r \ n 在System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep步骤)\ r \ n 在System.Web.HttpApplication.ExecuteStep(IExecutionStep步骤, 布尔值和完成同步)“
我可以通过尝试将序列化的JSON解析为文件路径来手动重现此内容:
2 virtualPathExists,HttpContextBase context,displayModeProvider displayModeProvider)\r\n at System.Web.WebPages.WebPageRoute.MatchRequest(String pathValue,String[] supportedExtensions,Func
但是,当然,尝试将序列化的JSON对象解析为文件会引发错误。为什么ASP.NET会根据用户代理标头修改解析行为?
我可以以某种方式覆盖 try
{
var isValid = System.IO.Path.GetExtension(jsonString);
}
catch (Exception e)
{
throw e;
}
的入站标头来强制框架实现功能行为吗?
要明确-我可以从Chrome(标准)中调用控制器,而不会出现任何问题。当我从Chrome发出完全相同的请求来调用控制器时(打开devtools并激活了移动模拟器),将引发异常。同样,当我用来自iPhone上Safari的完全相同的请求调用它时,将引发异常。在这种情况下,用户代理标头是自变量-因此必须遵循该标头以某种方式导致被调用的不同执行路径。对吧?
在执行所有Controller逻辑后会引发异常-引发Request
时,控制器将返回它。
解决方法
正如@Dipen Shah所指出的,解决方案在另一个post中。
为什么ASP.NET会基于用户代理标头修改解析行为?
ASP.NET应用程序(reference)中有一个WebPageHttpModule
自动注册。在内部,WebPageHttpModule
尝试根据显示模式路由请求。
// NOTE: Excluded unnecessary code
public sealed class DisplayModeProvider
{
public static readonly string MobileDisplayModeId = "Mobile";
private readonly List<IDisplayMode> _displayModes = new List<IDisplayMode>()
{
(IDisplayMode) new DefaultDisplayMode(DisplayModeProvider.MobileDisplayModeId)
{
ContextCondition = (Func<HttpContextBase,bool>) (context => context.GetOverriddenBrowser().IsMobileDevice)
},(IDisplayMode) new DefaultDisplayMode()
};
public IList<IDisplayMode> Modes
{
get
{
return (IList<IDisplayMode>) this._displayModes;
}
}
}
您可以在此处看到字符串Mobile
,并根据IsMobileDevice
(reference)检查条件。因此,上述post中的解决方案才有意义。一旦知道了它在内部的工作原理,就可以执行以下 hack
public static void RegisterDisplayModes()
{
var displayModes = DisplayModeProvider.Instance.Modes;
var mobileDisplayMode = displayModes.FirstOrDefault(d => d.DisplayModeId == DisplayModeProvider.MobileDisplayModeId);
if (mobileDisplayMode != null)
{
displayModes.Remove(mobileDisplayMode);
}
}
请注意,这是基于位于System.Web.WebPages.dll
的反编译的C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v2.0\Assemblies\
。
假设我完全理解您的问题,我使用Asp.net Core可以找到下面的代码和屏幕截图。
sage: x = sqrt(2)
sage: x
sqrt(2)
sage: x.n()
1.41421356237310
- 这是vscode的图像截图
- 这是使用chrome移动响应的屏幕截图
- 这是使用chrome web或桌面视图的屏幕截图
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。