Update: If you've experienced random PageRequestManagerParserErrorException errors that seem to vanish at a simple page refresh, read this post instead: An intermittent PageRequestManagerParserErrorException

I've built a TranslationFilter object that tries to.. well... translate ASP.Net pages. Everything ran smoothly until I had to use ASP.Net Ajax. I got the infamous error "Sys.WebForms.PageRequestManagerParserErrorException: The message received from the server could not be parsed. Common causes for this error are when the response is modified by calls to Response.Write(), response filters, HttpModules, or server trace is enabled.".

Starting analysing the problem, I soon understood that the Ajax requests go through the same Response mechanism as a normal page request, but the output is different. In case of normal page requests you get the HTML of the page, while in Ajax requests you get something formated like this:
contentLength|controlType|controlID|content|


If one uses Response.Write, the text is inserted both in the page HTML and the Ajax request format, resulting in something like "blablabla10|updatePanel|UpdatePanel1|0123456789" which cannot be parsed correctly and results in an error. The ScriptManager.IsInAsyncPostBack property shows us if the request is Ajax or not, so we can condition the Response.Write on this.

Also, if changing the content with a HttpResponse.Filter, the length of the content is no longer equal with the declared value. So what must be done is first detect if the content is Ajax. Unfortunately we cannot check the state of the ScriptManager from inside the HttpResponse.Filter, but we can check the format of the string to modify, then modify the content AND the contentLength, else it will all result in error.

Update: the content might not be changed by you! As one of the people asking me for help on the chat discovered, the web server provider might want to put in some ads, regardless if the request is an Ajax one, thus breaking the format. You need to patch the javascript ajax engine in order to work, that means changing the content the javascript function will get in order to not cause errors. You may find the solution here.

As an example, here is my Translate method:
        private string RecursiveTranslateAjax(string content)
        {
            Regex reg = new Regex(@"^(\d+)\|[^\|]*\|[^\|]*\|",
                         RegexOptions.Singleline);
            Match m = reg.Match(content);
            if (m.Success)
            {
                int length = To.Int(m.Groups[1]);
                reg = new Regex(
                         @"^(\d+)(\|[^\|]*\|[^\|]*\|)(.{" + length + @"})\|"
                         , RegexOptions.Singleline);
                m = reg.Match(content);
                if (m.Success)
                {
                    string trans = Translate(m.Groups[3].Value);
                    return trans.Length + m.Groups[2].Value 
                       + trans + "|"
                       + RecursiveTranslateAjax(content.Substring(m.Length));
                }
            }
            return Translate(content);
        }


Update:
I met this problem also when in the page there were Unicode characters. Everything works perfectly, then you can't postback anything, because some user text contains Unicode chars. The solution I used for this was to get the offending text (whether in Page.Render or in some other places based on specific situations) and take every character and check if it is ASCII. Web Pages should be UTF8 so any character bigger than 127 should be translated into a web page Unicode char &#[char code];

The code:

string s=[my string]
StringBuilder sb=new StringBuilder();
for (int c=0; c<s.Length; c++)
{
if (s[c]>127) sb.Append("&#"+((int)s[c])+";");
else sb.Append(s[c]);
}
s=sb.ToString();


Here is the full code
    private string RecursiveTranslateAjax(string content)
    {
        // look for the basic Ajax response syntax
        Regex reg = new Regex(@"^(\d+)\|[^\|]*\|[^\|]*\|", 
              RegexOptions.Singleline);
        Match m = reg.Match(content);
        // if found, search deeper, by taking 
        // into account the length of the html text
        if (m.Success)
        {
            // custom method to get an integer value
            int length = To.Int(m.Groups[1]); 
            reg = new Regex(@"^(\d+)(\|[^\|]*\|[^\|]*\|)(.{" + length + @"})\|",
                  RegexOptions.Singleline);
            m = reg.Match(content);
            if (m.Success)
            {
                string trans = Translate(m.Groups[3].Value);
                return
                    trans.Length + m.Groups[2].Value + 
                    trans + "|" + 
                    RecursiveTranslateAjax(content.Substring(m.Length));
            }
        }
        // if not Ajax, just translate everything,
        // it must be a normal PostBack or a string of some sort.
        return Translate(content);
    }
 
    // this method only fixes the weird characters
    // but you can put here any string change you would like
    // like search and replace some words.
    private string Translate(string content)
    {
        // Html code all chars that are not ASCII, thus getting rid of strange or Unicode characters
        StringBuilder sb = new StringBuilder();
        for (int c = 0; c < content.Length; c++)
        {
            if (content[c] > 127) sb.Append("&#" + ((int) content[c]) + ";");
            else sb.Append(content[c]);
        }
        return sb.ToString();
    }
 
    protected override void Render(HtmlTextWriter writer)
    {
        //base.Render(writer);
        // render to my own text writer
        HtmlTextWriter tw=new HtmlTextWriter(new StringWriter());
        base.Render(tw);
        // get the Rendered content of the page
        string content = tw.InnerWriter.ToString();
        content = RecursiveTranslateAjax(content);
        writer.Write(content);
    }


To.Int method
public static int Int(object o)
{
    if (o == null) return 0;
    if (IsNumericVariable(o)) return (int) CastDouble(o);
    string s = o.ToString();
    if (s == "") return 0;
    Match m = Regex.Match(s, "(-\\d+|\\d+)");
    if (m.Success)
        try
        {
            return Int32.Parse(m.Groups[0].Value);
        }
        catch
        {
        }
    return 0;
}
private static double CastDouble(object o)
{
    if (o is byte) return (byte) o;
    if (o is int) return (int) o;
    if (o is long) return (long) o;
    if (o is float) return (float) o;
    if (o is double) return (double) o;
    if (o is decimal) return (double) (decimal) o;
    throw new ArgumentException("Type is not convertable to double: " + o.GetType().FullName);
}

Internet Explorer has a lot of "features" that are completely useless. One of them is the infamous "Can't move focus to the control because it is invisible, not enabled, or of a type that does not accept the focus.". So what?! Just return a false value! Why do you have to throw an error?
Anyway, I've stumbled upon a bug accidentally while reviewing a html control on DynamicDrive. This is the basic setup:
<style>
.div {
display:none;
}
</style>
<script>
function loadGoogle() {
document.getElementById('div').style.display='';
document.getElementById('iframe').src='http://www.google.com';
return false;
}
</script>
<div class=div id=div style="">
<iframe id=iframe src="" ></iframe>
</div>
<a href="#" onclick="loadGoogle()">Click me!</a>


And it returns an error. Why? Because the javascript on Google tries to focus something:
document.f.q.focus();
But the display is cleared before changing the src. For all purposes, the div has the display set to an empty string (and you can check it with an alert right after it is set). The funny thing is, and that might come as a surprise, that if you move the display:none to the style attribute of the div, the script above doesn't return any error!

So, bottom line: attribute set in style tag or css cannot be changed dynamically without an error, while a control attribute can. What's up with that?! (Bug found on IE7.0). If you encounter this weird error, try moving the display attribute (I couldn't replicate the bug with the visibility attribute) in the control style attribute.

First of all, to turn a normal ASP.NET application to Ajax takes only a few minutes with the Microsoft Ajax.Net platform. It's as easy as moving some of the content in UpdatePanels and adding a ScriptManager. Of course, you need the Ajax.Net package installed.

What I am going to talk about is a simple way to enable/disable Ajax, and keeping the entire basic functionality intact. Why would I do that? Because sometimes you need to see the project working on a computer that doesn't have the Ajax framework installed. You might even want to work on the project itself. So this is what you do:

First of all, the ScriptManager control must appear on every Ajax page in the project, so why not move it to the MasterPage? Yes. Only one ScriptManager in the MasterPage suffices. Second of all, the UpdatePanel and the UpdateProgress controls are nothing more than normal Panels with the cool Ajax functionality added to them. So enabling or disabling Ajax surmounts to nothing more than replacing these controls with normal panels.

So here is the quick method of enabling, disabling Ajax.Net whenever you want:
Start off from the Ajax enabled application and save the web.config as web.config.ajax. Remove everything from it that resembles System.Web.Extensions and all other weird things that Ajax.Net adds to the web.config except this:
<system.web>
<pages>
<controls>
<add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</controls>

this you only replace with this:
<system.web>
<pages>
<controls>
<add tagPrefix="asp" namespace="System.Web.UI" assembly="MockAspNetAjax"/>
</controls>

Save it to Web.config.noajax

You might see where I am going already. Now create a new Visual Studio project, a class library, one that you will use for all these conversions, and call it MockAspNetAjax. Go to the project Properties and change the default namespace to System.Web.UI. Add three classes that do nothing but inherit from Panel: ScriptManager, UpdatePanel, UpdateProgress. The UpdateProgress will have some additional code:
 public UpdateProgress()
{
Init += new EventHandler(UpdateProgress_Init);
}

void UpdateProgress_Init(object sender, EventArgs e)
{
Visible = false;
}

because you don't want to see the Ajax Update Progress message continuously on your page.

In order to convert an ASP.NET Ajax application to a normal postback application you follow two simple steps:
1. overwrite the web.config with web.config.noajax
2. add MockAspNetAjax as a reference or include in the project if previously excluded.

back to Ajax:

1. overwrite the web.config with web.config.ajax
2. remove MockAspNetAjax as a reference or exclude the dll from the project, while keeping the dll there.

That's it!

Of course, Ajax has a lot more stuff to it, like for example the [ScriptService] web services that are directly accessed from Javascript. Or Ajax enabled controls or other controls which don't even work without the framework. These are more complex situations which cannot be solved with such a general solution, but the same basic principles apply: use web config to avoid Register tags in each page, replace controls with mockup controls, remove HttpHandlers and HttpModules, replace javascript code that uses Ajax with something that does nothing or emulates the same behaviour (preferably) through postbacks or hidden iframes, etc.

In ASP.NET a Control has a fully qualified id that can be deduced from the control hierarchy and can be accessed with the properties ClientID or UniqueID. It then becomes the unique id or name of rendered html controls. It makes sense that these properties should be used right after the control hierarchy is completely defined, that means before the rendering, therefore in the PreRender.

What is not so well known is that accessing those two properties sets the _cachedUniqueID member, which sets irrevocably the ID to a control. That's why using these properties in ItemCreated events, for example, makes the html id of controls to remain the default defined one.

Example: In a DataList, you have an item template that contains a control, let's call it Control1. The rendered id in html will look like this: ctl00_ContentPlaceHolder1_UcUserControl_DataList1_ctl00_Control1 , but if you use ClientID inside the DataList_ItemCreated event, the rendered html id will be just Control1, thus making any javascript manipulation futile.

Of course, one could create a method to return the UniqueID without setting the cached value, since there are moments when the partial hierarchy is enough to define a proper id. Unfortunately, for controls without a specific and declared id, ASP.NET creates and automatic ID like ctl[number] or _ctl[number] and, of course, those methods and fields are all private or internal. One could use Reflection to get to them, but what would be the point?
UniqueID and ClientID are overridable, though, so one can change their behaviour in user defined controls.

Related links:
Accessing ClientID or UniqueID too early can cause issues

Long story short, here's the link:
Inserting at the cursor using JavaScript

I had this DataList with a simple ItemTemplate which contained a Select button. I wanted to click on the item and select it, without the use of the button. So what I s did is add this in DataList1.OnInit:
Panel1.Attributes["onclick"]=Page.ClientScript.GetPostBackEventReference(btnSelect, "");

Nothing was working after that. The select button didn't fire the OnItemCommand event and its ClientID was just btnSelect, not ctl00$ContentPlaceHolder1$UcGroupEdit1$DataList1$ctl00$btnSelect like it should have been. Of course, even considering the possibility of a button firing a command event when there are ten other buttons with the same ID on the page was ridiculous. What has caused this?

Well, I removed the line above and everything worked again. The only solution was to override the user control Render method, then take each item, FindControl the button and the panel, then repeat the same line, with an additional parameter that said to register the control for postback. If I didn't do that, an event validation error would have occurred. Why Render? Because using the last parameter anywhere else causes the "RegisterForEventValidation can only be called during Render();" error.

So
Panel1.Attributes["onclick"]=Page.ClientScript.GetPostBackEventReference(btnSelect, "",true);
in the Render event was the only solution. I've spent hours just understanding what is wrong. Grrr!

Update: I think the post Problems when using ClientID or UniqueID before the PreRender event is closer to the problem and its causes.

I have been working recently with Page.LoadTemplate and ITemplate.InstantiateIn to add content from user controls to pages or other controls. This thing solves the problem of having to declare abstract classes in App_Code, but poses another problem linked to the lack of object references to the user controls you instantiate. What that means, among other things, is that you lose the ability to use events in your code.

But there is a way to bubble events to the upper controls and catch them. The first thing you should look at is the OnBubbleEvent protected method of the Control object. It catches all the events raised by its controls. Override it and you can catch events and treat them. Now, this method returns a bool value. It tells the RaiseBubbleEvent method (I'll talk about it shortly) if the event was handled or not. If it was, then the event doesn't rise above that control.

Now, about the RaiseBubbleEvent method, also a protected method of the Control object. What it does is go up the object hierarchy and execute on each object the OnBubbleEvent. It also stops if the method returns true. It is so simple and perfect that it is not overridden in any of the ASP.NET 2.0 WebControls.

But there is a catch. Some objects, like DataLists, DataGrids, Gridviews, Repeaters, etc, choose to handle the events in their items no matter what. That's why if you click a button inside a DataList, the event won't bubble to the OnBubbleEvent method from the UserControl or Page the DataList is in. Instead, the event reaches the OnItemCommand event.

So, if you want to use this general bubbling method with WebControls that override OnBubbleEvent, you have two options.
One is use inherited objects that remove this issue altogether (like inheriting from a DataList, overriding OnBubbleEvent, executing base.OnBubbleEvent, then always return false), which might make things cumbersome since you would have to define a control library.
The second option is to always handle the OnItemCommand and other similar events with something like RaiseBubbleEvent(sender, args); . This very line will re bubble the event upwards.

Benefits: the benefits of using this general event bubbling technique is that you don't have to always specifically write code in the OnItemCommand or having to handle OnClick events and so on and so on. Just catch all events, check if their arguments are CommandEventArgs, then handle them depending on source, command name and command argument.

First of all there is no reason not to apply this method to any other templatable control like GridViews or DataGrids. The basic mechanism is the same.

The problem here is how to display different templates for different items (not just for different item types) like when databinding to a general collection of different objects.

Basically all you have to do is use the OnItemCreated event to first load a template (using Page.LoadTemplate) from any user control and then applying it to the DataListItem (using ITemplate.InstantiateIn). But there are a few catches. First of all, the original templates (the ones in the as?x file) are applied before the OnItemCreated event. So if some templates are defined, like ItemTemplate for example, you need to clear the controls in the item before you instantiate your template. Second of all, you cannot declare the OnItemCreated event in the Page_Load method, since it is executed after the OnItemCreated event. But you can declare it in the as?x file.

So let's combine all this into code. First the aspx:
<asp:DataList id="dlMain" runat="server" OnItemCreated="dlMain_ItemCreated" >
</asp:DataList>

nothing fancy. Then the cs code:
protected void dlMain_ItemDataBound(object sender, DataListItemEventArgs e)
{
ITemplate template1 = e.Item.ItemIndex % 2 == 0
? Page.LoadTemplate("~/ucTest1.ascx")
: Page.LoadTemplate("~/ucTest2.ascx");
e.Item.Controls.Clear();
template1.InstantiateIn(e.Item);
}


That's it! ucTest1 and ucTest2 are two arbitrary user controls I am loading alternatively. For this particular case an AlternatingItemTemplate could have been used, but you get the point.

One of the issues that largely remains unsolved in AJAX applications is the ability to bookmark (say, add to the Favourites) the page with all the AJAX added info on it. This very cool javascript library allows one to save the state of the page using the window.location.hash variable, which holds the string after the # character, also called a hash.
Javascript can modify and read this value with no refresh of the page. Also, if you have anchors in your page, like... <a name="hash" Javascript code like
window.location.hash='hash';
will scroll the page there.

I have this Web User Control that has a simple function of displaying a customised grid and fill it with data. Since I had to email the rendered HTML I've added a static method to the Web User Control that would render itself based on some parameters. However, in Net 2.0 one cannot dynamically use the types declared in the codebehind of a user control or page inside another control or page, only types declared in App_Code. In pages this gets solved as in the link above, but what do you do when you want to use the type inside a class in App_Code or, like I needed to, in a web service (where register directives are not allowed)?

In my case, there were two solutions. One is to create a page that loads the user control and nothing else, then read its html. That solves the problems of using the code, but adds security issues. I have to either add a security mechanism to the page or allow anyone to render the UserControl. The second solution, the one that I ended up implementing, is to use reflection.

Let's recap. I have the web user control, let's call it Wuc, and I have the static method Wuc.GetHtml(int i) that I must access from a Web Service. If I write
string s=Wuc.GetHtml(i); it doesn't get to compile, returning the error "The name 'Wuc' does not exist in the current context".

So I do something like this:
UserControl uc = new UserControl();
uc = (UserControl) uc.LoadControl("~/Wuc.ascx");

and I get the object I need to get the type of. Then I should get a reference to the method I want so I try:

MethodInfo mi = uc.GetType()
.GetMethod("GetHtml",BindingFlags.Static);


which should work, but it doesn't!

Why not? Because the type of the object is not Wuc is wuc_ascx and it's the dynamically generated ASP.NET type. I get all the methods of Wuc, but not the static ones! So, the (really ugly) solution is to make the method not static and use this code:

MethodInfo mi = uc.GetType()
.GetMethod("GetHtml");
string s = (string)mi.Invoke(uc, new object[] { i });


which finally works.

Update
Scott Gu was nice enough to respond to my request on how to do this. He has this blog entry that explains how to render a control in NET 2.0 within an ASP.NET Ajax environment, but what really connects with my blog entry is this archive and the ViewManager object. Scott uses here the Page.LoadControl method (here is why) to load the control and Server.Execute instead of RenderControl.

Update!! Read the Sift3 post. It is an even better algorithm.


A while ago I wrote a little algorithm that tried to cope with the large amount of time that the Levenshtein edit-distance algorithm took to compare two strings. It was a really funny algorithm, but it was fast enough to show me the similarity between strings that, after all, should have been either very similar or different.

Meanwhile I started thinking if I could improve on it. I was sure I could, because it wasn't very scientific, it was empirical. And finally I did it. This is the Sift2 algorithm, along with an SQL server function that can make one million string comparisons in 2.5 minutes. Compared with Levenshtein, Sift2 performs 10 to 25 times faster and it is four times faster than Sift.

The concept:
  • Starting from the beginning of both words, compare the letters on the same position.
  • If the same, move forward, else search the letter from the first word in the next maxOffset letters in the second word and viceversa.
  • Offset the words according to the closest found letter, add 1 to distance
  • Repeat until one of the words ends
  • Add to the calculated distance half of the length of string remained unparsed from the other word
That's it! Here is the code:


C# Code (double click to show/hide)




T-SQL code (double click to show/hide)



You can find a nice OOP Javascript implementation at IT BASE.

Performance:
The algorithm seems to be working fine for letter insertions, typos, letter inversions and such. It gives slightly different values than Levenshtein when big words are inverted. When a lot of letters are inverted, the difference from Levenshtein increases. Example: abcdefghijkl vs. badcfehgjilk (every two letters inverted) results in 0.42 similarity in Levenshtein and 0.08 in Sift2. But let's face it, the two words are really different.

Update:
I've optimised the algorithm a little and also changed the formula so that it matches the Levenshtein distance as close as possible. The basic idea remains the same, but now the average error from Levenshtein (calculated or real company name and address data) is only 3%.
Some people saw the goto line and immediately laughed. Well, I tried replacing it with a break and a subtraction and even removed the subtraction altogether (thus maiming the algorithm) and the goto implementation was still the fastest. So I will continue to use goto, as it is more efficient.

Request:
I have seen a lot of people actually searched on Google and got here. I would really really really like some comments, links to implementations or whatever... It's my baby after all. Thanks!

Check out this little link: You receive an "interface not registered" error message when you try to build a Setup project in Visual Studio .NET
Why this is happening in the first place, I do not know, but the fix worked wonderfully. I was trying to build a Net 1.1 setup vdproj with Visual Studio 2003 and I got the error: "Could not find the file '[file that was obviously there]' 'Interface not registered' ".

Sometimes, when you use ASP.Net 2.0 with MasterPages, UserControls and dynamic loading like LoadControl, you get a silly error: Unable to cast object of type 'X' to type 'X' where X=X. Of course, it is a versioning problem. Some of these errors appear in the VS2005 designer, when the designer uses an older version of a library, but also when trying to open the web page in a browser.

Microsoft has released a fix for this: http://support.microsoft.com/kb/915782 , but, to quote the same source: "This hotfix may receive additional testing. Therefore, if you are not severely affected by this problem, we recommend that you wait for the next Microsoft .NET Framework 2.0 service pack that contains this hotfix.". So you risk screwing things up.

The issue seems to be mostly a developer problem. That means that during programming, you get this error when you keep changing stuff in the project. A client might get this error if an update of the site created this problem. The iisreset utility won't work. Recompiling locally and reupdating the site usually solves the issue.

and has 2 comments
This article is obsolete, a better version of the algorithm has been published: Sift3

While researching different ways of measuring the distance between two strings, or how different they are, I've found of course the Levenstein algorithm. The problem with it is that it is slow. Searching more, I've seen some algorithms that seemed fast, but I didn't have the time or brain power to understand them. So I've devised my own algorithm, called SIFT. You might think the name comes from Siderite's Intelligent and Fast Technique, but it comes from the English word 'sift'. :)
How does it work? Well, the common scenario in comparing strings is that someone made a mistake, a typo. So in principle, the two strings should be very similar in order to be worth comparing them. So what I do is this:

foreach phase
remove identical overlapping characters
shake strings
return number of shakes + the length of the longest string between the two.

There is an optimisation towards the safe side: if the sift similarity is big enough, perform the constly Levenstein distance.

Ok, it might not be so clear, let's take an example:
INTERESTING
INFORMATIVE

Step 1: remove all identical overlapping characters (sift)
TEESNG
FOMAVE

Now we have smaller words to check, let's suppose there was a typo, that means that part of the one word is offset with one or maybe two characters from the other. So we move them a bit, that's a 'shake'.

Step 2: shake
TEESNG
[]FOMAVE

Oops, no overlapping characters. We do this one or two times more and there is no result, so...

Step 3: return result
MaxLength(TEESNG, FOMAVE)=6

There you have it. The sifting algorithm, because it resembles sifting grain.

Not satisfied with such a simple example? Let's take another:
Click here

Tests have shown it to be pretty close to Levenstein, at least in the cases that matter, while being substantially faster.

and has 0 comments
Long story short: the BackgroundWorker object. Available in .NET 2.0
This is a Microsoft tutorial on using BackgroundWorker:
How to: Run an Operation in the Background
This is an older and more Windows Forms basic tutorial on multithreading:
Safe, Simple Multithreading in Windows Forms, Part 1
Safe, Simple Multithreading in Windows Forms, Part 2

Details:
BackgroundWorker has the DoWork, ProgressChanged, RunWorkerCompleted, and Disposed events. You need to assign at least one method for DoWork and one for RunWorkerCompleted, then run
bw.RunWorkerAsync(obj);
The DoWork method should do something like
e.Result=BackgroundOperation(obj);
while the RunWorkerCompleted method should do anything related to the GUI. There is also a CancelAsync() method, to try to stop a background operation.

Also, here is an article about a possible bug in BackgroundWorker, but I haven't replicated it on my computer.