2009-09-09 5 views
0

J'ai une méthode get passant dans un objet de type Stocker à la vue, lors de la création de la vue en utilisant la boîte de dialogue de menu (c.-à-d. Créer une vue fortement typée) le formulaire lorsque je choisis le contenu de la vue à éditer. Sans rien changer sur la vue, j'ajoute une méthode post qui accepte un objet store comme paramètre. Les propriétés sur l'objet ne sont jamais remplies avec les données de formulaire et je suis incapable de comprendre pourquoi. Un Request.Form.Count montre 14 éléments qui est correct moins l'Id qui ferait 15. Si je tape chaque paramètre séparément, ils sont réglés. Je peux aussi utiliser la méthode FormCollection pour obtenir les valeurs, mais il serait bien de renvoyer l'objet entier et de l'utiliser.Aide pour passer un objet à l'action de post s'il vous plaît

Y a-t-il une raison pour que cela se produise?

Définition de magasin:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

namespace DomainModel 
{ 
    public class Store : GuidIdentityPersistenceBase 
    { 
     private string _address1; 

     private string _address2; 

     private string _city; 

     private string _county; 

     private int _oldStoreNumber; 

     private string _faxNumber; 

     private bool _hasHydraulicHose; 

     private bool _hasInsCounter; 

     private bool _hasPaintBooth; 

     private bool _isHubStore; 

     private bool _isOpenNightsWeekends; 

     private int _newStoreNumber; 

     private string _phoneNumber; 

     private string _postalCode; 

     private string _state; 

     private IList _walls = new List(); 

     public virtual string Address1 
     { 
      get 
      { 
       return _address1; 
      } 
      set 
      { 
       _address1 = value; 
      } 
     } 

     public virtual string Address2 
     { 
      get 
      { 
       return _address2; 
      } 
      set 
      { 
       _address2 = value; 
      } 
     } 

     public virtual string City 
     { 
      get 
      { 
       return _city; 
      } 
      set 
      { 
       _city = value; 
      } 
     } 

     public virtual string County 
     { 
      get 
      { 
       return _county; 
      } 
      set 
      { 
       _county = value; 
      } 
     } 

     public virtual int OLDStoreNumber 
     { 
      get 
      { 
       return _oldStoreNumber; 
      } 
      set 
      { 
       _oldStoreNumber = value; 
      } 
     } 

     public virtual string FaxNumber 
     { 
      get 
      { 
       return _faxNumber; 
      } 
      set 
      { 
       _faxNumber = value; 
      } 
     } 

     public virtual bool HasHydraulicHose 
     { 
      get 
      { 
       return _hasHydraulicHose; 
      } 
      set 
      { 
       _hasHydraulicHose = value; 
      } 
     } 

     public virtual bool HasInsCounter 
     { 
      get 
      { 
       return _hasInsCounter; 
      } 
      set 
      { 
       _hasInsCounter = value; 
      } 
     } 

     public virtual bool HasPaintBooth 
     { 
      get 
      { 
       return _hasPaintBooth; 
      } 
      set 
      { 
       _hasPaintBooth = value; 
      } 
     } 

     public virtual Guid Id 
     { 
      get 
      { 
       return _persistenceId; 
      } 
     } 

     public virtual bool IsHubStore 
     { 
      get 
      { 
       return _isHubStore; 
      } 
      set 
      { 
       _isHubStore = value; 
      } 
     } 

     public virtual bool IsOpenNightsWeekends 
     { 
      get 
      { 
       return _isOpenNightsWeekends; 
      } 
      set 
      { 
       _isOpenNightsWeekends = value; 
      } 
     } 

     public virtual int NewStoreNumber 
     { 
      get 
      { 
       return _newStoreNumber; 
      } 
      set 
      { 
       _newStoreNumber = value; 
      } 
     } 

     public virtual string PhoneNumber 
     { 
      get 
      { 
       return _phoneNumber; 
      } 
      set 
      { 
       _phoneNumber = value; 
      } 
     } 
     public virtual string PostalCode 
     { 
      get 
      { 
       return _postalCode; 
      } 
      set 
      { 
       _postalCode = value; 
      } 
     } 

     public virtual string State 
     { 
      get 
      { 
       return _state; 
      } 
      set 
      { 
       _state = value; 
      } 
     } 

     public virtual IList Walls 
     { 
      get 
      { 
       return _walls.ToList().AsReadOnly(); 
      } 
     } 

     public virtual void AddWall(Wall wall) 
     { 
      wall.Store = this; 
      _walls.Add(wall); 
     } 

    } 
}

Action Get:

[AcceptVerbs(HttpVerbs.Get)] 
     public ViewResult EditStore(Guid Id) 
     { 
      Store store; 
      using (UnitOfWork.Start()) 
      { 
       store = _storeRepository.GetStore(Id); 
      } 

      return View(store); 
     }

Action Post (oui je me rends compte qu'il n'y a pas d'encodage des chèques etc, juste ici rugueux au début):

[AcceptVerbs(HttpVerbs.Post)] 
      public ActionResult EditStore(Store store) 
     { 
      using (UnitOfWork.Start()) 
      { 
       _storeRepository.Update(store); 

       UnitOfWork.Current.Flush(); 
      } 

      return RedirectToAction("EditStore", store.Id); 
     }

<% using (Html.BeginForm()) {%>

<fieldset> 
     <legend>Fields</legend> 
     <p> 
      <label for="Address1">Address1:</label> 
      <%= Html.TextBox("Address1", Model.Address1) %> 
      <%= Html.ValidationMessage("Address1", "*") %> 
     </p> 
     <p> 
      <label for="Address2">Address2:</label> 
      <%= Html.TextBox("Address2", Model.Address2) %> 
      <%= Html.ValidationMessage("Address2", "*") %> 
     </p> 
     <p> 
      <label for="City">City:</label> 
      <%= Html.TextBox("City", Model.City) %> 
      <%= Html.ValidationMessage("City", "*") %> 
     </p> 
     <p> 
      <label for="County">County:</label> 
      <%= Html.TextBox("County", Model.County) %> 
      <%= Html.ValidationMessage("County", "*") %> 
     </p> 
     <p> 
      <label for="OLDStoreNumber">OLDStoreNumber:</label> 
      <%= Html.TextBox("OLDStoreNumber", Model.OLDStoreNumber) %> 
      <%= Html.ValidationMessage("OLDStoreNumber", "*") %> 
     </p> 
     <p> 
      <label for="FaxNumber">FaxNumber:</label> 
      <%= Html.TextBox("FaxNumber", Model.FaxNumber) %> 
      <%= Html.ValidationMessage("FaxNumber", "*") %> 
     </p> 
     <p> 
      <label for="HasHydraulicHose">HasHydraulicHose:</label> 
      <%= Html.TextBox("HasHydraulicHose", Model.HasHydraulicHose) %> 
      <%= Html.ValidationMessage("HasHydraulicHose", "*") %> 
     </p> 
     <p> 
      <label for="HasInsCounter">HasInsCounter:</label> 
      <%= Html.TextBox("HasInsCounter", Model.HasInsCounter) %> 
      <%= Html.ValidationMessage("HasInsCounter", "*") %> 
     </p> 
     <p> 
      <label for="HasPaintBooth">HasPaintBooth:</label> 
      <%= Html.TextBox("HasPaintBooth", Model.HasPaintBooth) %> 
      <%= Html.ValidationMessage("HasPaintBooth", "*") %> 
     </p> 
     <p> 
      <label for="IsHubStore">IsHubStore:</label> 
      <%= Html.TextBox("IsHubStore", Model.IsHubStore) %> 
      <%= Html.ValidationMessage("IsHubStore", "*") %> 
     </p> 
     <p> 
      <label for="IsOpenNightsWeekends">IsOpenNightsWeekends:</label> 
      <%= Html.TextBox("IsOpenNightsWeekends", Model.IsOpenNightsWeekends) %> 
      <%= Html.ValidationMessage("IsOpenNightsWeekends", "*") %> 
     </p> 
     <p> 
      <label for="NewStoreNumber">NewStoreNumber:</label> 
      <%= Html.TextBox("NewStoreNumber", Model.NewStoreNumber) %> 
      <%= Html.ValidationMessage("NewStoreNumber", "*") %> 
     </p> 
     <p> 
      <label for="PhoneNumber">PhoneNumber:</label> 
      <%= Html.TextBox("PhoneNumber", Model.PhoneNumber) %> 
      <%= Html.ValidationMessage("PhoneNumber", "*") %> 
     </p> 
     <p> 
      <label for="PostalCode">PostalCode:</label> 
      <%= Html.TextBox("PostalCode", Model.PostalCode) %> 
      <%= Html.ValidationMessage("PostalCode", "*") %> 
     </p> 
     <p> 
      <label for="State">State:</label> 
      <%= Html.TextBox("State", Model.State) %> 
      <%= Html.ValidationMessage("State", "*") %> 
     </p> 
     <p> 
      <input type="submit" value="Save" /> 
     </p> 
    </fieldset> 

<% } %> 

<div> 
    <%=Html.ActionLink("Back to List", "Index") %> 
</div> 

Fiddler:

Address1=1234+Main+street&Address2=Suite+100&City=Anywhere&County=MyCounty&OLDStoreNumber=1&FaxNumber=18001112222&HasHydraulicHose=true&HasHydraulicHose=false&HasInsCounter=true&HasInsCounter=false&HasPaintBooth=false&IsHubStore=false&IsOpenNightsWeekends=false&NewStoreNumber=1&PhoneNumber=18001112222&PostalCode=11001&State=MyState

Répondre

0

Le problème résidait dans le cadre IoC que j'utilisais. Eh bien, ce n'était pas un problème avec le framework lui-même, mais plutôt ma configuration de celui-ci. Lorsque vous utilisez Castle Windsor pour votre infrastructure IoC, vous devez marquer les conteneurs enregistrés comme ayant un mode de vie = Transitoire au lieu du mode Singleton par défaut. Si vous autorisez la valeur par défaut, cela causera des dégâts si vous l'utilisez comme je le suis.

Merci à tous pour votre aide.

0

Vous pouvez essayer d'utiliser la UpdateModel (StoreObject);

Peut-être que les valeurs seront définies.

+0

C'est l'approche que j'ai essayé d'utiliser, mais le StoreObject dans votre suggestion n'est pas rempli avec les données de formulaire. C'est le problème que j'ai. Je peux persister l'information correctement, j'ai juste du mal à l'obtenir de la forme dans le paramètre d'objet sur la méthode de poteau. –

1

Renommez les éléments de formulaire pour qu'ils correspondent au nom_objet. propertyname, comme ceci:

<%= Html.TextBox("SomeNewObj.Id",Model.Id); 
<%= Html.TextBox("SomeNewObj.Title",Model.Title); 

SomeNewObj est le nom du paramètre à la méthode POST:

public ActionResult SomePostMethod(int id, Store SomeNewObj) 
{ 
    //SomeNewObj.Title should be properly populated 
    //... 
} 

ASP.NET MVC fera l'association au nouvel objet de magasin seulement si les ID de formulaire incluent le nom du paramètre d'objet ainsi que ses propriétés.

N'oubliez pas de coder! :) Je l'ai laissé dans cet exemple.

+0

A donné un coup de feu, en changeant le premier argument sur TextBox à "store.Address1" et toujours pas de dés. Bonne idée cependant. –

1

Votre formulaire doit inclure toutes les propriétés non nullables du type, ou le classeur de modèle par défaut ne le liera pas. Vous dites que vous n'incluez pas l'ID. Est-ce un type non-nullable comme Guid ou int? C'est ton problème.

Il y a deux façons de contourner ce problème:

  1. Modifier le type de l'ID à un type nullable comme Guid?
  2. Ajoutez une valeur "par défaut" pour l'ID au formulaire, comme Guid.Empty.

Je note que vous utilisez TextBoxes pour lier aux propriétés booléennes.Cela signifie que si une valeur est omise ou ne peut pas être convertie en booléen, la liaison du type entier échouera, car les propriétés ne sont pas Nullable. Utiliser autre chose qu'une case à cocher pour lier un booléen est un peu précaire. En général, si vous concevez un type pour la liaison de modèle, vous pouvez vouloir rendre tout nullable dans le cas où un utilisateur ne remplissant pas une propriété ne veut pas dire que vous ne voulez pas voir ce qu'il a rempli pour d'autres propriétés.

+0

Je suppose que cela va être le problème alors. C'est un non non nullable Guid et a seulement un getter sur le modèle de domaine. En testant cette théorie, je vous ferai savoir ce que je trouve. –

+0

A donné un essai et toujours pas de dés. Ça me rend fou. –

+0

Affichez la définition de classe et le formulaire que votre page envoie (depuis l'onglet net Firebug ou Fiddler). –

0

Je configurerais un CustomModelBinder pour cela. pour un peu plus haut travail avant, ces retombées à long terme, croyez-moi ...

public class StoreModelBinder : DefaultModelBinder 
{ 
    protected override void OnModelUpdated(ControllerContext controllerContext, 
              ModelBindingContext bindingContext) 
    { 
     Store store= 
      (Store)(bindingContext.Model ?? new Store()); 

     // For example... 
     store.ID = Convert.ToInt32(controllerContext.HttpContext.Request["storeID"]); 

     // Set other properties... 
    } 
} 

Vous obtenez la réutilisation dans les contrôleurs et les actions et vos contrôleurs n'ont pas à vous soucier de la digestion FormCollections.

+0

Je suis à la recherche pour voir si cela répondra à mes besoins. Est-ce que chaque classeur modèle doit être enregistré séparément dans l'app_start? –

+0

App start est le meilleur endroit pour les enregistrer. – RailRhoad

Questions connexes