Making ASP.NET MVC 2 client side validation work with AJAX loaded forms

Few days ago I wrote a post in this thread on forums.asp.net. In one of the posts vazavi noticed, that client side validation works only until you reload form using AJAX. I decided to take a deeper look at this. After few hours I have found a solution. The solution depends on which client side validation script you are using (the one which works with jQuery or the one which not). First I will go with the one which doesn't use jQuery. To make it work we need to write one function (I have just added it to MicrosoftMvcValidation.js):
Sys.Mvc.FormContext.OnSuccessEnableClientValidation = function (ajaxContext) {
  //Getting the update target container
  var updateTarget = document.getElementById(ajaxContext.$4.id);
  //Getting all script elements in it (script elements injected with innerHtml are not executed)
  var mvcClientValidationMetadataOldScripts = updateTarget.getElementsByTagName('script');
  var mvcClientValidationMetadataNewScripts = [];
  //For every script element
  while (mvcClientValidationMetadataOldScripts.length > 0) {
    //Create a new one
    var mvcClientValidationMetadataNewScript = document.createElement('script');
    mvcClientValidationMetadataNewScript.type = 'text/javascript';
    mvcClientValidationMetadataNewScript.text = mvcClientValidationMetadataOldScripts[0].text;
    //Add it to collection
    mvcClientValidationMetadataNewScripts.push(mvcClientValidationMetadataNewScript);
    //And remove old one
    updateTarget.removeChild(mvcClientValidationMetadataOldScripts[0]);
  }
  //For every new script element
  while (mvcClientValidationMetadataNewScripts.length > 0) {
    //Append it to update target container, this way they will be executed and generate needed metadata
    updateTarget.appendChild(mvcClientValidationMetadataNewScripts.pop());
  }
  //Calling Microsoft validation initialization for new metadata
  Sys.Mvc.FormContext._Application_Load();
}

Now we can use our new function as OnSuccess handler for Ajax.BeginForm:
<% Html.EnableClientValidation(); %>
<% using (Ajax.BeginForm("...", "...", null, new AjaxOptions() { UpdateTargetId = "...", OnSuccess = "Sys.Mvc.FormContext.OnSuccessEnableClientValidation" }, new { id = "..." })) { %>
  ...
<% } %>

Now it should work. Let's do the same for MicrosoftMvcJQueryValidation.js. We will add the following function inside of it:
function __MVC_OnSuccessEnableClientValidation(ajaxContext) {
  //Getting the update target container
  var updateTarget = document.getElementById(ajaxContext.$4.id);
  //Getting all script elements in it (script elements injected with innerHtml are not executed)
  var mvcClientValidationMetadataOldScripts = updateTarget.getElementsByTagName('script');
  var mvcClientValidationMetadataNewScripts = [];
  //For every script element
  while (mvcClientValidationMetadataOldScripts.length > 0) {
    //Create a new one
    var mvcClientValidationMetadataNewScript = document.createElement('script');
    mvcClientValidationMetadataNewScript.type = 'text/javascript';
    mvcClientValidationMetadataNewScript.text = mvcClientValidationMetadataOldScripts[0].text;
    //Add it to collection
    mvcClientValidationMetadataNewScripts.push(mvcClientValidationMetadataNewScript);
    //And remove old one
    updateTarget.removeChild(mvcClientValidationMetadataOldScripts[0]);
  }
  //For every new script element
  while (mvcClientValidationMetadataNewScripts.length > 0) {
    //Append it to update target container, this way they will be executed and generate needed metadata
    updateTarget.appendChild(mvcClientValidationMetadataNewScripts.pop());
  }
  //Getting new metadata
  var allFormOptions = window.mvcClientValidationMetadata;
  if (allFormOptions) {
    //For every form in metadata
    while (allFormOptions.length > 0) {
      //Enable validation for form based on metadata
      var thisFormOptions = allFormOptions.pop();
      __MVC_EnableClientValidation(thisFormOptions);
    }
  }
}

We can use this function in the same way as previous one:
<% Html.EnableClientValidation(); %>
<% using (Ajax.BeginForm("...", "...", null, new AjaxOptions() { UpdateTargetId = "...", OnSuccess = "__MVC_OnSuccessEnableClientValidation" }, new { id = "..." })) { %>
  ...
<% } %>

I can't say that this solution has been tested in every possible scenario, so if you find any problems with it, just let me know.