ASP.NET MVC5 Identity gebruikers instellingen wijzigen

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Loller1
  • Registratie: April 2011
  • Laatst online: 20-08 12:18
Hallo

Ik ben bezig aan een project in ASP.NET met MVC5, dit is de eerste keer dat ik gebruik maak van deze omgeving. Anyways, ik gebruik Identity voor het maken van gebruikers maar iedere keer dat de instellingen voor de gebruiker op de Settings-pagina worden aangepast en opgeslagen word de PasswordHash en SecurityStamp op null gezet met als gevolg dat gebruikers na uit te loggen niet meer kunnen inloggen. Dit is de code die gebruikt wordt om die instellingen op te slaan:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Settings([Bind(Include = "Id,FirstName,LastName,Title,Email,Description,Interests,FieldId,PhoneNumber,UserName,CompanyId")] User user)
{
if (ModelState.IsValid)
{
db.Entry(user).State = EntityState.Modified;
db.SaveChanges();

return RedirectToAction("Index", new { confirm = "save", Id = System.Web.HttpContext.Current.User.Identity.GetUserId() });
}

ViewBag.FieldId = new SelectList(db.Fields, "FieldId", "Name", user.Field.FieldId);

return View(user);
}


Het is een basic auto-generated (vor het grootste deel) Action. Ik vind zelf niks over waarom dit gebeurd, en hoopte dat iemand hier mij zou kunnen helpen. Ik kan op zich wel met SecurityStamp = Guid.NewGuid().ToString() een nieuwe securityStamp genereren, maar is dit de bedoeling? En dat laat nog steeds het probleem van het resetten van het wachtwoord. Ga ik voor iedere keer dat men die instlelingen wilt aanpassen het wachtwoord moeten vragen?

Alvast bedankt.

Acties:
  • 0 Henk 'm!

  • Rhapsody
  • Registratie: Oktober 2002
  • Nu online

Rhapsody

In Metal We Trust

Volgens mij moet je de user nog toevoegen aan je dbcontext. (db.Attach(user); als het goed is) net voor de db.SaveChanges()

🇪🇺 pro Europa! | Puinhoop Veroorzaken en Vertrekken (PVV)


Acties:
  • 0 Henk 'm!

  • Loller1
  • Registratie: April 2011
  • Laatst online: 20-08 12:18
Als ik db.Users.Attach(user) voor db.SaveChanges() zet (en na db.Entry(user).State = EntityState.Modified;) slaat hij de gegevens niet meer op.

Acties:
  • 0 Henk 'm!

  • Loller1
  • Registratie: April 2011
  • Laatst online: 20-08 12:18
Het probleem lijkt te zijn dat deze code niet de gebruiker aanpast, maar hem geheel overschrijft met een nieuwe gebruiker waarbij alleen de velden die in de Bind zitten worden meegenomen. Weet iemand waarom dit gebeurd?

Acties:
  • 0 Henk 'm!

  • Haan
  • Registratie: Februari 2004
  • Laatst online: 18:46

Haan

dotnetter

Het is sowieso nooit verstandig om input vanaf een formulier direct de database in te knallen. Ze hebben daar dan een trucje voor bedacht om het wat veiliger te maken (het Bind attribuut, dat ik persoonlijk spuuglelijk vind).
Ik zou zelf gewoon een viewmodel gebruiken en deze in de controller mappen naar een database object (gebruik daarvoor eventueel een package als AutoMapper).
Als je viewmodel binnen komt,haal je dus eerst het record op uit de database, daarna map je de velden die je wilt bijwerken, en dan save je weer.

Kater? Eerst water, de rest komt later


Acties:
  • 0 Henk 'm!

  • Mohius
  • Registratie: Oktober 2014
  • Laatst online: 03-09-2024
Ik weet niet precies wat je probeert te bereiken, maar als je gebruikersinstellingen hebt en een gebruikersnaam/wachtwoord combi voor een gebruiker zou ik deze per definitie al niet in een tabel plakken in je database. Je kunt die 2 tabellen, een met de inloggegevens en een met de instellingen via een ID (primary key in de login tabel en een foreign key in de instellingen tabel) aan elkaar hangen.

Acties:
  • 0 Henk 'm!

  • MrTKing
  • Registratie: Oktober 2012
  • Laatst online: 15:41
Zoals Haan al aan gaf, is het makkelijker als je een viewmodel gebruikt. Vervolgens kan je objecten updaten met iets als:

C#:
1
2
3
4
var user = db.Users.FirstOrDefault(x => x.Id == viewmodel.Id);
// viewmodel properties naar user zetten
user.propertyX = viewmodel.PropertyX
db.SaveChanges();


De context detecteerd zelf de changes. Het koppieeren van properties kan ook met een package zoals AutoMapper.

Acties:
  • 0 Henk 'm!

  • Gaius
  • Registratie: September 2001
  • Niet online
Loller1 schreef op zaterdag 27 mei 2017 @ 23:38:
Het probleem lijkt te zijn dat deze code niet de gebruiker aanpast, maar hem geheel overschrijft met een nieuwe gebruiker waarbij alleen de velden die in de Bind zitten worden meegenomen. Weet iemand waarom dit gebeurt?
Yes, MVC is stateless. De instantie die je in je method binnenkrijgt is een nieuwe instantie, en niet degene die je in je view stopt. Hij kan die nieuwe instantie alleen vullen met informatie die je doorgeeft. PasswordHash en SecurityStamp worden blijkbaar niet gevuld in je view, en zullen dus null blijven. Vervolgens stuur je die instantie naar je database en zeg je dat ie alle wijzigingen moet opslaan. Dus ook de null-waarden.

Als je de Razor-syntax in je view gebruikt voor het binden kun je dat oplossen met Html.HiddenFor voor de properties die je niet wilt laten zien, maar waar je wel de waarde van wilt behouden.

Maar beter in dit geval is inderdaad om te doen wat Haan en tagengberink zeggen.

Acties:
  • 0 Henk 'm!

  • Stoelpoot
  • Registratie: September 2012
  • Niet online
Gaius schreef op donderdag 1 juni 2017 @ 15:03:
[...]


Yes, MVC is stateless. De instantie die je in je method binnenkrijgt is een nieuwe instantie, en niet degene die je in je view stopt. Hij kan die nieuwe instantie alleen vullen met informatie die je doorgeeft. PasswordHash en SecurityStamp worden blijkbaar niet gevuld in je view, en zullen dus null blijven. Vervolgens stuur je die instantie naar je database en zeg je dat ie alle wijzigingen moet opslaan. Dus ook de null-waarden.

Als je de Razor-syntax in je view gebruikt voor het binden kun je dat oplossen met Html.HiddenFor voor de properties die je niet wilt laten zien, maar waar je wel de waarde van wilt behouden.

Maar beter in dit geval is inderdaad om te doen wat Haan en tagengberink zeggen.
Volgens mij is het geen goed idee om de hash als hidden property te sturen. Het is dan wel een hash, maar uitlekken is nog steeds niet nodig.

Een ViewModel is inderdaad de makkelijkste manier. Elegant en je kan er ook nog een hoop meer mee IPV automatisch alles maar laten vullen.

Acties:
  • 0 Henk 'm!

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 17:23

gorgi_19

Kruimeltjes zijn weer op :9

Haan schreef op zondag 28 mei 2017 @ 08:25:
Het is sowieso nooit verstandig om input vanaf een formulier direct de database in te knallen. Ze hebben daar dan een trucje voor bedacht om het wat veiliger te maken (het Bind attribuut, dat ik persoonlijk spuuglelijk vind).
Ik zou zelf gewoon een viewmodel gebruiken en deze in de controller mappen naar een database object (gebruik daarvoor eventueel een package als AutoMapper).
Als je viewmodel binnen komt,haal je dus eerst het record op uit de database, daarna map je de velden die je wilt bijwerken, en dan save je weer.
Als je toch bezig bent met AutoMapper te pluggen, kan je ook de EF6 extensions erbij zetten :P
https://github.com/AutoMapper/AutoMapper.EF6

Daar maak je nog eenvoudiger je projectie mee (met viewmodel).

Bind Attribute verdient niet de schoonheidsprijs en lijkt er later ingefietst om under- en overposting te voorkomen. Posting met viewmodels vind ik ook niet altijd even mooi. Meestal splits ik die nog verder op en maak nog een onderscheid tussen viewmodels en commands. In viewmodels zitten bijvoorbeeld ook de zaken die anders in een viewbag zouden zitten.

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Acties:
  • 0 Henk 'm!

  • Neko Koneko
  • Registratie: December 2006
  • Niet online
(overleden)
Ik gebruik voor dit soort zaken een ViewModel en als daarin een bepaald veld leeg is (= niet ingevuld) dan wordt dat veld niet meegenomen bij het updaten en gebruikt hij gewoon de oude waarde. Ik doe sowieso heel veel checks handmatig (die misschien automatisch zouden kunnen) maar ik ben paranoïde dus ik doe het vaak zelf.

End-users are clingy complaining dipshits who will never ever be grateful for any concession you make. The moment you shut out their shrill, tremulous voices, the happier you will be for it.


Acties:
  • 0 Henk 'm!

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 17:23

gorgi_19

Kruimeltjes zijn weer op :9

Neko Koneko schreef op vrijdag 2 juni 2017 @ 09:03:
Ik gebruik voor dit soort zaken een ViewModel en als daarin een bepaald veld leeg is (= niet ingevuld) dan wordt dat veld niet meegenomen bij het updaten en gebruikt hij gewoon de oude waarde. Ik doe sowieso heel veel checks handmatig (die misschien automatisch zouden kunnen) maar ik ben paranoïde dus ik doe het vaak zelf.
Wat vind je handmatig checks uitvoeren?

Daarnaast: alles wat standaard gechecked wordt en gevalideerd wordt met unit testing heeft mijn voorkeur. Handmatig checks uitvoeren roept bij mij het beeld van 'dubbel werk' op, met het risico dat je een aanpassing niet op twee plekken doorvoert en hier dus een risico mee loopt.

Digitaal onderwijsmateriaal, leermateriaal voor hbo

Pagina: 1