2010-09-22 4 views
3

Vous essayez de faire en sorte que UpdateModel fonctionne pour mon utilisateur. La classe User possède des propriétés de chaîne de base comme CompanyName, FirstName, LastName, etc, donc rien d'exotique.ASP.Net MVC Controller UpdateModel non mis à jour

Voici l'en-tête pour moi:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Public.Master" Inherits="System.Web.Mvc.ViewPage<User>" %> 

Après qu'ils soumettent, dans mon contrôleur, le code ressemble à ceci:

[HttpPost] 
    public ActionResult Edit(string id, FormCollection collection) 
    { 
     try 
     { 
      User myUser = db.Get<IUserRepository>().Get(id); 
      UpdateModel(myUser); 
      db.Update(myUser); 

      return RedirectToAction("Index", "Home"); 
     } 
     catch 
     { 
      return View(); 
     } 
    } 

Les valeurs passées dans FormCollection ont les valeurs telles que:

[0] "FirstName" string 
[1] "LastName" string 
[2] "Email" string 

Voici mon UserModelBinder (sorti un certain code de vérification d'erreur) qui semble être t il source du problème:

public class UserModelBinder : IModelBinder 
{ 
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) 
    { 
     IPrincipal p = controllerContext.HttpContext.User; 
     User u = db.Get(p.Identity.Name); 
     return u; 
    } 
} 

tandis que le myUser que je reçois de la base de données a toutes ses valeurs d'origine, le UpdateModel pour mon contrôleur ne fait jamais en fait aucun changement. J'ai lu des problèmes avec les ViewModels et le préfixe à utiliser, mais je ne fais que passer dans l'objet de base de données habituel. La chose étrange est que cette modification de l'utilisateur est pour ma zone "publique" et j'ai déjà une modification de l'utilisateur pour la zone d'administration qui permet à l'administrateur de modifier les propriétés supplémentaires. La zone "Admin" La fonction de modification de l'utilisateur fonctionne correctement, mais la zone "Public" pour la modification de l'utilisateur ne fonctionne pas, même si le code est presque identique.

Mise à jour:

Cela est avéré être un problème de ModelBinding personnalisé et en changeant mon UserModelBinding tirer de DefaultModelBinder et d'ajouter dans ma méthode de bindModel:

if (bindingContext.Model != null) 
      return base.BindModel(controllerContext, bindingContext); 

Tout semble fonctionner.

Répondre

2

Essayez plutôt

public ActionResult Edit(User thisUser) 

Id devra venir d'un champ caché peut-être.

De même, vous devrez vous assurer que les noms de vos champs correspondent aux noms de propriété de l'utilisateur.

Vous ne devriez rien faire d'autre car l'objet devrait avoir les valeurs qu'il contient.

Si ce n'est pas utile alors laissez-moi savoir et je vais supprimer cette réponse

modifier

C'est l'une de mes méthodes de mise à jour

[HttpPost] 
    public ActionResult EditCustomer(Customer customer) 
    { 
     //ensure that the model is valid and return the errors back to the view if not. 
     if (!ModelState.IsValid) 
      return View(customer); 

     //locate the customer in the database and update the model with the views model. 
     Customer thisCustomer = customerRepository.Single(x => x.CustomerID == customer.CustomerID); 
     if (TryUpdateModel<Customer>(thisCustomer)) 
      customerRepository.SaveAll(); 
     else 
      return View(customer); 

     //return to the index page if complete 
     return RedirectToAction("index"); 
    } 

modifier 2

mon classeur modèle personnalisé

public class CustomContactUsBinder : DefaultModelBinder 
    { 
     protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext) 
     { 
      ContactFormViewModel contactFormViewModel = bindingContext.Model as ContactFormViewModel; 

      if (!String.IsNullOrEmpty(contactFormViewModel.Name)) 
       if (contactFormViewModel.Name.Length > 10) 
        bindingContext.ModelState.AddModelError("Name", "Name is too long. Must be less than 10 characters."); 

      base.OnModelUpdated(controllerContext, bindingContext); 
     } 
    } 
+0

Eh bien, l'identifiant de chaîne provient de l'URL de l'édition: – enantiomer2000

+0

J'avais précédemment configuré ModelBinding for User. Cela pourrait-il affecter la façon dont l'utilisateur est transmis et comment UpdateModel l'affecterait? J'ai remarqué que l'utilisateur étant passé est certainement celui de la base de données (à partir du ModelBinder que j'ai créé). – enantiomer2000

+0

Griegs, votre méthode semble fonctionner, mais seulement si je supprime la classe personnalisée UserModelBinder de la liste ModelBinders dans le global.asax. J'ai un peu aimé pouvoir faire passer mon instance User automatiquement, plutôt qu'un IPrincipal. Quelqu'un at-il des idées sur la façon de faire ce travail avec ma façon originale? – enantiomer2000

2

Ce blog post ressemble à cela résout votre problème exact:

UpdateModel(user, "User"); 

Comme il semble que les données que vous souhaitez lier est préfixé par le nom de viewmodel.

+1

Si ce serait préfixé le FormCollection contiendrait des clés comme User.FirstName et User.LastName –

+0

Henrik est correct et j'ai déjà essayé cela en vain. Je pense que cela peut avoir quelque chose à voir avec le ModelBinding personnalisé que j'ai créé pour passer facilement dans mes contrôleurs l'instance User de l'utilisateur authentifié. Enquêter davantage ... – enantiomer2000

+0

Pouvez-vous envoyer votre code ModelBinding personnalisé? – amurra

Questions connexes