.Net MVC 3 - Editor For en struct

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Guillome
  • Registratie: Januari 2001
  • Niet online
Ik ben bezig met .net in het MVC 3 framework.

Ik heb dit model:
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
public class Person
    {
        public virtual int Id { get; set; }
        public virtual PersonName Name { get; set; }
    }

    public struct PersonName
    {
        public PersonName(string firstName, string middleName, string lastName) : this()
        {
            FirstName = firstName;
            MiddleName = middleName;
            LastName = lastName;
        }

        public string FirstName { get; private set; }
        public string MiddleName { get; private set; }
        public string LastName { get; private set; }
    }
public class NamePrinter
{
        public string GetName(PersonName name)
        {
            string Output = name.FirstName;
            if (!String.IsNullOrEmpty(name.MiddleName))
                Output += " " + name.MiddleName;
            Output += " " + name.LastName;
            return Output;
        }
}


En ik wil dit editable maken. Echter het probleem is nu dat hij de struct niet mee stuurt met de postrequest.
De Id wordt wel gevuld, maar de rest niet.

Controller + View:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public ActionResult Edit(int id)
        {
            var session = db.connect();

            var person = session.Get<Person>(id);
            return View(person);
        }
        [HttpPost]
        public ActionResult Edit(int id, Person person)
        {
            // Om te testen alleen de view weer herladen met de postgegevens
            //TryUpdateModel<Person>(person);
            //return person.Name.FirstName;
            return View(person);
        }

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@model NHibernateTest.Models.Person
..
@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>Person</legend>

        @Html.HiddenFor(model => model.Id)
        
        @Html.EditorFor(model => model.Name)
                
        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
}


Wat doe ik fout? Hij pakt de struct niet mee, zoveer lijkt het. Ik kan op google helaas niets vinden, en de tutorials gebruiken geen structs icm databasebewerking.

edit:
Even wat aanvullende gegevens:
Als ik een losse property onder Id zet in person:
C#:
1
public virtual string NameRaw { get; set; }

Dan komt die wel goed over als ik daarvoor ook een Html.EditorFor voor aanmaak.

En de variabelen uit de struct komen wél over als ik dit in de view zet:
code:
1
    @Request.Form["Name.FirstName"];


Maar met Html.EditorFor(model => model.Name) pakt ie m dus niet

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Even een quick-check: werkt het wel als je een class maakt van die struct?

[ Voor 4% gewijzigd door CodeCaster op 18-09-2011 18:20 ]

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Acties:
  • 0 Henk 'm!

  • Guillome
  • Registratie: Januari 2001
  • Niet online
Even zien

Edit:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    public class PersonName
    {
        public PersonName() { }
        public PersonName(string firstName, string middleName, string lastName)
        {
            FirstName = firstName;
            MiddleName = middleName;
            LastName = lastName;
        }

        public string FirstName { get; private set; }
        public string MiddleName { get; private set; }
        public string LastName { get; private set; }
    }


Werkt ook niet.
Ik moest een argument-loze constructor maken, waarom weet ik eerlijk gezegd nog niet :$

[ Voor 114% gewijzigd door Guillome op 19-09-2011 11:17 ]

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


Acties:
  • 0 Henk 'm!

  • alwinuzz
  • Registratie: April 2008
  • Laatst online: 25-09 19:05
Omdat MVC anders niet weet hoe die je PersonName moet maken.

Je kan vast wel iets aanpassen aan MVC dat het zonder default constructor werkt, maar de vraag is of je al die moeite wil doen :P

Acties:
  • 0 Henk 'm!

  • Guillome
  • Registratie: Januari 2001
  • Niet online
Nee de vraag is hoe het wel kan werken met een struct/class ;)

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


Acties:
  • 0 Henk 'm!

  • Rockafello
  • Registratie: Maart 2005
  • Laatst online: 27-12-2023
Volgens mij moet je een eigen EditorTemplate maken voor PersonName.

Acties:
  • 0 Henk 'm!

  • Guillome
  • Registratie: Januari 2001
  • Niet online
Bedoel je met een editortemplate een partial view voor dat model in de shared/EditorTemplates map?

Edit: als ik in de controller bij [HttpPost] edit als parameter FormCollection doe, staan daar wel alle gegevens in.
Maar dan als "Name.FirstName" etc. Die worden dus niet omgezet door de EditorFor functie.
Nu zou ik dat wel handmatig kunnen doen, maar mijn gevoel zegt dat ik iets niet weet of niet goed doe, want daar heeft het MVC framework vast wel iets voor.

TryUpdateModel werkt niet, hij blijft leeg.
C#:
1
2
            var person = new Person();
            TryUpdateModel(person, collection.ToValueProvider());

In enkele variaties

[ Voor 74% gewijzigd door Guillome op 18-09-2011 21:24 ]

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


Acties:
  • 0 Henk 'm!

  • alwinuzz
  • Registratie: April 2008
  • Laatst online: 25-09 19:05
Maar waarom gebruik je niet gewoon een class met default constructor? Waarom wil je een struct gebruiken?

Acties:
  • 0 Henk 'm!

  • Megamind
  • Registratie: Augustus 2002
  • Laatst online: 10-09 22:45
Een eigen class (struct weet ik niet) posten gaat niet zomaar, MVC kan niet ruiken wat jij wilt, je zal een modelbinder moeten maken: http://buildstarted.com/2...-mvc-3-with-imodelbinder/

Acties:
  • 0 Henk 'm!

  • HMS
  • Registratie: Januari 2004
  • Laatst online: 21-08 23:06

HMS

Probeer de setters eens public te maken, grote kans dat het dan wel werkt. Het ligt aan het gebruik van een custom constructor om je object te initialiseren, en niet gewoon rechtstreeks aan velden binden. Dus zul je inderdaad een modelbinder voor je value type class / struct moeten gaan maken.


edit:
even verduidelijkt

[ Voor 25% gewijzigd door HMS op 18-09-2011 23:52 ]


Acties:
  • 0 Henk 'm!

  • Rockafello
  • Registratie: Maart 2005
  • Laatst online: 27-12-2023
Guillome schreef op zondag 18 september 2011 @ 21:08:
Bedoel je met een editortemplate een partial view voor dat model in de shared/EditorTemplates map?
Jep die bedoel ik. alhoewel het niet in de shared hoeft, maar mag ook in je View/EditorTemplates komen.

Ook de genoemde modelbinder is een goede optie om je model weer correct te posten.

Acties:
  • 0 Henk 'm!

  • Guillome
  • Registratie: Januari 2001
  • Niet online
Bedankt, ik ga er mee aan de slag! :) Ik laat het resultaat wel weten hier

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


Acties:
  • 0 Henk 'm!

  • creator1988
  • Registratie: Januari 2007
  • Laatst online: 25-09 20:02
MVC doet dingen by convention. Een daarvan is dat je classes gebruikt en geen structs voor je view models. Dus maak er een class van, voeg een parameterless constructor toe en maak je setters publiek; want dat scheelt een hele hoop custom code.

[ Voor 5% gewijzigd door creator1988 op 19-09-2011 10:48 ]


Acties:
  • 0 Henk 'm!

  • Guillome
  • Registratie: Januari 2001
  • Niet online
Ik heb juist geleerd dat je structs gebruikt voor identiteit-loze objecten, zoals in dit geval de name.
Het heeft geen ID nodig, het is gewoon een datamodel zeg maar. Dus gebruik je een struct.
Dat heb ik uit 3dbuzz video`s en andere turorials. Scheelt geheugengebruik.

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 10:32

Haan

dotnetter

Het gebruik van structs vs. classes is imo een groot grijs gebied. Persoonlijk gebruik ik eigenlijk nooit structs. Daarbij is MVC.Net zoals creator1988 al zegt gebaseerd op 'convention over configuration', wat je een hoop gedoe scheelt, mits je je aan die conventies houdt.

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

  • creator1988
  • Registratie: Januari 2007
  • Laatst online: 25-09 20:02
Haan schreef op maandag 19 september 2011 @ 11:08:
Het gebruik van structs vs. classes is imo een groot grijs gebied. Persoonlijk gebruik ik eigenlijk nooit structs. Daarbij is MVC.Net zoals creator1988 al zegt gebaseerd op 'convention over configuration', wat je een hoop gedoe scheelt, mits je je aan die conventies houdt.
/met Haan

Bovendien scheelt een struct vs. een class 1 pointer per instance, dus dat is meestal 4 bytes. Voor short living objects als view models dus een besparing van niets.

[ Voor 6% gewijzigd door creator1988 op 19-09-2011 11:10 ]


Acties:
  • 0 Henk 'm!

  • Guillome
  • Registratie: Januari 2001
  • Niet online
Ok, thanks voor de informatie :) Dan ga ik het ombouwen naar een class.

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 26-09 17:09
creator1988 schreef op maandag 19 september 2011 @ 10:48:
MVC doet dingen by convention. Een daarvan is dat je classes gebruikt en geen structs voor je view models. Dus maak er een class van, voeg een parameterless constructor toe en maak je setters publiek; want dat scheelt een hele hoop custom code.
Ik ben geen MVC kenner, maar dit vind ik maar een ranzige workaround om het snel werkend te krijgen.
In het voorbeeld van de TS, is 'Name' een value object, en is het an sich een goeie kandidaat om als 'struct' te implementeren ....

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • Guillome
  • Registratie: Januari 2001
  • Niet online
Ja, zo noemde zij het ook, een value object.

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


Acties:
  • 0 Henk 'm!

  • creator1988
  • Registratie: Januari 2007
  • Laatst online: 25-09 20:02
whoami schreef op maandag 19 september 2011 @ 11:13:
[...]

Ik ben geen MVC kenner, maar dit vind ik maar een ranzige workaround om het snel werkend te krijgen.
In het voorbeeld van de TS, is 'Name' een value object, en is het an sich een goeie kandidaat om als 'struct' te implementeren ....
Een struct in MVC kent geen parameterless constructors, dus bij het terugmappen van je geposte data naar een viewmodel kan deze geen nieuw object instantieren. Wil je het met een struct gaan doen dan kan je je eigen mapping logica schrijven maar dan ben je MVC opnieuw aan het schrijven.

Acties:
  • 0 Henk 'm!

  • Guillome
  • Registratie: Januari 2001
  • Niet online
Maar zoals ik al aangaf werkt het met een class ook niet:
Guillome in ".Net MVC 3 - Editor For en struct"

[ Voor 41% gewijzigd door Guillome op 19-09-2011 11:17 ]

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


Acties:
  • 0 Henk 'm!

  • creator1988
  • Registratie: Januari 2007
  • Laatst online: 25-09 20:02
maak je setters public.

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 26-09 17:09
Mja, maar nu ben je uw model aan het verkrachten, om het maar werkend te krijgen met dat framework ...

Men moet natuurlijk niet heiliger willen zijn dan de paus, en het belangrijkste is natuurlijk dat je een werkende applicatie op tijd kunt opleveren, maar, aan de andere kant mag je de kwaliteit ook niet uit het oog verliezen.

Nogmaals, ik ken het ASP.NET MVC framework niet, maar het kan toch zo moeilijk niet zijn om dat werkend te krijgen zonder dat je uw model hoeft aan te passen ?

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • OMX2000
  • Registratie: Januari 2001
  • Laatst online: 26-09 22:38

OMX2000

By any means necessary...

Als ik het zo snel lees, was je in het begin al close. En is het logisch dat je alleen de id terug kreeg. In de Edit methode moet je

Je method signature zou als volgt moeten zijn : public ActionResult Edit(Person person). Dan bind MVC het bij een HTTP post automatisch aan de gegevens uit Model object wat in de view gebruikt wordt.

Dè developers podcast in je moerstaal : CodeKlets Podcast


Acties:
  • 0 Henk 'm!

  • creator1988
  • Registratie: Januari 2007
  • Laatst online: 25-09 20:02
OMX2000 schreef op maandag 19 september 2011 @ 11:33:
Als ik het zo snel lees, was je in het begin al close. En is het logisch dat je alleen de id terug kreeg. In de Edit methode moet je

Je method signature zou als volgt moeten zijn : public ActionResult Edit(Person person). Dan bind MVC het bij een HTTP post automatisch aan de gegevens uit Model object wat in de view gebruikt wordt.
Zijn method signature is prima.

Acties:
  • 0 Henk 'm!

  • Guillome
  • Registratie: Januari 2001
  • Niet online
OMX2000 schreef op maandag 19 september 2011 @ 11:33:
Als ik het zo snel lees, was je in het begin al close. En is het logisch dat je alleen de id terug kreeg. In de Edit methode moet je

Je method signature zou als volgt moeten zijn : public ActionResult Edit(Person person). Dan bind MVC het bij een HTTP post automatisch aan de gegevens uit Model object wat in de view gebruikt wordt.
Helaas, dat heb ik ook al geprobeerd, maar dat werkt niet.

Ik las wel in mijn boek het volgende:
Per class/struct in je model (oftewel: complex types, alles behalve int, string etc) worden inderdaad gepost als ClassName.PropertyName. Dus in mijn geval Name.FirstName.

En nu las ik dat je zoiets moet doen (uit mn hoofd):
C#:
1
2
3
[HttpPost]
public ActionResult Edit(Person person, PersonName Name)
{}


Heb het gisternacht pas gelezen en niet meer kunnen proberen

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 10:32

Haan

dotnetter

Ik zou die properties gewoon lekker in de Person class proppen, in je view kan je ook de volledige naam opbouwen. Of desnoods een viewmodel gebruiken.
Dus zoiets:

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
public class Person
{
    public int Id { get; set; }
    public string Firstname { get; set; }
    public string Middlename { get; set; }
    public string Lastname { get; set; }
}


public class PersonViewModel
{
    private Person _person;

    public PersonViewModel()
    {
    }

    public PersonViewModel(Person person)
    {
        _person = person;
    }

    private string _fullname;
    public string Fullname
    {
        get
        {
            return string.Format("{0} {1}{2}", 
                                    _person.Firstname,
                                    string.IsNullOrEmpty(_person.Middlename) ? string.Empty : _person.Middlename + " ",
                                    _person.Lastname);
        }
        set { _fullname = value; }
    }
}

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

  • Guillome
  • Registratie: Januari 2001
  • Niet online
Dat is het probleem omzeilen en niet oplossen ;)
Dit is namelijk een voorbeeld, dit wordt straks gebruikt voor gevallen waar je niet even alles in 1 class kan gooien.

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


Acties:
  • 0 Henk 'm!

  • creator1988
  • Registratie: Januari 2007
  • Laatst online: 25-09 20:02
Guillome schreef op maandag 19 september 2011 @ 11:57:
Dat is het probleem omzeilen en niet oplossen ;)
Dit is namelijk een voorbeeld, dit wordt straks gebruikt voor gevallen waar je niet even alles in 1 class kan gooien.
Allemaal leuk en aardig, maar ook complex binding werkt hier prima met de default binder van MVC zolang je maar view models gebruikt.

Acties:
  • 0 Henk 'm!

  • Rockafello
  • Registratie: Maart 2005
  • Laatst online: 27-12-2023
Ik heb het even snel in elkaar gezet, struct wordt (nog) niet ondersteund in Entity Framework.

*snip*

[ Voor 22% gewijzigd door Woy op 20-09-2011 08:55 ]


Acties:
  • 0 Henk 'm!

  • Guillome
  • Registratie: Januari 2001
  • Niet online
Het werkt!! Als ik de setters in de structs maar niet op private zet. In de classes wel, maar in structs dus niet.
Dus het wordt wel ondersteund :)

Thanks rockafello voor je moeite!!

[ Voor 11% gewijzigd door Guillome op 19-09-2011 19:06 ]

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


Acties:
  • 0 Henk 'm!

  • Woy
  • Registratie: April 2000
  • Niet online

Woy

Moderator Devschuur®
Rockafello schreef op maandag 19 september 2011 @ 18:35:
Ik heb het even snel in elkaar gezet, struct wordt (nog) niet ondersteund in Entity Framework.

*snip*
Het is misschien goed bedoeld, maar we zien liever niet dat er op een externe plek complete solutions aangeboden worden. Liever hebben we gewoon een klein stukje code met de kern van de oplossing in je post, dat werkt namelijk over een paar jaar ook nog, op het moment dat iemand anders naar een vergelijkbare oplossing aan het zoeken is.

“Build a man a fire, and he'll be warm for a day. Set a man on fire, and he'll be warm for the rest of his life.”


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
whoami schreef op maandag 19 september 2011 @ 11:24:
Mja, maar nu ben je uw model aan het verkrachten, om het maar werkend te krijgen met dat framework ...

Men moet natuurlijk niet heiliger willen zijn dan de paus, en het belangrijkste is natuurlijk dat je een werkende applicatie op tijd kunt opleveren, maar, aan de andere kant mag je de kwaliteit ook niet uit het oog verliezen.

Nogmaals, ik ken het ASP.NET MVC framework niet, maar het kan toch zo moeilijk niet zijn om dat werkend te krijgen zonder dat je uw model hoeft aan te passen ?
Het zijn view models die gepasst worden via de browser terug de controller in. Waarom zou je -niet- de conventie hanteren? In je domain model kun je vrolijk code bouwen zoals je dat gewend bent. Voor je view models gelden er een paar regels die het framework oplegt. Ben je het daar niet mee eens dan kun je je eigen model binder bouwen.

Ik zie het probleem niet zo..

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 26-09 17:09
Grijze Vos schreef op dinsdag 20 september 2011 @ 09:08:
[...]

Het zijn view models die gepasst worden via de browser terug de controller in. Waarom zou je -niet- de conventie hanteren? In je domain model kun je vrolijk code bouwen zoals je dat gewend bent. Voor je view models gelden er een paar regels die het framework oplegt. Ben je het daar niet mee eens dan kun je je eigen model binder bouwen.
Nee, ik dacht dat het om het domein-model ging. Niet zozeer het View-model.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Het zou kunnen dat de TS die twee niet goed van elkaar gescheiden heeft. Je ziet dat helaas iets te vaak in de MVC voorbeelden die op het net rondzwerven. Als die twee gewoon netjes van elkaar gesepareerd zijn heb je dit soort problemen iig niet.

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


Acties:
  • 0 Henk 'm!

  • Guillome
  • Registratie: Januari 2001
  • Niet online
Dat heb ik gister toevallig gescheiden. Ik had er wel veel over gehoord in het begin, maar later niet meer. En gister schoot het me weer te binnen.

Ik heb nu dus mijn Person en Address classes enzo, en een UserViewModel class waarin ik de data naar mijn view(s) stuur :)

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router

Pagina: 1