Page 1 of 2 in the ASPNet category Next Page
# Thursday, 05 December 2013

When Internet Explorer 10 launched, it caused some problems with the antiquated browser detection feature of ASP.Net, and thus you needed to make sure that you installed the right patches or performed the right fixes in order to get everything working properly. And I talk about the IE10 incident here on my blog.

And now Internet Explorer 11 has just been auto updated to many users, and again I was seeing problems with my websites. At a MUCH worse scale this time I might add, not only were scripts not being sent ASP.Net didn't think IE11 was capable of receiving cookies which just royally broke the website.

Sometimes your site might seem ok, but buttons are not working and everything that seems to be tied to Javascript seems to be malfunctioning, looking into the Javascript debug console you see something similar to this message :-

'__doPostBack' is undefined

or something like

'WebForm_DoPostBackWithOptions' is undefined.

Once again Scott Hanselman talks about the problem, and mentions the obvious solution of ensuring your server patches were up to date.

But I couldn't get my client's servers patched for some reason, so I hunkered down and tried to manually patch the browser definition file. At first I thought I could just insert the new version into the existing IE browser definition file like it was done for IE10 the last time. Then I actually saw the IE11 user agent string:-

Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko

The MSIE moniker which was used to identify Internet Explorer was DELIBRATELY removed, because IE11 is more than capable of handling HTML5 now and they didn't want any poorly coded Javascript library to incorrect identify IE11 as being an older, less HTML5 capable browser and tell users to use some other browser instead. Very good intentions I must say, too bad ASP.Net brefore 4.5 happens to be one of those legacy systems that do User Agent sniffing and because it didn't see anything it knew was defaulting IE11 to something which couldn't handle Javascript, Cookies, and many many other things.

At first I thought about writing a regular expression pattern which could parse the new User Agent and identify the browser properly. But there were 2 problems with that idea. The first was that I was CRAP at writing complex regular expressions, the second was the fact that why should I even bother with browser sniffing? Every damn browser supports Javascript now, and websites pretty much NEED Javascript anyway. So I set about to make it so that the default browser definition enabled all modern features.

I did so by overriding the default browser defintion at my web site level. First I created a app_browsers folder in the root of the web site, then I create a file called newdef.browser with the following content

UPDATE Jan 30th 2013 : You might not see changes right away when you drop the file in, you might want to try restarting the IIS web pool, if you can't do that, try toggling the compilation/debug attribute under system.web in the root web.config file by alternating it between true and false to restart it.

<?xml version="1.0" encoding="utf-8"?>
<browsers>
<browser refID="Default">
 <capabilities>
  <capability name="browser" value="Generic UpLevel" />         
            <capability name="type"                            value="Generic" />
            <capability name="ecmascriptversion"               value="3.0" />
            <capability name="javascript"                      value="true" />
            <capability name="javascriptversion"               value="1.7" />
            <capability name="w3cdomversion"                   value="1.0" />
            <capability name="supportsAccesskeyAttribute"      value="true" />
            <capability name="tagwriter"                       value="System.Web.UI.HtmlTextWriter" />
            <capability name="cookies"                         value="true" />
            <capability name="frames"                          value="true" />
            <capability name="javaapplets"                     value="true" />
            <capability name="supportsCallback"                value="true" />
            <capability name="supportsDivNoWrap"               value="false" />
            <capability name="supportsFileUpload"              value="true" />
            <capability name="supportsMaintainScrollPositionOnPostback" value="true" />
            <capability name="supportsMultilineTextBoxDisplay" value="true" />
            <capability name="supportsXmlHttp"                 value="true" />
            <capability name="tables"                          value="true" />
        </capabilities>
</browser>
</browsers>

What the file does is that it overrides the default browser definition of a crummy featureless browser to a more up to date one which supports all the cool stuff like cookies, Javascript, etc. etc. I basically just copied all the capability tags from the Chome browser definition file.

WARNING : If for some poor unfortunate reason that you actually RELY on ASP.Net's browser detection feature to detect ancient browsers this will effectively BREAK the function so do so at your own risk!


Thursday, 05 December 2013 23:29:33 (Malay Peninsula Standard Time, UTC+08:00)  #    Comments [0]  | 
# Sunday, 10 November 2013
A few years ago Microsoft introduced a new ASP.Net feature called ASP.Net Web Pages. I found the light use of control tags intriguing, but I didn't see any reason to use it instead of the standard ASP.Net Web Forms style of developing web sites. It also didn't help that Microsoft seemed like it was talking about Razor as a side component to be used with ASP.Net MVC another new feature which I wasn't too keen on. But recently as I sat down to take a look at Razor once more, it finally dawned on me what Razor is actually good for. So make yourself a drink and come back to the longest code snippet filled article ever written by me on this site!

Sunday, 10 November 2013 21:00:45 (Malay Peninsula Standard Time, UTC+08:00)  #    Comments [0]  | 
# Tuesday, 24 July 2012

As I was surfing around the web using my Windows 8 machine, I noticed a few problems with some of my websites. After poking around a bit I realized that the symptoms I was seeing were pretty much the same as the iOS Safari WebView problem I discovered previously. And sure enough... it's the browser capability files again. More info available on Scott Hanselman's blog.

You really should go and read up on the post, but in summary. If you run a ASP.Net webserver, you really should install these patches like RIGHT NOW so that users on IE10 will not experience any problems.

They should be up on Windows Update, but better safe than sorry.

If you don't have control of the server and can only upload files to your web application's folder, download this file from Scott's site. In the zip you'll find a projects/net[version] folder, along with some *.browser files. Copy the appropriate file to an app_browser folder in the root of your website and you'll be fine. Note that ASP.Net 3.0/3.5 is consider to be running on ASP.Net 2.0.


Tuesday, 24 July 2012 22:46:45 (Malay Peninsula Standard Time, UTC+08:00)  #    Comments [0]  | 
# Friday, 03 June 2011

A colleague showed me an interesting problem, the ASP:LinkButton controls in our ASP.Net 4.0 website wouldn't work when it was viewed from a browser control hosted inside an iOS app (ie. The viewer that pops up in the Facebook app when you click on a weblink) What made it weirder was that depending on the order you hit the webpage, either through the Facebook App first, then through Safari. The link button might or might not work.

We ran some test on an ASP.Net 2.0/3.5 site, and the LinkButtons on those sites worked fine. Baffled, I enabled trace.axd on the server to see if there were any differences between requesting for a page through the Facebook App, and through Safari. Immediately I noticed that the User Agent string was different.

When viewed through Safari the User Agent string was something like this.

Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_2 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8H7 Safari/6533.18.5

When the page was viewed through an app the User Agent looked like this.

Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_2 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Mobile/8H7

Notice that both the Version and Safari values are missing when viewed from the app.

In order to figure out what the difference was when these 2 values are missing, I fed the 2 UserAgent strings through IE9's developer toolbar and viewed the page on the desktop so I had more debugging ability. And to my surprise, when I used the UserAgent string without the Safari moniker, the following code was missing from the output page.

function __doPostBack(eventTarget, eventArgument) {
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
        theForm.__EVENTTARGET.value = eventTarget;
        theForm.__EVENTARGUMENT.value = eventArgument;
        theForm.submit();
    }
}

This happens to be the Javascript code which ASP.Net LinkButtons and various other auto postback controls will use to post the form through script on the page. So if the function was missing, then none of the controls would be able to post anything. So I begun my search on why the code was missing when the Safari moniker is missing. And I found the source of the problem, ASP.Net's feature for dynamically changing the way something is rendered based on the client's browser capability. Based on the sample shown on this page on how to see what browser capability was detected, I wrote a quick page which dumps the browser capabilities out with the code below.

        Dim ht As IDictionaryEnumerator = Request.Browser.Capabilities.GetEnumerator
        Response.Write(Request.Browser.Id)
        Response.Write("<br/>")
        Response.Write(Request.UserAgent)
        Response.Write("<br/>")
        Response.Write("----------------<br/>")
        While ht.MoveNext = True
           
            'If ht.MoveNext() = True Then
               
            Response.Write(String.Format("{0}:{1}", ht.Key, ht.Value))
            Response.Write("<br/>" & vbCrLf)
           ' End If
        End While

That's when I realized that WITHOUT the Safari moniker, the default browser capability DISABLES JAVASCRIPT that's why the clientside postback chunk was not delivered to the server.

Interestingly enough even without the Safari moniker, an ASP.Net 2.0 site will still flag the iPhone browser as Javascript capable.

Now that I knew what was missing, what was left was to make a new Browser Definition File which will enable Javascript for the ASP.Net 4.0 site even without the Safari moniker. I basically copied the definition for the Safari browser, but made it so it'll look for the AppleWebKit moniker in the UserAgent instead of the Safari moniker and flag it as Javascript capable.

<browsers>
  <browser id="safariiphone" parentID="mozilla">
    <identification>
      <userAgent match="AppleWebKit"/>   
    </identification>
    <capabilities>
            <capability name="version"                         value="${version}" />
            <capability name="majorversion"                    value="${major}" />
            <capability name="minorversion"                    value="${minor}" />
            <capability name="type"                            value="Safari${major}" />
            <capability name="ecmascriptversion"               value="3.0" />
            <capability name="javascript"                      value="true" />
            <capability name="javascriptversion"               value="1.6" />
            <capability name="w3cdomversion"                   value="1.0" />
            <capability name="tagwriter"                       value="System.Web.UI.HtmlTextWriter" />
            <capability name="cookies"                         value="true" />
            <capability name="frames"                          value="true" />
            <capability name="javaapplets"                     value="true" />
            <capability name="supportsAccesskeyAttribute"      value="true" />
            <capability name="supportsCallback"                value="true" />
            <capability name="supportsDivNoWrap"               value="false" />
            <capability name="supportsFileUpload"              value="true" />
            <capability name="supportsMaintainScrollPositionOnPostback" value="true" />
            <capability name="supportsMultilineTextBoxDisplay" value="true" />
            <capability name="supportsXmlHttp"                 value="true" />
            <capability name="tables"                          value="true" />
        </capabilities>
  </browser>
</browsers>

This file is saved as whateveryouwant.browser then placed under the App_Browsers folder of the website so it can be processed by ASP.Net. This fixed my problem but I was still still curious as to why it worked in ASP.Net 2.0 but NOT 4.0, so I dug around the Browser Definition Files for ASP.Net 2.0 and found this element it used to identify the Safari browser in ASP.Net 2.0

        <identification>
            <userAgent match="AppleWebKit/(?'webversion'\d+)" />
        </identification>

Which means that in ASP.Net 2.0 it's looking for the AppleWebKit moniker to identify Safari browsers, where as in ASP.Net 4.0 the identification element reads this.

        <identification>
            <userAgent match="Safari" />
            <userAgent nonMatch="Chrome" />
        </identification>

Seems like it was trying to avoid clashing with Google Chrome's Useragent which also happens to contain the AppleWebKit moniker but they ended causing problems in certain scenarios.


Friday, 03 June 2011 18:03:28 (Malay Peninsula Standard Time, UTC+08:00)  #    Comments [2]  | 
# Tuesday, 14 October 2008

My colleague pointed me at a Javascript library called JQuery today, he was tellling me that it was a neat library to do client side animations. I was a bit skeptical at first cause I didn't like how some of the libraries worked.

But after running through some tests just now I'm impressed, it's nice, simple and clean. Very straightforward to use and doesn't seem like it'll get in the way of our other scripting methods, including the ASP.Net Ajax Extensions. But I guess to be sure I'll need to go through it a bit more.

I guess it doesn't hurt that Microsoft feels it's pretty good too!

Hmmm.. ok… have to try out something one of these days.


Tuesday, 14 October 2008 02:35:11 (Malay Peninsula Standard Time, UTC+08:00)  #    Comments [0]  | 
# Saturday, 05 July 2008

Another interesting thing that happens during work. We receive some content to be entered onto a webpage from our copywriters, we copy the text from the mail, and paste it into our webpage. It looks fine when we pasted it in Visual Studio but then when other people look at it they see SOMETHING like this.

image

So you take a close look at the file and notice that where all the weird symbols were appearing is basically where an approstophe.. (Damn I can't spell it.. the ' in 's and 're)  is supposed to be, so the correct text should look like this.

image

So... what went wrong? Let see another example.

image

See the difference now? Still not yet? Look at the ', doesn't it look different between the 2 lines? Even the double quotes are actually different but they don't seem to be affected that much.

So... why is there a weird ' in the sentence? It's a very simple answer, just ask the person who prepared the document did he do it in MS Word? Now... dig into Word's auto correct options and you'll find something like this (varies depending on which version of Word you're looking at)

image

See the part about "Straight Quotes" with "smart quotes"? With that option on, basically when you use a non interesting " or ' Word will replace it with more pleasant looking ones, curvier ones, ones that look nicer when you print. But of course doesn't always work when you put it on a webpage, or a page designed to be viewed from a phone.

Just another one of the weird things you learn after developing web sites for a while


Saturday, 05 July 2008 01:32:50 (Malay Peninsula Standard Time, UTC+08:00)  #    Comments [0]  | 
# Friday, 04 July 2008

When you work with designers, it's very likely that sooner or later they'll come up with a web page design that uses multiple images that need to be joined together to form a display say something like this.

image

Where the yellow cell is actually where your content goes, and the cell below it is supposed to perfectly join up to the cell above to form a single unbreaking image. (Why does my sample suck? Because I can't draw! :P) But sometimes you'll end up with something like this. (The image below is simulated cause I can't get the error to show when I WANT it to! :P)

image

You'll see a gap between your supposedly perfectly joined cells (Usually about 1 pixel, I deliberately enlarged it so it's more visible right now).

Your HTML seems to be fine, with no additional cells, and the fact that you've already turned off cellpadding and cellspacing.

<table cellspacing="0" cellpadding="0" width="300">
        <tr>
            <td>
                <div style="background-color: yellow">
                    I'm in a TD
                </div>
            </td>
        </tr>
        <tr>
            <td>
                <img src="footer.jpg" />
            </td>
        </tr>
</table>

So you're scratching your head wondering what went wrong. The next time you see a problem like this, remove ALL spaces between the TD tags. So essentially make your HTML look like this.

<table cellspacing="0" cellpadding="0" width="300">
    <tr>
        <td><div style="background-color: yellow">
                I'm in a TD
            </div></td>
    </tr>
    <tr>
        <td><img src="footer.jpg" /></td>
    </tr>
</table>

Why does it happen? I have no idea, but to fix the problem it's always the same thing. Remove all whitespace from the TD tags. If that still doesn't fix it or you're feeling paranoid, close up the TRs as well.

<table cellspacing="0" cellpadding="0" width="300">
    <tr><td><div style="background-color: yellow">
                I'm in a TD
            </div></td></tr>
    <tr><td><img src="footer.jpg" /></td></tr>
</table>

Again.. I have no idea why it just happens sometimes, but it does, and here's how I fix the problem. More little tips from the trenches to follow.


Friday, 04 July 2008 00:45:36 (Malay Peninsula Standard Time, UTC+08:00)  #    Comments [0]  | 
# Wednesday, 28 November 2007

I was deploying an ASP.Net 2.0 web application yesterday, after copying all the files in I browsed to the site and I got an error telling me that one of my handlers couldn't be found.

I immediately assumed that there was an error with the permissions of the Network Service user that was being used to run the website. Totally forgetting that if the Network Service user couldn't compile to the temporary ASP.NET folder the error would be an access denied writing to temporary folder.

After spending TOO MUCH time trying to figure out the permissions, my Project Manager came to me and asked me what was taking so long. I told him that there was something wrong with the service permissions and that the compiler was acting as if the files weren't there. My PM asked the question "Are you sure the files are there?" I replied affirmatively since I was sure I saw that there were files in the web folder, so I decided to show him and browsed to the web site's APP_CODE folder, it was EMPTY....

I did a quick check on all the other folders and sure enough... ALL THE .VB CODE BEHIND FILES WERE GONE!!!! Some how the fact that I right clicked dragged the ZIP file containing the web files from a network share and then directly extracting it using the built in Compressed Folders handler of Windows 2003 cause all the VB files to NOT be extracted.

Copying the ZIP file to the web server first and then extracting it from there solved the problem.

So I learnt to ALWAYS CHECK THE OBVIOUS LESS WORK INTENSIVE REASONS FIRST BEFORE ANY OTHER SOLUTIONS when something bad happens. But still a few questions exists... namely Why the heck were the files removed in the first place? It wasn't the antivirus cause it didn't log any deletes, then I repeated the same action on a similarly configured Win2k3 server but the VB files weren't deleted.

Weird.....


Wednesday, 28 November 2007 10:01:57 (Malay Peninsula Standard Time, UTC+08:00)  #    Comments [1]  | 
# Wednesday, 14 November 2007

Well, the security company came and went without much of a problem. So I guess I survived my first code review pretty well with no major problems reported.

Experience, and of course this book (absolute must read for ANY programmer) helped ensure that our code was pretty tight (yes it wasn't perfect, but we did very good).

Best quote from a member of the review team.

Generally .Net code has fewer security problems.

I know a few people who would love to have you make that an official statement. ;)


Wednesday, 14 November 2007 21:34:48 (Malay Peninsula Standard Time, UTC+08:00)  #    Comments [0]  | 
# Sunday, 06 May 2007
Ahhh.. how far we've come now in application developement. Things used to be so easy when I started delving into programming, back then an application was just a program that just ran on your computer and that was it, hmmm and if I started work back then I guess it be a lot of database applications since that was when everything started being digitized. After the announcement of Silverlight recently I think I'll now use this post to reflect on the different methods/types of application developement that are now available.. from a MS technology based perspective of course since that's what I'm most experienced in.

Sunday, 06 May 2007 23:56:26 (Malay Peninsula Standard Time, UTC+08:00)  #    Comments [0]  | 
Page 1 of 2 in the ASPNet category Next Page