Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PartialView and unobtrusive client validation not working

I'm currently using ASP.NET MVC3 RC and I'm using the unobtrusive JQuery validations as described by Brad Wilson on his blog. It works great but when I send my form (in Ajax) to the server, I do some server side validations and return the same row (that is included in a partial view) if my model state isn't valid. 2 problems with that :

1st : When I do a return PartialView in my action, all the unobtrusive attributes aren't rendered. I found a "non elegant" way to do it but when I do it, client validations are broken. After I return from my action, even if I call jQuery.validator.unobtrusive.parse() on my updated row, $("form").valid() always return true even if it's not the case.

2nd : I want my rendered view to be render as a string on the server so I can send it back in a JsonResult (ex:myJSonResult.html=RenderPartialToString("partialName",model)).

Has a reference, there's my view (editInvitation) :

<td>
    <%= Html.HiddenFor(x=>x.ID,new{id="ID"}) %>
    <%= Html.HiddenFor(x=>x.GroupID,new{id="GroupID"})  %>
    <%: Html.TextBoxFor(x => x.Name, new { id = "Name" })%><%:Html.ValidationMessageFor(x=>x.Name) %>
</td>
<td>
    <%: Html.TextBoxFor(x => x.Email, new { id = "Email" })%>  <%:Html.ValidationMessageFor(x=>x.Email) %>
</td>
<td>
    <%: Model.Status.ToFriendlyName()%>
</td>
<td>
  <%= InvitationsViewModel.RenderActions(Model, Html, InvitationsViewModel.CreateRowID(Model.ID))%>
</td>

And my controller action :

if (TryUpdateModel(invitation))
{
    validModel = true;
    //Other stuff
}
if (Request.IsAjaxRequest())
{
     //TODO : I return a partial view but I would prefer to return a JSonResult with the rendered view as a string in an Property of my JSon result
     return PartialView(validModel ? "DisplayInvitation" : "EditInvitation", invitation);
}

Thanks

like image 860
mberube.Net Avatar asked Nov 15 '10 18:11

mberube.Net


1 Answers

I finally make it worked. This is how :

HtmlHelper helper = GetHelper();
MvcHtmlString partialView = helper.Partial("myView" , model);
var result = new { success = ModelState.IsValid, html = partialView.ToString() };
return Json(result);

There's the helper functions:

protected HtmlHelper GetHelper()
{
    return GetHelper(string.Empty);
}
protected HtmlHelper GetHelper(string formID)
{
    HtmlHelper helper = new HtmlHelper(getViewContext(formID), new ViewPage { ViewData = this.ViewData });
    helper.EnableClientValidation(isClientValidationEnabled());
    helper.EnableUnobtrusiveJavaScript(isUnobtrusiveJavascriptEnabled());
    return helper;
}
private ViewContext getViewContext(string formID)
{
    var vc = new ViewContext(this.ControllerContext, new WebFormView(this.ControllerContext, "~/Views/Home/Index.aspx"), this.ViewData, new TempDataDictionary(), new System.IO.StringWriter());
    vc.UnobtrusiveJavaScriptEnabled = isUnobtrusiveJavascriptEnabled();
    vc.ClientValidationEnabled = isClientValidationEnabled();
    vc.FormContext = new FormContext { FormId = formID };
    return vc;
}

I'm not sure it's the best way to do it but it worked for me. Let's hope the ASP.NET MVC team would provide an easier way to render a view as a string.

Thanks

like image 167
mberube.Net Avatar answered Sep 29 '22 10:09

mberube.Net