2013-02-26 12 views
12

Se ho una vista che ha un modello, consente di dire auto ..distacco ad un altro modello da un modulo in ASP.NET MVC

@model Project.Car 

dentro quella vista io voglio creare un modulo che invia i dati al un nuovo modello di

@using (Html.BeginForm("Add", "Controller")) 
    { 
     @Html.Hidden("ID", "1") 
     @Html.Hidden("UserID", "44") 
     @Html.TextArea("Description") 
    } 

ho notato che se la mia azione è definita con il mio ViewModel che non funziona (il modello è sempre nullo):

[HttpPost] 
    public PartialViewResult Add(ViewModels.NewModel model) 

Tuttavia, se uso un FormCollection funziona:

[HttpPost] 
    public PartialViewResult Add(FormCollection formCollection) 

Ecco il ViewModel:

public class NewModel 
{ 
    public int ID { get; set; } 
    public int UserID { get; set; } 
    public string Description { get; set; } 
} 

La mia domanda è posso inviare dati a NewModel dalla mia forma? La vista su cui si trova è corretta per essere legata a Project.Car. È un piccolo modulo sulla pagina che deve pubblicare un set di dati diverso che non ha nulla a che fare con Project.Car.

+0

Puoi pubblicare anche il ViewModel? – brenton

+0

Certo, l'ho appena aggiunto. – Alex

+0

Ma stai pubblicando un Project.Car. Non è vero? – idipous

risposta

6

Hai una discrepanza tra il nome del modello e la tua azione. Nell'esempio che hai mostrato il modello si chiama Add mentre nella tua azione stai usando ViewModels.NewModel. Ancora peggio, la tua vista è fortemente digitata su un modello chiamato Car. Tutto questo disordinato.

Così inizia definendo una corretta visione del modello:

public class CarViewModel 
{ 
    public int ID { get; set; } 
    public int UserID { get; set; } 
    public string Description { get; set; } 
} 

e poi un controllore:

public class CarsController: Controller 
{ 
    public ActionResult Add() 
    { 
     var model = new CarViewModel 
     { 
      // don't ask me, those are the values you hardcoded in your view 
      ID = 1, 
      UserID = 44, 
     }; 
     return View(model); 
    } 

    [HttpPost] 
    public PartialViewResult Add(CarViewModel model) 
    { 
     ... 
    } 
} 

e una corrispondente vista fortemente tipizzato alla vista del modello:

@model CarViewModel 
@using (Html.BeginForm()) 
{ 
    @Html.HiddenFor(x => x.ID) 
    @Html.HiddenFor(x => x.UserID) 
    @Html.TextAreaFor(x => x.Description) 
    <button type="submit">Add</button> 
} 
+0

Le mie scuse, ho postato questo mentre lavoravo su una funzione rapidamente e ho dovuto cambiare i nomi delle azioni e dei controller per scopi di esempio. Ho corretto il problema. – Alex

1

La visualizzazione è impostata per utilizzare un modello di tipo Project.Cartuttavia il tuo metodo di azione prende un modello di tipo ViewModels.NewModel, ma anche la tua classe di modello pubblicata è di tipo Add?

cambiarli tutti a partita (supponendo Add è corretto):

Vista:

@model Add 

Controller:

[HttpPost] 
public PartialViewResult Add(Add model) 
4
My question is can I post data to NewModel from my form? 

La risposta breve è sì, si può inviare il modulo per qualsiasi azione del controller su qualsiasi controller relativo a qualsiasi modello nella propria applicazione.

Ad esempio, per il modulo di inviare all'azione "Add" sul controller NewModel:

@using (Html.BeginForm("Add", "NewModel")) 
    { 
     @Html.Hidden("ID", "1") 
     @Html.Hidden("UserID", "44") 
     @Html.TextArea("Description") 
    } 

Dal momento che il punto di vista è fortemente tipizzato al modello Car, è possibile cambiare questo e inviare un ViewModel alla vista del tipo descritto il modello di vostro aggiornamento (come Darin demonstrated), o sarà necessario mappare i dati post da Car sul NewModel nel controller:

Sul CarController s' Add azione (Messaggio):

[HttpPost] 
public PartialViewResult Add(Car model) 
{ 
    //now map attribute values from the Car model onto 
    //corresponding attributes of an instance of NewModel 
    NewModel new = new NewModel(); 
    new.ID = model.ID; 
    new.UserID = model.UserID; 
    new.Desc = model.Description; 
    //etc... 

    //update your model/db 
    _db.Add(new); 

    //Redirect however you wish... 
} 

Inoltre, controllare AutoMapper, un mappatore oggetto-oggetto che automatizza mappatura dei ViewModels su modelli e viceversa.

-3

È inoltre possibile creare un raccoglitore modello personalizzato per questo scopo.

2

Sì, è possibile digitare una vista su un modello e inviarlo a un altro modello.

In questo modo si hanno due opzioni:

  1. fornire manualmente nomi corretti per ogni campo di input, in modo che il legante di default lo capirà e creare il modello (example).

    Mentre funziona, significa anche che è necessario tenere d'occhio gli errori di battitura e non si verificheranno errori di compilazione in caso di errore di ortografia nel nome di una proprietà.

  2. Creare manualmente un helper HTML nella vista associata al nuovo tipo di modello. Quindi genererà correttamente l'HTML per te.

    Per costruire l'helper, è necessario un oggetto wrapper che esporrebbe l'istanza del modello nel formato dell'interfaccia IViewDataContainer. È possibile definire che involucro ovunque, tra cui il modello stesso:

    public class NewModel 
    { 
        public int ID { get; set; } 
        public int UserID { get; set; } 
        public string Description { get; set; } 
    
        public class WrapperForHtmlHelper : System.Web.Mvc.IViewDataContainer 
        { 
        public System.Web.Mvc.ViewDataDictionary ViewData { get; set; } 
    
        public WrapperForHtmlHelper(NewModel value) 
        { 
         this.ViewData = new System.Web.Mvc.ViewDataDictionary<NewModel>(value); 
        } 
        } 
    } 
    

    Poi, in vista di creare un aiutante legata a un'istanza di NewModel:

    var ModelToPost = new YourApp.Models.NewModel() { ID = 1, UserID = 43, Description = "" } 
    
    var hlp = new HtmlHelper<YourApp.Models.NewModel> 
         (this.ViewContext, 
          new YourApp.Models.NewModel.WrapperForHtmlHelper(ModelToPost) 
         ); 
    

    e quindi si utilizza l'helper come al solito:

    @hlp.HiddenFor(m => m.ID) 
    @hlp.HiddenFor(m => m.UserID) 
    @hlp.TextAreaFor(m => m.Description) 
    

    Quindi il tuo PartialViewResult Add(ViewModels.NewModel model) riceverà correttamente i dati.

Problemi correlati