8

Ho creato una vista parziale in un'applicazione MVC 3. Questo punto di vista ha un modello fortemente tipizzato come questo:ASP.NET MVC PartialView non emette il markup di convalida

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

     set; 
    } ... 
} 

Nel mio metodo di azione invoco il metodo PartialView come questo

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

Ma sulla pagina non riesco a vedere nessun marcatore per la logica di convalida e comunque non succede niente se ci sono errori nella pagina. Se utilizzo questa vista parziale come modello di editor, funziona. Qualsiasi aiuto è apprezzato.

Modifica: per essere più specifico, ho un modulo HTML e voglio aggiungere markup ad esso tramite un aggiornamento Ajax (se l'utente fa clic su un pulsante, voglio aggiungere un nuovo markup a tale modulo). Se includo questi controlli staticamente, voglio dire che se li renderizzo quando la pagina viene caricata, la validazione funziona, ma se aggiungo controlli a quel modulo con una chiamata Ajax, per questi controlli non viene inserito alcun markup di convalida. La mia vista parziale simile a questa:

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

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

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

La mia forma è simile al seguente:

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

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

Il codice sopra funziona bene, la convalida funziona. Sul lato server invoco un metodo di azione che assomiglia:

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

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

ho capito che il motore MVC inserisce quelli Markup Validation solo se rileva che i controlli sono all'interno di un controllo di modulo. Quando provo ad aggiornare il controllo del mio modulo tramite una chiamata ajax, MVC non ha modo di sapere che saranno posizionati all'interno di un elemento del modulo ed è per questo che non emette alcuna logica di convalida per loro, suppongo.

+0

Ha senso che un editor "emetta" errori di convalida e così, e che una vista non lo fa. Possiamo vedere il codice per la tua vista? – rfmodulator

+0

Il problema è che MVC inserisce il markup di convalida solo se rileva che i controlli si trovano all'interno di un modulo. Il problema è che voglio aggiungere markup a un controllo di modulo tramite l'aggiornamento ajax, ma in questo modo il motore MVC non sa che questo markup verrà inserito in un elemento form e quindi non emetterà alcun markup di convalida. – Zoliqa

+0

È possibile forzarlo con un codice Html.ValidationMessageFor(). Come ho detto, mostraci il tuo punto di vista per favore. – rfmodulator

risposta

1

Hai abilitato la convalida non invasiva in web.config o nella vista stessa?

nel web.config:

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

o codice all'interno:

HtmlHelper.ClientValidationEnabled = true; 
HtmlHelper.UnobtrusiveJavaScriptEnabled = true; 
+0

La sua convalida funziona correttamente nell'editor, quindi questo ci dice che la configurazione è corretta. – rfmodulator

2

Nel vostro Vista Parziale, aggiungere questo (C#/Razor):

@Html.ValidationMessageFor(model => model.ProductPrice) 
0

Utilizzando convalida del client , è possibile convalidare nuovamente gli elementi caricati dopo il caricamento della pagina. Poiché MVC ora utilizza la convalida di jQuery, se hai attivato la convalida del client;

jquery validate - validating a field on pageload

Questo potrebbe aiutare.

10

mettere questo nella parte superiore del vostro vista parziale e si otterrà il messaggio di convalida reso in l'output HTML:

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

Se si utilizza Ajax per aggiungere i campi del modulo è possibile attivare i nuovi campi vengono aggiunti alla validazione, una volta che sono state aggiunte al DOM/pagina utilizzando qualcosa di simile:

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

EDIT/UPDATE (23 Fed 2013): ho appena hackerato il FormContext di una vista parziale la prima volta in Visual Studio 2012 e sembra che con le ultime versioni di jQuery e Validation, ecc. Non ho bisogno di aggiungere le 3 linee di javascript (sopra) affinché la convalida funzioni dinamicamente su ajax che è fantastico!

+0

Questo ha funzionato, ma non sono sicuro di aver capito perché. –

+0

@ChrisJackson - beh, guardando il problema puramente da una prospettiva black-box di alto livello, sarebbe corretto dire che Html.ValidationMessageFor cerca un FormContext non nullo, che tipicamente verrà impostato usando qualcosa come (Html.BeginForm) {- e se non ne trova uno, non disturba il rendering dei messaggi di convalida. La mia ipotesi è che la convalida JS richieda un modulo per funzionare correttamente, quindi non ha senso avere messaggi di convalida. IMO è una svista del team .Net. – Rob

+1

@Rob, grazie, questo ha risolto il mio mal di testa! – Netricity

2

Non sono sicuro se questo è ancora un problema per voi, ma la soluzione potrebbe essere quella di chiamare:

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

dopo aver caricato il form di marcatura/controlli tramite AJAX. Questo analizza i nuovi elementi del modulo e crea la convalida del client specificata nella vista.

+0

Indipendentemente dal fatto che fosse un problema per lui, era un problema per me. Ho continuato a rimbalzare nel profondo dell'interwebz in quel pomeriggio sconvolgente, sapendo che sarebbe stato qualcosa per riapplicare la convalida. Il mio unico rimpianto è che ho un solo voto da dare. Grazie, gentile signore, come posso ora smettere di sprintare la testa prima in questo muro di mattoni che è stato macchiato con molte pinta di sangue. Oh, non ho detto $ ('# my-new-form-div'), ho detto $ ('form') e funzionava ancora. FYI. – vbullinger