将特定用户代理的别名添加到用户代理别名的内部集合中。
来自 <https://msdn.microsoft.com/zh-cn/library/6379d90d(v=vs.110).aspx>
用户代理别名的集合指示 ASP.NET 服务器控件应为其呈现内容的目标用户代理。其信息可以在Page.ClientTarget属性中获取,且仅为一个字符串,但在MVC中无法找到类似属性,故无法作任何试验或考证。
如果未设置 ClientTarget 属性,则与 Page.Request 属性关联的 HttpBrowserCapabilities 对象将反映客户端浏览器的功能。如果设置了此属性,则将禁用客户端浏览器检测,并且页将使用与提供的值(别名)关联的浏览器功能。
Web 服务器计算机中的根配置文件 (Web.config) 定义了四个默认别名,可以用作常用用户代理字符串的缩写:
- uplevel,指定等效于 Internet Explorer 6.0 的浏览器功能。
- downlevel,指定等效于不支持客户端脚本的较旧浏览器的浏览器功能。您可以使用此别名来确认网页在已禁用客户端脚本的浏览器中的工作方式。
可以使用此属性以编程方式设置别名字符串,也可以使用 指令的 ClientTarget 特性以声明方式设置该别名。
在应用程序级别的 Web.config 文件的 clientTarget 部分中,您可以定义其他的别名。
来自 <https://msdn.microsoft.com/zh-cn/library/system.web.ui.page.clienttarget(v=vs.110).aspx>
虽然无法考证,但按个人推测,clientTarget是按照User-Agent的匹配(应该不包含正则的匹配)得出浏览器的别名,从而立即确定浏览器类型,得出浏览器别名后直接用浏览器别名去获得浏览器功能定义,而不再进行browserCaps或者Browser的匹配。而ASP.NET MVC有可能不包含对clientTarget的使用,只局限于WebForm中使用。
在WebForm的Page类的ClientTarget是如下定义
这里的_request是密封类HttpRequest的字段,HttpRequest与HttpRequestBase没有继承关系。HttpRequest的ClientTarget定义如下所示
当设置了_clientTarget之后,browsercaps会被置null,这就有对应了上文中"如果设置了此属性,则将禁用客户端浏览器检测,并且页将使用与提供的值(别名)关联的浏览器功能 ",但是即便是对broswercaps置空了,但是在获取Browser属性时又会通过Factory对其进行赋值,赋值的结果则不是另外一个HttpBrowserCapabilities了。
试验是通过反射进行的
定义了clientTarget和browsercap
<clientTarget> <add alias="IE10" userAgent="Chrome/52.0.2743.116 Safari/537.36"/> </clientTarget> <browserCaps> <use var="HTTP_USER_AGENT"/> <filter> <case match="Chrome/52.0.2743.116 Safari/537.36"> cookies=false hopegi=mr.hopegi </case> </filter> </browserCaps>
HttpRequest request = System.Web.HttpContext.Current.Request; PropertyInfo propInfo = request.GetType().GetProperty("ClientTarget", BindingFlags.NonPublic | BindingFlags.Instance); propInfo.SetValue(request, "IE10", null); FieldInfo browserField=request.GetType().GetField("_browsercaps", BindingFlags.NonPublic | BindingFlags.Instance); object bVal = browserField.GetValue(request);
注意一下这里用的是System.Web.HttpContex,而并不是MVC里面的HttpContext属性,感觉微软在这里弄得有点挫HttpContextBase和HttpContext。
没设值前是Chorme
设值完毕后,_browser属性被置空了
此时再次获取Browser属性重新计算,得出的结果不再是Chorme。失败的是,这里只能把Browser的类型弄成Unknown,而弄不到其他浏览器类型。