Click here to Skip to main content
15,039,525 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
I want to modify an object property values in MVC.
@model Test.Web.Models.CountryLanguageModel

<div class="col-md-8 col-md-offset-2">
        @using (Html.BeginForm())
        {
            @Html.ValidationSummary(true)
            <fieldset>
                <legend>Language Edit</legend>

                @Html.HiddenFor(model => model.CountryId)

                <div class="editor-label">
                    @Html.LabelFor(model => model.CountryLanguage.LanguageName)
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.CountryLanguage.LanguageName)
                </div>

                <div class="editor-label">
                    @Html.LabelFor(model => model.CountryLanguage.Message)
                </div>
                <div class="editor-field">
                    @Html.EditorFor(model => model.CountryLanguage.Message)
                </div>
          
                <br />
                <div class="form-group">
                    <div class="col-md-offset-2 col-md-10">
                        <input type="submit" value="Save" class="btn btn-default" />
                    </div>
                </div>
            </fieldset>
        }
    </div>


And in controller. I have two methods.
public ActionResult LanguageEdit(int id)
       {
           var model = new CountryLanguageModel();
           model.CountryLanguageId = id;
           var CountryLanguage = CountryService.Get(x => x.LanguageId == id);
           model.CountryLanguage = CountryLanguage;
           return View(model);
       }

       [HttpPost]
       public ActionResult LanguageEdit(CountryLanguageModel CountryLanguageModel)
       {
           if (ModelState.IsValid)
           {
           }
           var model = new CountryLanguageModel();
           model.CountryLanguageId = CountryLanguageModel.CountryLanguageId;
           var CountryLanguage = CountryService.Get(x => x.LanguageId == model.CountryLanguageId);
           model.CountryLanguage = CountryLanguage;
           return View(model);
       }


In the first method, it works correctly
public ActionResult LanguageEdit(int id)

My question is in the second method
public ActionResult LanguageEdit(CountryLanguageModel CountryLanguageModel)

I don't see the changes in the model.

What I have tried:

For example, I found in the second method. model.CountryLanguage is null. That means I failed to pass the model.
Posted
Updated 26-Jun-17 6:18am
Comments
F-ES Sitecore 26-Jun-17 12:09pm
   
You should always use CountryLanguageModel rather than creating a new instance of the model. If CountryLanguage is null then use the debugger to step through the code to see where it is going wrong. Is "CountryLanguageModel.CountryLanguageId" correct? Is "CountryLanguage" null after the CountryService.Get?
Member 12658724 26-Jun-17 13:21pm
   
You are right. I shouldn't create a new instance. CountryLanguage is not null.

1 solution

Your issue is with the how model binding in MVC handles complex objects for use in the HTML helpers which is what you have going on in your view. Since you didn't post your model, I am guessing your model looks something like

C#
public class CountryLanguageModel
{
   public CountryLanguage CountryLanguage {get;set;}
}

public class CountryLanguage
{
   public string LanguageName {get;set;
}


Because your view implements @Html.EditorFor(model => model.CountryLanguage.LanguageName) its going to look in HTML as something like <input type="text" id="CountryLanguage_LanguageName" name="CountryLanguage_LanguageName" />.

When you look at your CountryLanguage model in your Post action, chances are that class doesn't have a property name of public string CountryLanguage_LanguageName rather, your Post action is looking for properties posted to that action via the behind the scenes model binding to be simply LanguageName.


The easy fix here would be to change your view to either use your model to be @Model CountryLanguage or if that isn't possible, create a partial view, pass in Model.CountryLanguage from the parent view into the partial view you create in order to appease the model binding of MVC. What this would do is change the above example of CountryLanguage_LanguageName to look something like @Html.EditorFor(model=>model.LanguageName) which renders html to look something like <input type="text" id="LanguageName" name="LanguageName" />

The other option is to not use a strongly typed view and instead you specify the attributes by using @Html.Editor instead of @Html.EditorFor This would look something like @Html.Editor("LanguageName", @Model.CountryLanguage.LanguageName") which should (i'm going off of memory) render HTML that looks something like <input type="text" name="LanguageName" id="LanguageName"/>

If those options are not possible for you then you need to look into custom model binding/property mapping options within MVC. Personally, if i ever run into this issue i go the route of partial views.

These are a few links from a quick search that may be of help if you choose to go the custom model binding route:

asp.net mvc 4 - Underscore string model binder - Stack Overflow[^]

[^]

Edit:

Looked at your post action again and saw it is CountryLanguageModel, so if for whatever reason your Post action does require the complex class object of CountryLanguageModel with CountryLanguage class as a property of the LanguageModel, then you may have to look into a custom model binding solution, but I would also take a look and re-think your class structure if possible.
   
v4

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900