Internet explorer 11 detection on server side - asp.net

We all know that IE11 detection does not work with server side languages because Microsoft has removed the IE/MSIE browser indication and now is fully "Mozilla".
I also know that doing browser detection/version is risky but has served us all well in the past.
some requirements for a website are things like:
must work with certain version of firefox and above
must work with certain version of chrome and above
must work with certain version of safari's (some below and some newer)
must work with IE >= 8
so here is the problem... IE11 indicates on my list that it is not supported. I want to support it from the web side of things on the server (ASP.NET/MVC)
it is not clear exactly how to detect this from the server side. Does anyone know how?
this is the user agent now being shown in IE 11:
"Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"
rv:11.0 tells us its IE11 however doing a parse on that will still mean that for example, it could be chrome of a certain version that is not supported in such a requirement or even firefox.
so, what is the best way here to see if it is indeed IE 11 or higher?
I am not so sure about searching from "Trident" and onwards because I don't know if other browsers use that or not.
any direction is welcomed.

Use a Regular Expression like:
Regex.IsMatch(this.Request.UserAgent, #"Trident/7.*rv:11")
Trident is the name of the rendering engine IE uses. Some other applications also use the Trident engine, as you can see in the Wikipedia article. But it shouldn't be a problem to search for Trident in the User Agent, since no other major browsers use Trident.
Only IE11 uses Trident version 7 so if you search for Trident/7 with the regex, it should find IE11.

To maintain compatibility with existing code, I created a custom provider so Request.Browser will return the information as expected. For example, Browser.Browser will be "IE" not "InternetExplorer", which is the new value after the hotfix is installed.
Additionally, this approach returns the actual version of IE, not version 7 when in compatibility view. Note that Browser.Type will return "IE7" when in compatibility view in case you need to detect it, or you could easily modify the custom provider to change .Type as well.
The approach is simple. Derive a class from HttpCapabilitiesDefaultProvider and set BrowserCapabilitiesProvider to an instance of your class.
In Global.asax.cs:
protected void Application_Start(Object sender, EventArgs e)
{
...
HttpCapabilitiesBase.BrowserCapabilitiesProvider = new CustomerHttpCapabilitiesProvider();
...
}
Define your class: UPDATED TO INCLUDE MICROSOFT EDGE BROWSER
public class CustomerHttpCapabilitiesProvider : HttpCapabilitiesDefaultProvider
{
public override HttpBrowserCapabilities GetBrowserCapabilities(HttpRequest request)
{
HttpBrowserCapabilities browser = base.GetBrowserCapabilities(request);
// Correct for IE 11, which presents itself as Mozilla version 0.0
string ua = request.UserAgent;
// Ensure IE by checking for Trident
// Reports the real IE version, not the compatibility view version.
if (!string.IsNullOrEmpty(ua))
{
if (ua.Contains(#"Trident"))
{
if (!browser.IsBrowser(#"IE"))
{
browser.AddBrowser(#"ie");
browser.AddBrowser(#"ie6plus");
browser.AddBrowser(#"ie10plus");
}
IDictionary caps = browser.Capabilities;
caps[#"Browser"] = #"IE";
// Determine browser version
bool ok = false;
string majorVersion = null; // convertable to int
string minorVersion = null; // convertable to double
Match m = Regex.Match(ua, #"rv:(\d+)\.(\d+)");
if (m.Success)
{
ok = true;
majorVersion = m.Groups[1].Value;
minorVersion = m.Groups[2].Value; // typically 0
}
else
{
m = Regex.Match(ua, #"Trident/(\d+)\.(\d+)");
if (m.Success)
{
int v;
ok = int.TryParse(m.Groups[1].Value, out v);
if (ok)
{
v += 4; // Trident/7 = IE 11, Trident/6 = IE 10, Trident/5 = IE 9, and Trident/4 = IE 8
majorVersion = v.ToString(#"d");
minorVersion = m.Groups[2].Value; // typically 0
}
}
}
if (ok)
{
caps[#"MajorVersion"] = majorVersion;
caps[#"MinorVersion"] = minorVersion;
caps[#"Version"] = String.Format(#"{0}.{1}", majorVersion, minorVersion);
}
}
else if (ua.Contains(#"Edge"))
{
if (!browser.IsBrowser(#"Edge"))
{
browser.AddBrowser(#"edge");
}
IDictionary caps = browser.Capabilities;
caps[#"Browser"] = #"Edge";
// Determine browser version
Match m = Regex.Match(ua, #"Edge/(\d+)\.(\d+)");
if (m.Success)
{
string majorVersion = m.Groups[1].Value;
string minorVersion = m.Groups[2].Value;
caps[#"MajorVersion"] = majorVersion;
caps[#"MinorVersion"] = minorVersion;
caps[#"Version"] = String.Format(#"{0}.{1}", majorVersion, minorVersion);
}
}
}
return browser;
}
}

I solved this by using the Regex below after having a knock out system to check what browser is being used to access the site.
in this case, even if the browser "IE" is checked and returns false, I go ahead and use this regex and check to see if it is a match against the user agent:
(?:\b(MS)?IE\s+|\bTrident\/7\.0;.*\s+rv:)(\d+)
I hope this helps someone. I tested it and works fine. I also changed the rv to be 12 and upwards, and it works fine too in case if in IE12, they change rv to be 12.

public ActionResult Index()
{
var browser = this.Request.Browser;
System.Diagnostics.Trace.WriteLine(browser.Browser); // InternetExplorer
System.Diagnostics.Trace.WriteLine(browser.MajorVersion); // 11
return View();
}
Please note that you need .NET 4.5 or .NET 4.0 with http://support.microsoft.com/kb/2836939/en-us installed to correctly detect IE11.

It does sound like you are whitelisting browsers, which is not a good idea. You really need to do client-side detection of capabilities instead, generally. MVC really does not know what browser it is, the Request.Browser object can give you some idea, but that is not really reliable, which is the case for IE 11. It tells me version 11 on my dev machine, but 7 on my server, which can be a catastrophic mistake.
I build Single Page Applications and have adopted a similar attitude as Google about only supporting the current and previous version of a browser only. When I detect an outdated browser I server a 'core' site that is just some basic CSS and markup, no JavaScript. It is just easier that way, makes development so much easier.
Anyway the way I detect is to test for the current versions of IE like so:
public static bool IsModernIE() {
return HttpContext.Current.Request.Browser.Browser == "InternetExplorer";
}
It is an HTML helper method. So in your cshtml you can use the test. In my controller I call the individual version tests. This is ultimately a very fragile way to do it. I am basically drawing a line in the sand between modern IE (10/11) and old IE (9-). This test could be irrelevant with the next version and I have not tested against say Xbox One yet.
I have a library I use, posted on GitHub. I would call it usable Alpha right now, so take it for that and run with it if you like. I want to make the tests more externally configurable, etc. here is the URL for the repository, https://github.com/docluv/SPAHelper. I actually use it on my Blog, http://love2dev.com.

Related

Detect default android browser by Wurfl

I want to detect default browser of android inside my MVC controller.
I have mobile detection right now:
public ActionResult Index()
{
if (WurflHelper.Instance.IsMobile(Request.UserAgent))
{
return View("MobileView");
}
else
{
return View();
}
}
How can i detect android default browser (not chrome). I need UserAgent parameters matches for this detection.
Thanks for advice.
--------------EDIT--------------------------------------------------------------
i found this solution for client (javascript) : How to detect the stock Android browser. I need same solution for asp.net MVC
I noticed that you are already using WURFL to detect the device. You could simply use the mobile_browser or advertised_mobile_browser capability to determine the browser of the device.
You can use this Request.Browser to get the browser info. Below is an example
var moo = Request.Browser;
var Name = moo.Browser;
var Version = moo.Version;
var Major_Version = moo.MajorVersion;
var Minor_Version = moo.MinorVersion;

Session doesn't work in IE, it works in all other browsers

I'm developing a website with asp.net, visual studio 2012, IIS8, .Net Framework 4.
I use SESSIONS to store user information after login.
when user click sign in button, I send information to .ashx file like this:
var url = "SignIn.ashx?username=" + UserName.value + "&password=" + PassWord.value;
xmlRequest_SignIn.open("GET", url);
xmlRequest_SignIn.onreadystatechange = function () { ApplyUpdateSignIn() }
xmlRequest_SignIn.send(null);
SignIn.ashx:
... // check login information and then
HttpContext.Current.Session["UserName"] = username.toString();
...
Now in every page of my website, I check this session to authenticate the user in ajax:
var url = "CheckMemberAccount.ashx";
xmlRequest_member.open("GET", url);
xmlRequest_member.onreadystatechange = function () { ApplyUpdateGetMemberAccount() }
xmlRequest_member.send(null);
CheckMemberAccount.ashx:
if (Convert.ToString(HttpContext.Current.Session["UserName"]) == "" || null == HttpContext.Current.Session["UserName"])
{
// user not logged in
}
else
{
// user logged in
}
For log out I use ajax too:
var url = "SignOut.ashx";
xmlRequest_SignOut.open(GET, url);
xmlRequest_SignOut.onreadystatechange = function () { ApplyUpdateSignOut() }
xmlRequest_SignOut.send(null);
SignOut.ashx:
// I try everything to make the session null or invalid!
// BUT it doesn't take effect in Internet Explorer !!
HttpContext.Current.Session["UserName"] = "";
HttpContext.Current.Session["UserName"] = null;
HttpContext.Current.Session.Clear();
HttpContext.Current.Session.RemoveAll();
HttpContext.Current.Session.Abandon();
HttpContext.Current.Request.Cookies["ASP.NET_SessionId"].Value = "";
As you can see I've tried everything to make session null or invalid.
This code works well in all browsers(Chrome, FireFox, Safari, Opera, Netscape, ...) EXCEPT in Internet Explorer !
In IE after Signing out, when I check the member acount with CheckMemberAccount.ashx file, the session still remain valid with valid value as if no sign out happened !
This problem is only in IE !!
note that IE settings are all in their defaults.
I have tried Global.asax:
After adding the class, and without adding any code to it ( just keep it unchanged with it's default functions such as Session_Start() ), My problem changed and now I always get null for the session in CheckMemberAccount.ashx ! and again the problem is just in IE !
I didn't find any solution after 3 days.
I'll appreciate any help :)
I believe the checkmemberaccount call is being cached in the browser by iE. this has gotten me in trouble many times before. Add a random variable to your Ajax call and I believe your problem will be solved.
You can verify this by using a tool like fiddler. You should see that the browser is caching the GET request. You could also switch from a GET to a POST. POSTS are not cached by IE.
By the way... You should fix this for any get requests that you don't want to cache.

Microsoft Speech Recognition in webservices is not returning the result

Well i'm using Microsoft Speech Platform SDK 10.2.
I made a asp.Net WebService application and most of the WebServices works fine (HelloWorld(), etc...), but I have one service that uses the SpeechRecognitionEngine and when I deploy the application and try to run this webservice I get no result, i.e, I can see through the debug mode that it reaches the return line, but when I call it trought the browser the page keeps loading for ever, without any response.
Here's a sample of the code:
[WebMethod]
public bool voiceRecognition() {
SpeechRecognitionEngine sre = new SpeechRecognitionEngine(new System.Globalization.CultureInfo("pt-PT"));
Choices c = new Choices();
c.Add("test");
GrammarBuilder gb = new GrammarBuilder();
gb.Append(c);
Grammar g = new Grammar(gb);
sre.LoadGrammar(g);
sre.InitialSilenceTimeout = TimeSpan.FromSeconds(5);
//// just for Testing
RecognitionResult result = null;
if (result != null) {
return true;
} else {
return false;
}
}
Note: I'm using IIS to deploy the WebService Application.
If someone have some thoughts please let me know.
I don't know if you've found your answer or not. When trying to solve this myself a couple of days ago, I stumbled across your question and it matched our circumstances to a "T".
In order to fix it all we had to do was put...
sre.RecognizeAsyncStop();
sre.Dispose();
where "sre" is your SpeechRecognitionEngine variable. If you don't stop it and dispose of it at the end of your web service then the web service won't return.
Hope this helps. :)

EAFlashUpload with ASP.NET 4.0 failes in Firefox, Chrome but works in IE

I'm using EAFlashUpload component with ASP.NET 4.0 on my site to allow for multiple file uploads (select multiple files at a time).
The component works great and with no issues with IE (7, 8, 9), but with Firefox or Chrome, it gives an "unknown http error" after a file is uploaded (when it is trying to do postback to the server, I think).
I'm running this under IIS7 on Windows 2008 Server R2, but I don't think the version of IIS or Windows is the significant factor.
This is the client side Javascript to handle the component:
<script type="text/javascript">
var params = { BGcolor: "#ffffff", wmode: "window" };
var attributes = { id: "EAFlashUpload", name: "EAFlashUpload" };
var flashvars = new Object();
var uploadUrl = "Pages/SendAdvanced.aspx";
//if (!document.all) {
// uploadUrl = "../" + uploadUrl;
//}
flashvars["uploader.uploadUrl"] = uploadUrl;
flashvars["viewFile"] = "EAFUpload/TableView.swf";
flashvars["view.removeButton.visible"] = "false";
flashvars["view.clearButton.visible"] = "false";
flashvars["queue.filesCountLimit"] = "10";
flashvars["queue.fileSizeLimit"] = "2147483648"; // 2 gigabytes = 2147483648 bytes
swfobject.embedSWF("EAFUpload/EAFUpload.swf", "EAFlashUpload_holder", "650", "380", "10.0.0", "EAFUpload/expressInstall.swf", flashvars, params, attributes);
function EAFlashUpload_onMovieLoad(errors) { if (errors != "") alert(errors); }
</script>
EDIT:
I discovered after further testing that the Flash component is throwing error #2038, which is a generic catchall error for "cannot connect to the server". Not sure why this is an issue with Chrome and FF, but this warrants additional investigation...
I found the answer, and it is absolutely NOT what I was expecting.
This line of code was the issue:
var uploadUrl = "Pages/SendAdvanced.aspx";
That line is a relative path, set in client side Javascript and used by the Flash component to know where to post the content.
When I changed it to this, it worked:
var uploadUrl = "http://www.mysite.com/Pages/SendAdvanced.aspx";
What I would love for someone to tell me is WHY the first line of code EVER works? Why does it work in Internet Explorer? Is there something special it is able to do to track relative paths, that the other browsers (and the Mac) won't do?
I found this answer when I was experiencing similar issues with the flash uploader (the uploads would fail before even connecting to the server). Using the following example code:
var uploadUrl = location.href;
if (!document.all) {
uploadUrl = "../" + uploadUrl;
}
//alert(uploadUrl);
var flashvars = new Object();
flashvars["uploader.uploadUrl"] = uploadUrl;
...
Turns out the problem only occurred with URLs that had a & and/or # in them (the flash object was receiving these and not knowing what to do with them because they were not encoded). There are more characters than these to worry about, however, in my case, this ended up solving the issue
I simply replaced the ampersands with the encoded version that flash was expecting, and removed the hash pound and everything following it (because it is useless from a server's perspective).
uploadUrl = uploadUrl.replace(/\&/g, '%26');
uploadUrl = uploadUrl.replace(/#.*/g, '');

Firefox does not deliver pdf if it is handled by http-handler and inside iframe

I have a site that runs on IIS7 ASP.NET 3.5
I implemented a http-handler that serverves pdf.
If I request a pdf-document (www.mysite.com/mypdf.ashx?id=doc1) in Firefox 3.0 I get the result in the browser.
I now have an iframe on my page. The src - attribute is set to www.mysite.com/mypdf.ashx?id=doc1.
The document is displayed in IE7 but in Firefox I only get scrambled text.
Is this posssible in Firefox?
I found this post PDF streaming in IFRAME not working in Firefox
Anybody tried this solution with modrewrite? The post is a couple of years old and there was no modrewrite for IIS7 then.
I do that in asp.net mvc and it works fine on IE6, IE7 and Firefox 3.5.3
Here is my code :
Html code :
<div id="ProductDetailsModal">
<iframe src="<%= Url.Content("~/GetPdf.axd?id=" + ViewData["ProductId"] + "&type=" + ViewData["ContentType"]) %>" width="100%" height="98%"></iframe>
</div>
And here the HttpHandler Code :
public void ProcessRequest(HttpContext context)
{
if (!String.IsNullOrEmpty(context.Request.Params["Id"]) && !String.IsNullOrEmpty(context.Request.Params["Type"]))
{
IProductBusiness productBusiness = new ProductBusiness();
var username = context.Session["Username"] as String;
var password = context.Session["Password"] as String;
var id = context.Request.Params["Id"].ToInt();
var type = context.Request.Params["Type"];
if (id != 0 && !String.IsNullOrEmpty(type))
{
var pc = productBusiness.GetProductContent(username, password, id, type, string.Empty);
if (!String.IsNullOrEmpty(pc.Name) && !String.IsNullOrEmpty(pc.Extension) && pc.Extension.ToLower() == "pdf")
{
var len = pc.File.Length;
byte[] output = Convert.FromBase64String(pc.File);
context.Response.Clear();
context.Response.ContentType = "application/pdf";
context.Response.AddHeader("Content-Disposition", String.Format("FileName=\"{0}\"", pc.Name));
context.Response.AddHeader("content-length", output.Length.ToString());
context.Response.Cache.SetCacheability(HttpCacheability.Private);
context.Response.Expires = -1;
context.Response.Buffer = true;
context.Response.BinaryWrite(output);
context.Response.End();
}
else
{
context.Response.Write("Erreur lors du chargement du fichier.");
}
context.Response.Clear();
}
}
}
Hope this helps.
There was no mod_rewrite for IIS 6 either. It is an Apache only process. There are alternatives like IIS 7 Rewriter Module or Managed Fusion URL Rewriter.
Are you setting the ContentType for the Response? IE is pretty good at guessing what a document is; firefox relies on being told.
You'll want to set the ContentType to "application/pdf"
Serving PDFs with an http handler is tricky business. There are so many different ways of loading and reading a pdf. Different versions of Adobe Acrobat Reader behave different as well.
Sometimes it tries to be clever and see if it can use partial requests (206). So you can see the first page before its finished downloading the entire document. You probably want to also set the correct cache headers, as that will save you a lot of bandwidth.
I have been using this http handler to successfully serve pdfs without any problems. It takes cares of most of the hassles for you.
http://code.google.com/p/talifun-web/wiki/StaticFileHandler

Resources