2013-05-10 4 views
33
@model Customer 

@Html.Partial("_UserProfile", (UserProfile)Model.UserProfile) 

Quando ho eseguito questo codice, ottengo questo errore:(PartialView) La voce modello di passato nel dizionario è di tipo 'clienti', ma questo dizionario richiede un elemento del modello di tipo 'ProfiloUtente'

The model item passed into the dictionary is of type 'Customer', but this dictionary requires a model item of type 'UserProfile'. 

Vista parziale _Profilo utente è fortemente digitato.

Desidero poter modificare questi campi. Qualche suggerimento?

+0

anche controllare la differenza tra Html.Action e Html.Partial è utile https://stackoverflow.com/questions/16886585/html-partial-skips-the-controller-action –

risposta

72

Verificare che Model.UserProfile non sia nullo.

Ho trovato il tuo post cercando di eseguire il debug dello stesso errore, e si è scoperto che non avevo inizializzato il mio equivalente "Model.UserProfile".

Immagino che cosa sta succedendo qui, è che se un modello null viene passato a RenderPartial, per default utilizza il modello della vista principale? Qualcuno può confermarlo?

+18

Hai ragione. Questo è un problema di sovraccarico. Quando si tenta di chiamare '@ Html.Partial (, )' mentre si passa il modello come 'null', l'implementazione assumerà che si sia chiamata la versione del metodo che accetta solo il nome della vista e passa il modello di vista corrente a la vista parziale. – Lafi

+0

Sì, hai ragione! Puoi aggiungere PropertyThatWasNull = new YourObject() nel tuo ViewModel Constructor per correggere questo problema nella maggior parte dei casi. Potrebbe essere più difficile con un oggetto UserProfile nullo. – jwize

+1

Cattivo bug su MVC, appena stato colpito da ciò, grazie per il suggerimento. – Alejandro

-1

Si sta tentando di inviare un oggetto di tipo Customer a un oggetto di tipo UserProfile. Di default questo non funzionerà in quanto il framework non ha idea di come lanciare questi oggetti. Se è assolutamente necessario fare in questo modo l'unica opzione è quella di fornire all'operatore cast esplicito come:

public static explicit operator Digit(byte b) // explicit byte to digit conversion operator 
{ 
    Digit d = new Digit(b); // explicit conversion 

    System.Console.WriteLine("Conversion occurred."); 
    return d; 
} 

Si può leggere di più su di esso here.

+0

C'è un cast per la proprietà UserProfile. In questo caso penso che non dovrebbe essere necessario, ma sembra un tentativo esplicito di dire al compilatore che questo è il tipo che sto passando. – avantprime

-1

Aggiungere la parola chiave "virtuale" alla proprietà UserProfile sul modello Cliente. E 'il modo easyest superare il lazy loading, ma le prestazioni ..

18

Se Model.UserProfile è nullo, si tenterà di passare nel modello del cliente.

due modi per aggirare questo:

@model Customer 

@Html.Partial("_UserProfile", (UserProfile)Model.UserProfile, new ViewDataDictionary()) 

O:

@model Customer 

if (Model.UserProfile != null) 
{ 
    @Html.Partial("_UserProfile", (UserProfile)Model.UserProfile) 
} 
+0

Il secondo non funzionerebbe, avresti bisogno di usare un cast difensivo: '@ Html.Partial (" _ UserProfile ", Modello come UserProfile)' – Echilon

+0

@Echilon: hai ragione il secondo non funziona, ma neanche lo fa il tuo suggerimento. La prima opzione nella risposta risolve comunque il problema. – musefan

+0

Il secondo è progettato per saltare la vista parziale se il modello è nullo. In questo esempio, potrebbe non essere utile visualizzare una vista Profilo utente quando non ci sono profili utente e questo eviterà l'errore. – Kcoder

0

Sarà fallback sul modello iniziale se l'oggetto passato è nullo.

Prova questo:

@Html.Partial("_UserProfile", (UserProfile)Model.UserProfile ?? new UserProfile()) 
1

mi sono imbattuto in questo problema quando si tratta di parti di un profilo utente come nome e indirizzo record. Se l'utente ha un profilo incompleto, desidero che la vista di gestione dell'account rilevi un record di indirizzo nullo e visualizzi un link di azione per creare un nuovo indirizzo o visualizzare qualsiasi dato di indirizzo disponibile.

Come descritto da altri quando viene passato null, il sovraccarico per Html.RenderPartial viene attivato e viene passato il modello di visualizzazione principale. Ho finito per convertire le mie viste parziali in Modelli di visualizzazione e editor per aggirare il problema.Ecco alcuni How-To articoli provenienti da: Hansleman e codeguru

si ottiene una migliore riutilizzabilità da questo metodo e conserva i valori nulli: Secondo lei:

@Html.DisplayFor(m=> m.Address) 

quindi gestire il valore null in il DisplayTemplate.

@model Namespace.Models.MyObject 
... 
if(@Model != null){ 
... 
}else{ 
... 
} 
+1

Di tutti i metodi che abbiamo provato a risolvere la nostra versione di questo problema, questo è stato di gran lunga il migliore. ViewData e ModelState (inclusi gli errori ModelState, ecc.) Vengono tutti passati normalmente con questo. La maggior parte delle altre soluzioni passa un nuovo oggetto ViewData che rovina qualsiasi ModelState. – mikeschuld

+0

Esattamente @mikeschuld Perché dovresti eliminare la gestione degli errori e lanciare un nuovo oggetto quando in realtà il tuo modello è nullo? Basta gestire lo stato in cui dovrebbe essere gestito. In tutta onestà non ho risposto alla domanda su come usare Html.Partial ho appena detto di non usarlo se il tuo oggetto potrebbe essere nullo. – reachingnexus

0

Ho affrontato lo stesso problema ma alla fine l'avevo capito. C'è una mancata corrispondenza di tipo nei modelli passati. La tua vista accetta il modello di tipo Customer ma la vista parziale passa il modello Userprofile quindi quello che devi fare è passare lo stesso modello in entrambi o .... creare un modello che ha tutte le proprietà di entrambi i modelli. Sicuramente il tuo problema sarà risolto.

Problemi correlati