2013-01-20 19 views
16

Sto utilizzando il framework di bootstrap di Twitter, quindi per ottenere i metodi EditorFor e DisplayFor per l'output di ciò che mi serve, ho creato modelli personalizzati per ciascuno dei tipi come stringa, testo, password ecc. . Per la mia pagina di login voglio un bool RememberMe, così come prima, ho creato il modello seguente e messo in in Boolean.cshtml:MVC 4 Modello personalizzato per bool (rasoio)

@model bool 

<div class="control-group"> 
    <div class="controls"> 
     <label class="checkbox"> 
      @Html.CheckBoxFor(m => m, new {@class = "checkbox"}) 
      @Html.LabelFor(m => m) 
     </label> 
    </div> 
</div> 

abbastanza semplice, ma quando uso:

@Html.EditorFor(m => m.RememberMe) 

Ricevo un'eccezione dicendo che il valore al basso non può essere nullo:

The model item passed into the dictionary is null, but this dictionary requires a non-null model item of type 'System.Boolean'. 

Cosa mi manca? Sembra che dovrebbe essere semplice. Il campo sull'oggetto del modello appare come segue:

[Display(Name = "Remember me?")] 
public bool RememberMe { get; set; } 

Grazie.

AGGIORNAMENTO: Quindi sembra che alla fine si tratta di creare un oggetto modello di vista vuoto e passarlo alla vista invece di consentire a MVC di crearne uno da solo.

+0

Potrebbe cercare di impostare il valore di' RememberMe' default con dataannotations '[DefaultValue (false)]' –

risposta

18

Non lo farei in questo modo. Se il valore può essere nullo, farei in modo che il modello di editor abbia il valore nulla booleano come tipo di modello. Quindi il tuo modello di editor (in Views \ Shared \ EditorTemplates \ Boolean.cshtml) sarebbe:

@model Boolean? 

@Html.CheckBox("", Model.HasValue && Model.Value) 

E poi nel rasoio di visualizzazione principale, si potrebbe avere:

<div class="control-group"> 
    <div class="controls"> 
     <label class="checkbox"> 
      @Html.EditorFor(m => m, new {@class = "checkbox"}) 
      @Html.LabelFor(m => m) 
     </label> 
    </div> 
</div> 
+0

Mi piace questo approccio. Il valore booleano normalmente non può essere nullo (non nell'oggetto del modello che stavo usando in ogni caso), ma penso che questo approccio gli permetterebbe di lavorare con il modo MVC standard di chiamare la vista come piuttosto che creare un nuovo oggetto modello vuoto . NOTA: In realtà penso che questa sia una risposta reale alla mia domanda originale, la mia risposta è stata una soluzione alternativa. –

-1

È necessario inizializzare il numero RememberMebool value all'interno del costruttore, come mostrato di seguito.

Ricordare che l'uso di variabili non inizializzate in C# non è consentito.

using System.ComponentModel; 

public class ClassName 
{  
    public ClassName() 
     { 
      RememberMe = false; 
     } 

    [DefaultValue(false)] 
    [Display(Name = "Remember me?")] 
    public bool RememberMe { get; set; } 
} 

Per ulteriori controllo infromation Default Values Table

Spero che questo vi aiuterà a voi.

+3

tipi di riferimento ha solo 'null' come valore di default. Bool è un tipo di valore e il valore predefinito di [bool è falso.] (Http://msdn.microsoft.com/en-us/library/vstudio/83fhsxwc.aspx). OP ha una semplice proprietà 'bool' un bool non annullabile (ad esempio' bool? '). – nemesv

+0

@nemesv Grazie per la correzione. Ho aggiornato il mio post. – Sampath

+0

La mia impressione era che bool avesse un valore predefinito di false. Ad ogni modo, ho provato entrambe le impostazioni su false in constructor e la proprietà DefaultValue con gli stessi risultati di prima. Mi chiedo se ho solo qualcos'altro che non va con il modello. Quando l'ho inserito direttamente nel codice con @ Html.ComboBoxFor, funziona perfettamente, quindi il bool è impostato. –

0

Leggendo le risposte finora, ho iniziato a chiedermi come inizializzare l'oggetto modello. Quindi questo è piuttosto strano, ma ho trovato la risposta. Spero che qualcuno possa spiegare la stranezza. Potrebbe essere come MVC inizializza un oggetto modello se non ne specifichi uno.

predefinito nel modello MVC Internet ha la seguente per l'azione Login:

[AllowAnonymous] 
public ActionResult Login(string returnUrl) 
{ 
    ViewBag.ReturnUrl = returnUrl; 

    return View(); 
} 

Questo dà l'errore. La modifica al seguente però, risolve il problema:

[AllowAnonymous] 
public ActionResult Login(string returnUrl) 
{ 
    var loginModel = new LoginModel(); 

    ViewBag.ReturnUrl = returnUrl; 

    return View(loginModel); 
} 

Quindi questo risponde alla domanda su come risolvere il problema, ma lascia ancora irrisolto il motivo. Potrebbe essere perché MVC crea un'istanza dell'oggetto in un modo diverso, ad esempio con una riflessione o qualcosa del genere?

+0

Sembra che nel primo esempio NON si imposti un modello di vista, ma la tua Vista ne sta aspettando una ... e quindi le proprietà (e il modello) sono tutte nulle. Controlla attentamente l'errore poiché mi aspetto che il null sia sul modello e non sulla proprietà stessa. Secondo esempio, stai istanziando esplicitamente il modello di vista, quindi il mondo è un buon posto. – BlueChippy

+0

Sì, sembra essere quello che sta succedendo. Questo primo bit è il codice del modello MVC predefinito e funziona normalmente. Suppongo che MVC crei il modello di visualizzazione da qualche parte lungo il percorso, ma non abbastanza presto per il modello personalizzato. –

+0

La differenza è che MVC3 EditorFor <> è un metodo di estensione in 'public static class EditorExtensions' che restituisce' MvcHtmlString'. Ciò significa che su un valore nullo può gestirlo e restituire la casella vuota. Il mio suggerimento: a) continua con quello che hai ... puoi anche aggiungere returnUrl al modello se preferisci. b) nella vista, aggiungi un blocco @code e imposta un bool locale per la casella di controllo. c) aggiungi un editor come metodo di estensione personale che restituisce mvchtmlstring. Infine: qual è la ragione per cui si ignora EditorFor con il proprio modello di editor? Può essere fatto con css, invece? – BlueChippy

0

Si potrebbe cambiare il proprio modello in modo che accetti i valori nulli come "sì" /" no"

public bool? RememberMe { get; set; } 
Problemi correlati