MVC 4 ViewModel not being sent back to Controller

后端 未结 9 1761
感情败类
感情败类 2020-12-08 07:17

I can\'t seem to figure out how to send back the entire ViewModel to the controller to the \'Validate and Save\' function.

Here is my controller:

[H         


        
相关标签:
9条回答
  • 2020-12-08 07:55

    Model binding hydrates your view model in your controller action via posted form values. I don't see any form controls for your aforementioned variables, so nothing would get posted back. Can you see if you have any joy with this?

    @using (Html.BeginForm("Send", "DepositDetails", FormMethod.Post, new { transaction = Model }))
    {
        @Html.TextBoxFor(m => m.WalletAddress, new { placeholder = "Wallet Address", maxlength = "34" })
        @Html.Hidden("Time", Model.Transaction.Time)
        @Html.Hidden("Location", Model.Transaction.Location)
        @Html.Hidden("TransactionId", Model.Transaction.TransactionId)
        <input type="submit" value="Send" />    
    
        @Html.ValidationMessage("walletAddress", new { @class = "validation" })
    }
    
    0 讨论(0)
  • 2020-12-08 07:57

    OK, I've been working on something else and bumpend into the same issue all over again. Only this time I figured out how to make it work!

    Here's the answer for anyone who might be interested:

    Apparently, there is a naming convention. Pay attention:

    This doesn't work:

    // Controller
    [HttpPost]
    public ActionResult Send(BitcoinTransactionViewModel transaction)
    {
    }
    
    // View
    @using (Html.BeginForm("Send", "DepositDetails", FormMethod.Post, new { transaction = Model }))
    {
    
    @Html.HiddenFor(m => m.Token);
    @Html.HiddenFor(m => m.Transaction.TransactionId);
    .
    .
    

    This works:

    // Controller
    [HttpPost]
    public ActionResult Send(BitcoinTransactionViewModel **RedeemTransaction**)
    {
    }
    
    // View
    @using (Html.BeginForm("Send", "DepositDetails", FormMethod.Post, new { **RedeemTransaction** = Model }))
    {
    
    @Html.HiddenFor(m => m.Token);
    @Html.HiddenFor(m => m.Transaction.TransactionId);
    .
    .
    

    In other words - a naming convention error! There was a naming ambiguity between the Model.Transaction property and my transaction form field + controller parameter. Unvelievable.

    If you're experiencing the same problems make sure that your controller parameter name is unique - try renaming it to MyTestParameter or something like this...

    In addition, if you want to send form values to the controller, you'll need to include them as hidden fields, and you're good to go.

    0 讨论(0)
  • 2020-12-08 08:06

    Can you just combine those 2 models you have? Here's how I do it with one model per view... 1. I use Display Templates from view to view so I can pass the whole model as well as leave data encrypted.. 2. Setup your main view like this...

    @model IEnumerable<LecExamRes.Models.SelectionModel.GroupModel>
    <div id="container"> 
    <div class="selectLabel">Select a Location:</div><br />
    @foreach (var item in Model)
    {           
        @Html.DisplayFor(model=>item)
    }
    </div>
    

    3. Create a DisplayTemplates folder in shared. Create a view, naming it like your model your want to pass because a DisplayFor looks for the display template named after the model your using, I call mine GroupModel. Think of a display template as an object instance of your enumeration. Groupmodel Looks like this, I'm simply assigning a group to a button.

    @model LecExamRes.Models.SelectionModel.GroupModel
    @using LecExamRes.Helpers
    @using (Html.BeginForm("Index", "Home", null, FormMethod.Post))
    {
     <div class="mlink">
        @Html.AntiForgeryToken()
        @Html.EncryptedHiddenFor(model => model.GroupKey)
        @Html.EncryptedHiddenFor(model => model.GroupName)
         <p>
             <input type="submit" name="gbtn" class="groovybutton" value=" @Model.GroupKey          ">
         </p>   
     </div>
    }       
    

    4. Here's the Controller. *GET & POST *

    public ActionResult Index()
        {
            // Create a new Patron object upon user's first visit to the page.
            _patron = new Patron((WindowsIdentity)User.Identity);
            Session["patron"] = _patron;            
            var lstGroups = new List<SelectionModel.GroupModel>();
            var rMgr = new DataStoreManager.ResourceManager();
            // GetResourceGroups will return an empty list if no resource groups where    found.
            var resGroups = rMgr.GetResourceGroups();
            // Add the available resource groups to list.
            foreach (var resource in resGroups)
            {
                var group = new SelectionModel.GroupModel();
                rMgr.GetResourcesByGroup(resource.Key);
                group.GroupName = resource.Value;
                group.GroupKey = resource.Key;
                lstGroups.Add(group);
            }
            return View(lstGroups);
        }
    
        [ValidateAntiForgeryToken]
        [HttpPost]
        public ActionResult Index(SelectionModel.GroupModel item)
        {
            if (!ModelState.IsValid)
                return View();
    
            if (item.GroupKey != null && item.GroupName != null)
            {               
                var rModel = new SelectionModel.ReserveModel
                {
                    LocationKey = item.GroupKey,
                    Location = item.GroupName
                };
    
                Session["rModel"] = rModel;
            }           
    //So now my date model will have Group info in session ready to use
            return RedirectToAction("Date", "Home");
       }
    

    5. Now if I've got alot of Views with different models, I typically use a model related to the view and then a session obj that grabs data from each model so in the end I've got data to submit.

    0 讨论(0)
提交回复
热议问题