2012-06-21 16 views
5

Arriva su asp.net MVC 4 da uno sfondo in Rails e sto avendo qualche problema a capire come gestire i modelli annidati.ASP.NET MVC 4 - Modelli annidati - Come impostare le associazioni appropriate?

Sto utilizzando Entity Framework 4.3 con un approccio CodeFirst.

L'applicazione è abbastanza semplice e ha un modello diSet - che ha molti Franchises. E ha un modello in franchising - che appartiene a Sets.

Le classi POCO sono state create insieme alle proprietà di navigazione appropriate, quindi ho impalcato i controller con le viste, quindi generato il database.

Qui ci sono le classi:

Set

namespace FranchiseManagerTest.Models 
    { 
     public class Set 
     {   
      [Key] 
      public int SetID { get; set; } 
      public string SetName { get; set; } 
      public string MainAddress { get; set; } 
      public string TimeZone { get; set; }  
      public virtual ICollection<Franchise> Franchises { get; set; } 
     } 
    } 

Franchise

namespace FranchiseManagerTest.Models 
{ 
    public class Franchise 
    { 
     [Key] 
     public int FranchiseID { get; set; }   
     public int SetID { get; set; } 
     public string FranchiseName { get; set; } 
     public string FranchiseNumber { get; set; }  

     public virtual Set Set { get; set; } 

    } 
} 

Poi ho creato alcuni set di franchising di prova e Franchising.

Qui è la vista principale:

enter image description here

Il progetto richiede che tutti Franchising relativi a un set sono visibili all'interno del relativo insieme. Inoltre, devo essere in grado di aggiungere un Franchise ad un Set mentre sono nei dettagli del Set.

ho creato uno screenshot per illustrare come si presenta dopo aver fatto clic su "dettagli" sulla vista principale:

enter image description here

Il pulsante Nuovo Franchise viene creato con un ActionLink che assomiglia a questo:

@Html.ActionLink("New Franchise", "Create", "Franchise", null, new { @class = "btn btn-large btn-primary" }) 

questo mi porta al franchise Crea pagina che assomiglia a questo:

enter image description here

Il problema, come si può vedere, è che il menu a discesa che dovrebbe contenere il relativo Set modello non è pre-popolato - invece devo fare clic sul menu a discesa e selezionare nuovamente il set che io sono già . in

la discesa è essere popolata - ma da tutti i gruppi esistenti - al posto del set che sono dentro di.

Ecco l'elenco a discesa quando clicco su di esso:

enter image description here

All'interno del Franchise Crea vista, questo è ciò che la discesa e la sua etichetta assomigliano:

 <div class="editor-label"> 
      @Html.LabelFor(model => model.SetID, "Set") 
     </div> 
     <div class="editor-field"> 
      @Html.DropDownList("SetID", String.Empty) 
      @Html.ValidationMessageFor(model => model.SetID) 
     </div> 

Ecco cosa ho provato:


ho tentato di passare in un setId valore alla vista utilizzando l'ActionLink:

@Html.ActionLink("New Franchise", "Create", "Franchise", Model.SetID, new { @class = "btn btn-large btn-primary" }) 

Allora ho provato a modificare l'attributo String.Empty della vista Crea per questo:

<div class="editor-label"> 
     @Html.LabelFor(model => model.SetID, "Set") 
    </div> 
    <div class="editor-field"> 
     @Html.DropDownList("SetID", Model.SetID) 
     @Html.ValidationMessageFor(model => model.SetID) 
    </div> 

Tuttavia, questo non ha funzionato e generato un errore argomento non valido.

Ecco un possibile indizio

Quando visito la vista Crea franchising dal set associata che mi trovo, qui è ciò che l'URL assomiglia (o un altro problema?):

enter image description here

Parto dal presupposto che se le associazioni tra Impostare e Franchise erano corrette, e quando sono andato per aggiungere un franchising all'interno di un set, che l'URL loo k:

localhost:52987/Set/1/Franchise/Create 

È un'ipotesi errata da fare - è possibile farlo in .NET MVC?

Qualsiasi consiglio qui è molto apprezzato!


EDITS


Ecco i percorsi nel mio file Global.asax se questo è utile:

public static void RegisterRoutes(RouteCollection routes) 
     { 
      routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 

      routes.MapHttpRoute(
       name: "DefaultApi", 
       routeTemplate: "api/{controller}/{id}", 
       defaults: new { id = RouteParameter.Optional } 
      ); 

      routes.MapRoute(
       name: "Default", 
       url: "{controller}/{action}/{id}", 
       defaults: new { controller = "Set", action = "Index", id = UrlParameter.Optional } 
      ); 
     } 

come richiesto - qui ci sono sia il GET e POST Creare metodi del Franchise Controller:

// 
    // GET: /Franchise/Create 

    public ActionResult Create() 
    { 
     ViewBag.SetID = new SelectList(db.Sets, "SetID", "SetName"); 
     return View(); 
    } 

    // 
    // POST: /Franchise/Create 

    [HttpPost] 
    public ActionResult Create(Franchise franchise) 
    { 
     if (ModelState.IsValid) 
     { 
      db.Franchises.Add(franchise); 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 

     ViewBag.SetID = new SelectList(db.Sets, "SetID", "SetName", franchise.SetID); 
     return View(franchise); 
    } 

Fammi sapere se più codice sarà utile.

+0

Che aspetto ha il tuo metodo FranchiseController.Create? – StriplingWarrior

+0

Hey Stripling - Ho aggiunto il codice del controller alla sezione Modifica del mio OP. Potrebbe benissimo essere qualcosa con il controller, ma non sono sicuro di cosa. Ho provato a inserire un parametro per SetID nel metodo GET Create, ma senza fortuna. Di nuovo - sono sicuro che sto sbagliando. Ho rimosso il parametro e questo è quello che sembra ora. – PhillipKregg

+1

È necessario modificare il metodo Create come suggerito da justinb138. Deve prendere un parametro 'SetID' in modo che quello che lo passi dal link possa essere usato come valore predefinito nel menu a discesa. (potresti persino voler usare un input nascosto per quel valore invece di un menu a discesa, a meno che non ti aspetti che le persone cambino il franchising) – StriplingWarrior

risposta