微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

“路径中包含非法字符”仅在通过移动浏览器查看时

如何解决“路径中包含非法字符”仅在通过移动浏览器查看时

我正在使用传统的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,Func 2 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,并根据IsMobileDevicereference)检查条件。因此,上述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的图像截图

enter image description here

  • 这是使用chrome移动响应的屏幕截图

enter image description here

  • 这是使用chrome web或桌面视图的屏幕截图

enter image description here

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。