[ASP.net MVC] Edit Action met references naar ander model

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • jvaneijk
  • Registratie: Mei 2003
  • Laatst online: 29-05 12:10
Hoi allemaal,

Ik zit met een grote uitdaging en blijkbaar nog te weinig kennis van ASP MVC.

Ik heb een Product welke een referentie heeft naar een Productgroup
Nu heb ik een Edit die netjes alles update maar als ik de waarde van mijn DropDownList verander wordt deze niet geupdate. Hieronder mijn code welke voor de update zou moeten zorgen dit werkt netjes als je maar een enkel Object moet editen welke geen reference heeft naar andere modellen maar als je een Object met references naar andere modellen moet updaten is het blijkbaar niet voldoende.

Als ik een breakpoint zet op mijn post method dan zijn Manufacturer en Productgroup null.

Action: Edit
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public ActionResult Edit(int id)
        {
            ViewData["ManufacturerList"] = new SelectList(_entities.Manufacturer.ToList(), "manufacturerID", "manufacturerName");
            ViewData["ProductgroupList"] = new SelectList(_entities.Productgroup.ToList(), "productgroupID", "productgroupName");

            var productToEdit = (from p in _entities.Product.Include("Productgroup").Include("Manufacturer")
                                 where p.productID == id
                                 select p).First();
            
            return View(productToEdit);
        }

        //
        // POST: /Product/Edit/5

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Edit(Product productToEdit)
        {
            ViewData["ManufacturerList"] = new SelectList(_entities.Manufacturer.ToList(), "manufacturerID", "manufacturerName");
            ViewData["ProductgroupList"] = new SelectList(_entities.Productgroup.ToList(), "productgroupID", "productgroupName");

            
            try
            {
                var originalProduct = (from p in _entities.Product.Include("Manufacturer").Include("Productgroup")
                                       where p.productID == productToEdit.productID
                                       select p).First();

                _entities.ApplyPropertyChanges(originalProduct.EntityKey.EntitySetName, productToEdit);
                _entities.SaveChanges();
                return RedirectToAction("Index");
            }
            catch
            {
                return View();
            }
        }


View: Edit
HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<% using (Html.BeginForm()) {%>

        <fieldset>
            <legend>Fields</legend>
            <p>
                <label for="productID">productID:</label>
                <%= Html.TextBox("productID", Model.productID) %>
                <%= Html.ValidationMessage("productID", "*") %>
            </p>
            <p>
                <label for="productName">Product:</label>
                <%= Html.TextBox("productName", Model.productName) %>
                <%= Html.ValidationMessage("productName", "*") %>
            </p>
            <p>
                <label for="productDescription">Description:</label>
                <%= Html.TextBox("productDescription", Model.productDescription) %>
                <%= Html.ValidationMessage("productDescription", "*") %>
            </p>
            <p>
                <label for="Manufacturer">Manufacturer:</label>
                <%= Html.DropDownList("Manufacturer", (IEnumerable<SelectListItem>)ViewData["ManufacturerList"], Model.Manufacturer.manufacturerID)%>
                <%= Html.ValidationMessage("Manufacturer", "*")%>
            </p>
            <p>
                <label for="Productgroup">Productgroup:</label>
                <%= Html.DropDownList("Productgroup", (IEnumerable<SelectListItem>)ViewData["ProductgroupList"], Model.Productgroup.productgroupID)%>
                <%= Html.ValidationMessage("Productgroup", "*")%>
            </p>
            <p>
                <label for="productWarranty">Warranty:</label>
                <%= Html.TextBox("productWarranty", Model.productWarranty) %>
                <%= Html.ValidationMessage("productWarranty", "*") %>
            </p>
            <p>
                <label for="Price">Price:</label>
                <%= Html.TextBox("Price", String.Format("{0:F}", Model.Price)) %>
                <%= Html.ValidationMessage("Price", "*") %>
            </p>
            <p>
                <label for="active">Active:</label>
                <%= Html.CheckBox("active", Model.active) %>
                <%= Html.ValidationMessage("active", "*") %>
            </p>
            <p>
                <input type="submit" value="Save" />
            </p>
        </fieldset>

    <% } %>


Nu heb ik al gezocht hoe je een model can updaten met references in ASP.net maar kan niets vinden.. Heb eerlijk gezegd ook niet een goed idee hoe ik dat zou moeten noemen, en hoop dus dat iemand mij kan helpen hiermee, ben er namelijk al 3 dagen mee bezig :(

iRacing Profiel


Acties:
  • 0 Henk 'm!

  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Zijn ProductGroup en Manufacturer public fields, of hebben ze een getter en setter. Dat schijnt uit te maken.

Hetzelfde artikel raadt ook aan om je je ViewModel als een aparte class te benoemen. Je viewmodel kun je vervolgens middels generics aan je view koppelen, wat via de MVC "add view" wizard in Visual Studio natuurlijk mega makkelijk automagisch te doen is.

[ Voor 11% gewijzigd door bigbeng op 30-07-2009 14:43 ]


Acties:
  • 0 Henk 'm!

  • jvaneijk
  • Registratie: Mei 2003
  • Laatst online: 29-05 12:10
bigbeng schreef op donderdag 30 juli 2009 @ 14:41:
Zijn ProductGroup en Manufacturer public fields, of hebben ze een getter en setter. Dat schijnt uit te maken.

Hetzelfde artikel raadt ook aan om je je ViewModel als een aparte class te benoemen. Je viewmodel kun je vervolgens middels generics aan je view koppelen, wat via de MVC "add view" wizard in Visual Studio natuurlijk mega makkelijk automagisch te doen is.
Ze hebben een getter en setter die beide public zijn. Ik moet er wel even bijzeggen dat ik complete noob ben op het gebied van ASP.net en MVC. En snap ook niet echt hoe ik een customViewModel moet maken..

iRacing Profiel


Acties:
  • 0 Henk 'm!

  • TheNameless
  • Registratie: September 2001
  • Laatst online: 07-02 21:38

TheNameless

Jazzballet is vet!

Komt waarschijnlijk door deze 2 statements:
C#:
1
2
3
<%= Html.DropDownList("Manufacturer", (IEnumerable<SelectListItem>)ViewData["ManufacturerList"], Model.Manufacturer.manufacturerID)%> 

<%= Html.DropDownList("Productgroup", (IEnumerable<SelectListItem>)ViewData["ProductgroupList"], Model.Productgroup.productgroupID)%> 


Helpt het als je er het volgende van maakt? Zoja, dan zal ik het daarna proberen uit te leggen :)
C#:
1
2
3
<%= Html.DropDownList("Manufacturer.manufacturerID", (IEnumerable<SelectListItem>)ViewData["ManufacturerList"], Model.Manufacturer.manufacturerID)%> 

<%= Html.DropDownList("Productgroup.productgroupID", (IEnumerable<SelectListItem>)ViewData["ProductgroupList"], Model.Productgroup.productgroupID)%> 


Tevens deze tip:
C#:
1
2
3
<%= Html.TextBox("productID", Model.productID) %> 
//is hetzelfde als:
<%= Html.TextBox("productID") %> 

Wat MVC hier doet tijdens het renderen is kijken of er een property bestaat op je Model met de naam: 'productID'. Zoja, dan gebruikt hij deze waarde voor je textbox. Scheelt weer typen :)


Verder nog een opmerking; waarom vul je de ViewData dictionary in je POST methode?

[ Voor 16% gewijzigd door TheNameless op 30-07-2009 20:00 ]

Ducati: making mechanics out of riders since 1946


Acties:
  • 0 Henk 'm!

  • jvaneijk
  • Registratie: Mei 2003
  • Laatst online: 29-05 12:10
TheNameless schreef op donderdag 30 juli 2009 @ 19:48:
Komt waarschijnlijk door deze 2 statements:
C#:
1
2
3
<%= Html.DropDownList("Manufacturer", (IEnumerable<SelectListItem>)ViewData["ManufacturerList"], Model.Manufacturer.manufacturerID)%> 

<%= Html.DropDownList("Productgroup", (IEnumerable<SelectListItem>)ViewData["ProductgroupList"], Model.Productgroup.productgroupID)%> 


Helpt het als je er het volgende van maakt? Zoja, dan zal ik het daarna proberen uit te leggen :)
C#:
1
2
3
<%= Html.DropDownList("Manufacturer.manufacturerID", (IEnumerable<SelectListItem>)ViewData["ManufacturerList"], Model.Manufacturer.manufacturerID)%> 

<%= Html.DropDownList("Productgroup.productgroupID", (IEnumerable<SelectListItem>)ViewData["ProductgroupList"], Model.Productgroup.productgroupID)%> 


Tevens deze tip:
C#:
1
2
3
<%= Html.TextBox("productID", Model.productID) %> 
//is hetzelfde als:
<%= Html.TextBox("productID") %> 

Wat MVC hier doet tijdens het renderen is kijken of er een property bestaat op je Model met de naam: 'productID'. Zoja, dan gebruikt hij deze waarde voor je textbox. Scheelt weer typen :)


Verder nog een opmerking; waarom vul je de ViewData dictionary in je POST methode?
Helaas maakt het niets uit om van manufacturerID Manufacturer.manufacturerID te maken wat betreft die textbox, dat wist ik al maar VS.net genereerd dit zo en heb nog niet echt want vond het wel mooi zo.

iRacing Profiel


Acties:
  • 0 Henk 'm!

  • TheNameless
  • Registratie: September 2001
  • Laatst online: 07-02 21:38

TheNameless

Jazzballet is vet!

Je POST action heeft een object nodig van het type Product.
Dit betekend dat MVC de System.Web.MVC.DefaultModelBinder gaat gebruiken om van je POST variabelen een instantie van Product te maken.

De DefaultModelBinder kan complexe geneste klasses binden, maar kan dat alleen op property niveau (vandaar dat je Manufacturer en Productgroup ook een property moet zijn).
Tevens moeten alle klasses die hij moet instantieren dan ook een default constructor hebben.

Daarom kwam ik met het idee om je textbox naam van "Manufacturer" te veranderen naar "Manufacturer.manufacturerID", omdat deze textbox de manufacturerID waarde bevat en niet de gehele Manufacturer klasse.

Wat je kan doen is je ModelState inspecteren in je POST action. Als de DefaultModelBinder problemen heeft binden dan zou hij de details in je ModelState moeten melden. Hier heb ik zelf (nog) geen ervaring mee.

Ducati: making mechanics out of riders since 1946

Pagina: 1