C# – html.hidden for value not set in asp.net MVC core Razor view

asp.netasp.net-coreasp.net-mvcc

I am working on an asp.net MVc core application. I have a popup with a form element like this:

@using (Html.BeginForm("AddIVR", "ITPVoice", FormMethod.Post, new { role = "form" }))
 {    
       @*@Html.HiddenFor(m =>m.m_newIVR.Account, new { @value= Model.accountID})*@
       @Html.Hidden("m.m_newIVR.Account", Model.accountID)    
 }

I have a viewmodel like this:

public class AccountDetailsViewModel
{
    public IVRS m_newIVR { get; set; }
}

and IVRS model class like this:

 public class IVRS
 {

        [JsonProperty("_id")]
        public string Id { get; set; }

        [JsonProperty("name")]
        public string Name { get; set; }

        [JsonProperty("description")]
        public string Description { get; set; }

        [JsonProperty("account")]
        public string Account { get; set; }

}

I am trying to populate it in my view like this:

@Html.HiddenFor(m =>m.m_newIVR.Account, new { @value= Model.accountID})

but when i see view source, Value is null

I tried using:

 @Html.Hidden("m.m_newIVR.Account", Model.accountID)

and it shows m_newIVR.Account populated.

Then I am posting the form to controller this action

 [HttpPost]       
        public ActionResult AddIVR(AccountDetailsViewModel model)
{
 return RedirectToAction("AccountDetails", "mycontroller")
}

Although I see that AccountId is populated in view ( using viewsource), but in post action method value of model.m_newIVR.Account is null.

HTML output looks like this:

        <div id="edit-ivrs-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style="display: none;">


      <div class="modal-dialog">
<form action="/ITPVoice/AddIVR" method="post" role="form">                        <div class="modal-content">
                            <div class="modal-header">

                                <h4 class="modal-title">Add IVR</h4>
                                <input id="m_newIVR_Account" name="m_newIVR.Account" type="hidden" value="" />
                                <input id="AccountId" name="AccountId" type="hidden" value="56f5e3d77ea022a042665be1" />
                            </div>
                            <div class="modal-body">
</div>
</div>

My Questions are:

  1. Why html.hiddenfor is not setting value of the model variable?
  2. Although html.hidden is setting value, why it is not accessible in post action method ?

Please suggest.

Best Answer

Now I am able to answer your question why does it works for Html.Hidden but not for Html.HiddenFor.

  1. When you Html.HiddenFor with m =>m.m_newIVR.Account then it always try to set value for hidden field value whatever value available in property m.m_newIVR.Account not the value that you specify using @value = Model.AccountId.

If you want to use HiddenFor the set m_newIVR.Account in ViewModel just use following thing.

 @Html.HiddenFor(m =>m.m_newIVR.Account)
  1. Html.Hidden is not strongly type so it not depend on name. You can specify different name and value parameter. In this case It is your responsibility to generate proper name for HiddenField.

My Working Sample

Model

public class AccountDetailsViewModel
{
    public string AccountId { get; set; }
    public IVRS m_newIVR { get; set; }
}

public class IVRS
{

    [JsonProperty("_id")]
    public string Id { get; set; }

    [JsonProperty("name")]
    public string Name { get; set; }

    [JsonProperty("description")]
    public string Description { get; set; }

    [JsonProperty("account")]
    public string Account { get; set; }

}

Controller Action

    [HttpGet]
    public IActionResult Index1()
    {
        AccountDetailsViewModel model = new AccountDetailsViewModel();
        //model.AccountId = "1222222";
        model.m_newIVR = new IVRS();
        model.m_newIVR.Account = "122222";
        return View(model);
    }

    [HttpPost]
    public IActionResult Index1(AccountDetailsViewModel model)
    {
        return View(model);
    }

View (Index1.cshtml)

@model WebApplication2.Controllers.AccountDetailsViewModel

@using (Html.BeginForm())
{
    @Html.HiddenFor(m =>m.m_newIVR.Account)    
    <input type="submit" />
}

// Sample Out

enter image description here