SSRS2008 ASP.NET ServerReport fails on IE11 with OEM UserAgent - c#

I am rendering a SSRS ServerReport to PDF and in the ReportViewer WebForm Control in a ASP.NET 3.5 Application with a SQL Server Report Service 2008.
Some people using Internet Explorer 11 reported that they cannot open generated PDF files or see anything in the viewer.
The rendering fails with this error:
library!ReportServer_0-403!7c8!01/02/2014-11:07:37:: e ERROR: Throwing Microsoft.ReportingServices.Diagnostics.Utilities.InternalCatalogException: , Microsoft.ReportingServices.Diagnostics.Utilities.InternalCatalogException: Interner Fehler beim Berichtsserver. Weitere Informationen finden Sie im Fehlerprotokoll. ---> System.ArgumentNullException: Value cannot be null.
Parameter name: String
at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
at System.Web.Configuration.HttpCapabilitiesBase.get_MajorVersion()
at Microsoft.ReportingServices.Diagnostics.Utilities.BrowserDetectionUtility.GetBrowserInfoFromRequest(HttpRequest request)
at Microsoft.ReportingServices.Diagnostics.RSRequestParameters.SetBrowserCapabilities(HttpRequest request)
at Microsoft.ReportingServices.Library.RenderReportAction.SetBrowserCapabilities()
at Microsoft.ReportingServices.Library.RenderReportAction.PerformExecution()
at Microsoft.ReportingServices.Library.RenderReportAction.Render()
--- End of inner exception stack trace ---;
I could track these errors down to a OEM string used in the UserAgent of IE11.
Examples:
Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; MALC; rv:11.0) like Gecko
Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; MATM; rv:11.0) like Gecko
Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; NP06; rv:11.0) like Gecko
MALC, MATM and NP06 appear to be OEM strings and are not part of the usual IE11 UserAgent.
Removing these strings in IEs developer tools user agent settings makes everything work normally, but is not a solution for the end user.
Things I have tried:
Overriding the UserAgent of the incoming Request in the ASP.NET application, but it appeared to never change regardless what I was setting. (I might have done this wrong, all I found was that I cannot change it so I tried anyway)
Override the header at the Begin-/EndRequest event in the Global.asax
Adding a custom .browser file in the App_Browser directory of the application itself and on the SSRS Server Application
What does work:
Intercepting the request and making a custom Request using HttpWebRequest with a different UserAgent, copying cookies (session id) and request/response headers back and forth.
I feel like this is a horrible solution and should not be done like this.
How can I make SSRS not throw an error while parsing IE11s UserAgent?
Is there a way to disable it or add a custom Regular Expression to parse it manually?

You can override the user agent to the report server by supplying additional device information.
This can be done when calling the Render method of the SOAP API by supplying this XML fragment as a parameter
<DeviceInfo>
<UserAgent>custom_user_agent_here</UserAgent>
</DeviceInfo>
Or using URL access like this
http://<Server Name>/reportserver?/SampleReports/Sales Order Detail&rs:Command=Render&rs:Format=HTML4.0&rc:UserAgent=custom_user_agent_here
.
References
Reporting Services Device Information Settings
http://msdn.microsoft.com/en-us/library/ms155397(v=sql.110).aspx
HTML Device Information Settings
http://msdn.microsoft.com/en-us/library/ms155395(v=sql.110).aspx

Related

Downloading a pdf in .NET 3.5 vs .NET 4.6 using C#

I have a third party server url that opens a pdf file in browser. Before one can access the pdf, request must be authenticated, so authentication information is integrated in the url. So It takes the form like:
SERVER_IP:/runReport.jsp?&jrs.cmd=jrs.get_subnodes&jrs.authorization=YWRtaW46YWRtaW4=&jrs.report_sheet$Report=true&jrs.catalog=/cata/catafolder/cataname.cat&jrs.report=/cata/catafolder/container.cls&jrs.result_type=2&jrs.profile=myProfile&jrs.param$InputAD;1_#assignmentId=AD0000695585
jrs.authorization=YWRtaW46YWRtaW4=
is authorization information attached to the URL. I developed two pieces of code.
The one in .NET 4.6 is:
HttpClient client = new HttpClient();
string param= "someparamvalue";
string url = UrlBuilder(param);
HttpResponseMessage message = client.GetAsync(url).Result;
HttpContent content = message.Content;
System.IO.Stream stream = content.ReadAsStreamAsync().Result;
FileStream fs = File.Create($"exported\\{param}.pdf");
stream.CopyTo(fs);
fs.Close();
stream.Close();
And it successfully downloads the pdf in the "exported" folder.
We have a restriction to do it in .NET 3.5 (.NET 4+ cannot be installed immediately on the machine), so I tried it with following code in 3.5:
string param= "someparamvalue";
string url = UrlBuilder(param);
string fileName = $"exported\\{param}.pdf";
WebClient wc = new WebClient();
wc.Headers.Add(HttpRequestHeader.UserAgent, "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36");
wc.Headers.Add(HttpRequestHeader.Accept, "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
wc.DownloadFile(url, fileName);
but all it downloads, is a pdf that is 1) Cannot be opened with pdf reader (A message appears that says "File is either not supporte or corrupted...") 2) I can still open the downloaded file in "Notepad++", I see the html for login web page. (So even if authorization information is there in URL, it still didn't authenticate the user)
Anything, I am missing on how these 2 pieces of code work differently for same request? What wrong I am doing with 3.5 code ?

How can I access Whatsapp Web from WebBrowser Control?

Im trying to access Whatsapp Web from my desktop application using a WebBrowser Control, but a message popups, recommending me to use Chrome, Firefox, etc..
How can I avoid this message and get the QR Code? I tried changing the User-Agent this way:
[DllImport("urlmon.dll", CharSet = CharSet.Ansi)]
private static extern int UrlMkSetSessionOption(int dwOption, string pBuffer, int dwBufferLength, int dwReserved);
const int URLMON_OPTION_USERAGENT = 0x10000001;
private void Form1_Load(object sender, EventArgs e)
{
string userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36";
UrlMkSetSessionOption(URLMON_OPTION_USERAGENT, userAgent, userAgent.Length, 0);
}
But it didn't work. I mean, it changed the User-Agent, but I'm still getting the same message.
I check current User-Agent using this web: http://www.whoishostingthis.com/tools/user-agent/
What can I do? Thanks in advice!
The native WebBrowser control is based on Internet Explorer, which, when embedded, runs in IE7 compatibility mode by Default.
IE is used regardless of the default browser on your system.
Whatsapp Web seems to support no version of IE, so it makes no sense to alter the compatibility mode of the WebBrowser control.
Instead, you should consider using a different browser control, like Chromium.
There are a lot of resources on the web about how to integrate Chromium into a .Net application.

Spellcheck in web browser control not working under IE11 emulation

I am trying to have spellcheck work in a Winforms web browser control.
This is my current C# code:
try
{
String appname = Process.GetCurrentProcess().ProcessName + ".exe";
RegistryKey key = Registry.LocalMachine.OpenSubKey("Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION", RegistryKeyPermissionCheck.ReadWriteSubTree);
object ieVal = key.GetValue(appname, null);
MessageBox.Show(ieVal.ToString());
if (ieVal == null || (int)ieVal != 11001)
{
key.SetValue(appname, 11001, RegistryValueKind.DWord);
}
key.Close();
}
catch
{
MessageBox.Show("Registry stuff didn't work");
}
MessageBox.Show(webBrowser1.Version.ToString());
webBrowser1.DocumentText = "<html><head><body><div spellcheck=\"true\" style=\"width:100%; height:100%;\" contenteditable=\"true\"></div>"
+"<script>alert(navigator.userAgent);</script>"
+"</body></html>";
So first I set the proper registry key so that the browser emulates IE11
Then I add a div tag with spellcheck attribute set to true.
The version that the MessageBox.Show(webBrowser1.Version.ToString()) shows is:
11.0.9600.18525
The navigator.userAgent that the Javascript displays is:
Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko
So it seems like the web browser control is using IE11. But when I type the spell check doesn't work.
Note: When I run that html code with the real IE everything works properly.
Also, the navigator.userAgent displayed on the actual browser is:
Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; rv:11.0) like Gecko
Note2: When I run my application on Windows 10 machine the spellcheck works. But I need to make it work on Windows 7 machines.
I had very similar problems using a WebBrowser control on a form and found 2 solutions, each with differing effects, which could both be used.
Using spellcheck=true in the HTML:
Adding the attribute spellcheck=true to the HTML or BODY or TEXTAREA tags, depending on where you want it implemented, will allow spelling checking on text input boxes (my tests were on Windows 10).
Note that any EXISTING text in the text boxes was not spell checked - you had to type NEW text in. This caught me out when running test EXEs with a pre-filled text box, which never got the little red underlines on its spelling mistakes.
Registry entry for FEATURE_SPELLCHECK
This did something different. It allowed spell checking in TinyMCE to work in our embedded web browser control. On its own, it did not enable spell checking in text areas.
See the link below for references to a registry key close to the one you were setting. However, it requires a new key and then a value that matches the name of the EXE you're running. In my case, this involved creating the FEATURE_SPELLCHECKING registry key, and then a DWORD with name TEST123.EXE and value 1.
https://msdn.microsoft.com/en-us/library/ee330735%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396#spellchecking
I found this through the page linked below, where someone reports it not working for Windows 7. Note that this person also tries it with a "local user" key, which does not work in my experience:
https://social.msdn.microsoft.com/Forums/ie/en-US/515fa4b1-2b85-46e4-a041-7dc27c4539c4/how-to-enable-spell-checker-in-web-browser-control-for-ie10?forum=ieextensiondevelopment
Use both of the above.
We found that approach 2 above met most of our needs, as we were using TinyMCE. However, in other applications, both 1 and 2 can be used in conjunction to provide the most functionality.

Specified value has invalid HTTP characters with WebClient download

I have done a bit of research on this problem before. I had a look at this question and it didn't help me. Basically I am trying to build a program to help people use a website, and I need to get the recaptcha V2 challenge images from google's recaptcha API. I keep getting a
Specified value has invalid HTTP characters
when attempting to download the stream
try
{
WebClientEx wc = new WebClientEx(cookieJar);
wc.Headers.Add("Referer", recaptchaframe_url);
wc.Headers.Add("UserAgent:", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)");
Stream responsestream = wc.OpenRead("http://www.google.com" + challengeimageurl);
}
catch (Exception ex)
{
MessageBox.Show("This program was unable to download CAPTCHA image" + ex.Message);
}
I was able to get past this error by converting all manually set headers in the webclient to their .NET properties. (eg UserAgernt to HttpRequestHeader.UserAgent. It appears that it's useless to set header names manually.

Fixing a youtube downloader class

A Little time ago I opend a thread (link at the bottom).
And I'm happy to say it has been fixed, that is partially.
It still uses the wrong youtube links.
And since youtube keeps updating all examples i could find where broken.
I think this has to do with the "regular" expressions.
Could someone enlighten me on that subject?
And now for the error at hand:
An unhandled exception of type 'System.Net.WebException' occurred in System.dll
Additional information: The remote server returned an error: (403) Forbidden.
At Line 22: wc.DownloadFile(kvp.Value, #"C:\Users\waralot\Downloads\youtube\"+kvp.Key);
The console during compilation is here: pastebin.com/BrgKkAmk
Original project at HackForums: http://www.hackforums.net/showthread.php?tid=2052105
My current version: http://pastebin.com/2iH2vQ2L
Again my first thread can be found here: Converting a Youtube downloader form VB to C#
Seems like Youtube blocks you from accessing the link, this may because you don't set an user-agent for your WebClient.
Try adding this before you try to download the video.
wc.Headers.Add ("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)");
Code for url cleanup also needs to be changed like so.
//clean up residual tags and encoded strings
link = slink.Replace("url=", "");
link = link.Replace("\\u0026", "&");
link = HttpUtility.UrlDecode(link);

Categories

Resources