ASP.NET MVC PartialView doesn't emit validation markup
Asked Answered
F

5

8

I created a partial view in an MVC 3 application. This view has a strongly typed model like this:

public class ProductViewModel
{
    [Required, Display(Name = "Product price")]
    public decimal? ProductPrice
    {
        get;

        set;
    } ...
}

In my action method I invoke the PartialView method like this

PartialView("ProductViewModel", products[0]);

But on the page I cannot see any markup for the validation logic however and nothing happens if any errors are on the page. If I use this partial view as an editor template, it works. Any help is appreciated.

Edit: To be more specific I have an HTML form and I want to add markup to it via ajax update (if th e user clicks on a button, I want to add new markup to that form). If I include those controls statically, I mean if I render them when the page gets loaded, validation works but if I add controls to that form by an ajax call, no validation markup is inserted for those controls. My partial view looks like this:

@Html.LabelFor(x => x.ProductPrice)

@Html.TextBoxFor(x => x.ProductPrice)

@Html.ValidationMessageFor(x => x.ProductPrice)

My form looks like this:

@using (Html.BeginForm())
{
    <div id="div_Products">
        @Html.EditorFor(x => x)
    </div>

    <input type="submit" value="Compare" />
}

The code above works well, validation works. On server side I invoke an action method that looks like:

[HttpPost]
public ActionResult InsertProduct()
{
    var newProductVM = new ProductViewModel{ ProductPrice = 789 };

    return PartialView("~/Views/Nutrition/EditorTemplates/ProductViewModel.cshtml", newProductVM);
}

I figured out that the MVC engine inserts those validation markup only if it finds that the controls are inside a form control. When I try to update my form control via an ajax call, MVC has no way to know that they will be placed inside a form element and that's why it doesn't emit any validation logic for them, I suppose.

Flitting answered 22/12, 2011 at 14:13 Comment(3)
It makes sense that an editor "emits" validation errors and such, and that a view does not. Can we see the code for your view?Eternalize
The problem is that MVC inserts validation markup only if it finds that the controls are inside a form. The problem is that I want to add markup to a form control via ajax update but this way the MVC engine doesn't know that this markup will be inserted into a form element and therefore it doesn't emit any validation markup.Flitting
You can force it with some Html.ValidationMessageFor() code. Like I said, show us your view please.Eternalize
O
10

Put this in the top of your partial view and you will get the validation message rendered into the html output:

if (this.ViewContext.FormContext == null) 
{
    this.ViewContext.FormContext = new FormContext(); 
}

If you are using ajax to add the form fields you can trigger the new fields to get added to the validation, once they've been added to the DOM/Page using something like:

$("form").removeData("validator");
$("form").removeData("unobtrusiveValidation");
$.validator.unobtrusive.parse("form");

EDIT/UPDATE (23 Fed 2013): I've just hacked the FormContext of a partial view for the first time in Visual Studio 2012 and it seems that with the latest versions of jQuery and Validation etc I don't need to add the 3 lines of javascript (above) for the validation to work dynamically over ajax which is great!

Orff answered 24/1, 2012 at 11:36 Comment(1)
@ChrisJackson - well, looking at the problem purely from a high-level black-box perspective, it would be fair to say that the Html.ValidationMessageFor looks for a non-null FormContext - which would typically be set up using something like using(Html.BeginForm){ - and if it doesn't find one then it doesn't bother rendering the validation messages. My guess is that the JS validation requires a form in order to function correctly so there's no point having validation messages. IMO it's an oversight by the .Net team.Orff
E
2

In your Partial View, add this (C#/Razor):

@Html.ValidationMessageFor(model => model.ProductPrice)
Eternalize answered 22/12, 2011 at 14:46 Comment(0)
P
2

Not sure if this is still a problem for you, but the solution would be to call:

$.validator.unobtrusive.parse($('#your-new-form-div'));

after you have loaded the form markup/controls through AJAX. This parses your new form elements and creates the clientside validation you have specified in your view.

Pianissimo answered 20/2, 2012 at 13:42 Comment(1)
Regardless as to whether or not it was a problem for him, it was a problem for me. I've been bouncing around the depths of the interwebz all freaking afternoon looking for this, knowing it was going to be something about reapplying the validation. My only regret is that I have but one upvote to give. Thank you, kind sir, as I may now stop sprinting head first into this brick wall that has been stained with many a pint of my blood. Oh, I didn't say $('#my-new-form-div'), I said $('form') and it still worked. FYI.Luciolucita
C
1

Did you enable unobstrusive validation in web.config or the view itself?

in web.config:

<configuration>
    <appSettings>
        <add key="ClientValidationEnabled" value="true"/>
        <add key="UnobtrusiveJavaScriptEnabled" value="true"/>
    </appSettings>
</configuration>

or inside code:

HtmlHelper.ClientValidationEnabled = true;
HtmlHelper.UnobtrusiveJavaScriptEnabled = true;
Cockroach answered 22/12, 2011 at 14:32 Comment(1)
His validation works correctly in the editor, so this tells us that the configuration is correct.Eternalize
A
0

Using client validation, it's possible to re-validate elements loaded after the page load. As MVC now uses jQuery validation, if you've got client validation enabled;

jquery validate - validating a field on pageload

This might help you.

Anglicist answered 22/12, 2011 at 14:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.