MVC TextBox with name specified not binding model on post
The first parameter of the HtmlHelper.TextBox
function is the name attribute of the input element created by the function. You're specifying "employee_stock_name" as that parameter (and thus as the name attribute of the input element), so that is what is being sent across the wire.
You should either specify the correct name:
@Html.TextBox("EmployeeName", Model.EmployeeName)
or use HtmlHelper.TextBoxFor
to generate it automatically:
@Html.TextBoxFor(m => m.EmployeeName)
Icestorm0141
C# & .NET developer with a strong focus on CSS & front end web development.
Updated on June 16, 2020Comments
-
Icestorm0141 almost 4 years
This is like MVC 101 here so I feel completely helpless on why this isn't working. I have an extremely basic Model:
public class StockEnrollmentModel { [Required] [DisplayName("Employee Name:")] public string EmployeeName { get; set; } }
My view looks like this:
@using (Html.BeginForm("SimulateForm", "HR", FormMethod.Post)) { <div class="row"> <div class="col-md-6"> <div class="form-group"> @Html.LabelFor(e => e.EmployeeName) @Html.TextBox("stock_employee_name", Model.EmployeeName) </div> </div> </div> <button type="submit" class="btn btn-primary" value="Submit">Submit</button> }
The web service I will be posting to requires specific names for the input fields in order to successfully receive the data
As in, the rendered html needs to read:
<input type="stock_employee_name" type="text" />
After much googling, I determined I need to use an Html.Text box in order to have control of the name attribute that is generated.
The problem I'm having is that when I submit the form, the model in my controller is completely void of data. Investigating this shows that the form posted to the server with "employee_stock_name=Some Name" rather than "EmployeeName=Some Name"
From my research, this shouldnt be happening, correct?? This exact situation should be the reason you use TextBox instead of TextBoxFor.
What am I missing?
Here is my controller for what its worth:
[HttpPost] public RedirectToRouteResult SimulateForm(StockEnrollmentModel model ) { if ( ModelState.IsValid ) { return RedirectToAction("SignForm", "HR", model); } return RedirectToAction("StockPurchase", model ); }
UPDATE
The accepted answer below was what I eventually ended up using. There's no real way to easily change the name of the HTML field and maintain the MVC model binding. I ended up changing my property names to match what I needed the name field to read.
-
Icestorm0141 almost 9 yearsAgain, the rendered html needs to read <input name="employee_stock_name" type="text" />. I've been finding posts where the name of the rendered html field is different from the model property name though. So I wouldnt think this would be a problem. Theres cause for this functionality to exist. What if you want to name your property PersonId but have the query string read Id=? instead?? With those limitations, I should be able to make this work. Why would TextBox exist then if passing in a custom name attribute breaks model binding?
-
Tim almost 9 yearsHow are you expecting MVC to map
employee_stock_name
toEmployeeName
? And why are you expecting it to be "EmployeeName" if it "needs" to be "employee_stock_name" for your webservice to read it? Edit: Let me add this: What is the name of the property on StockEnrollmentModel that you're expecting to be filled with the value? Also, is that controller/action you showed also the web service you are mentioning? Or are they for some reason two different things? -
Icestorm0141 almost 9 yearsWhen I've seen this issue come up in my search results is when you have nested models and your binding to something like: @Html.TextBox("MyPreferedName", Model.SearchParams.someParam) If this isnt what this is supposed to be used for, help me understand why the above code (which was found here: stackoverflow.com/questions/6920935/…) is any different from my use case? How does MVC know how to bind that?
-
Tim almost 9 yearsCheck my edit on the previous comment and the comment I added to the OP. Something is missing from the discussion, trying to figure out what.
-
Icestorm0141 almost 9 yearsName of the property on StockEnrollmentModel is EmployeeName. Understandably, its not being filled when the form posts to the controller with "stock_employee_name". The webservice that I am posting to is an external webservice, not that URL. The controller action I have shown is interception and faking out the response the webservice will give. Yes I can alter all my properties, to match the names, but some of the names are pretty obscure and hard to understand. Not ideal
-
Icestorm0141 almost 9 yearsWebservice I'm posting to has corresponding fields that I'm trying to fill. Some of the names are pretty obscure for these fields, so changing my model properties to reflect all the fields the web service is expecting isn't ideal.
-
Tim almost 9 yearsSo essentially, your question is really "how do I get the MVC binding system to bind a field to a property with a different name [for the purposes of mocking/faking]" is that accurate?
-
Tim Iles almost 9 yearsSorry to say that it sounds like it's grunt work you're just going to have to do - you could probably alleviate it somewhat to use a custom model binder that understands underscore case, but it won't magically resolve stock_employee_name to EmployeeName without a helpful nudge.
-
Icestorm0141 almost 9 yearsThat is very accurate