MrJD
MrJD

Reputation: 1889

html.TextBoxFor and html.Textbox, POSTing values, model in parameters

Alright guys, Need some help!

Im working with asp.net mvc3 razor (and am fairly new to it but did lots of web forms)

Okay so onto the problem

My question revolves around submitting a view. I have a very complicated model that my view is based off (strongly typed).

I want to return the model into the arguments in the HttpPost method of the controller. do basically:

public ActionResult Personal()
    {
        DataModel dataModel = new DataModel();
        FormModel model = new FormModel();
        model.candidateModel = dataModel.candidateModel;
        model.lookupModel = new LookupModel();

        return View(model);
    }

    [HttpPost]
    public ActionResult Personal(FormModel formModel)
    {
        if (ModelState.IsValid)
        {
            //stuff
        }
        return View(formModel);
    }

Now...
I'm having trouble getting values into the formModel parameter on the post method.

This works (meaning i can see the value)but is tedious as i have to write exactly where it sits in a string every single field:

@Html.TextBox("formModel.candidateModel.tblApplicant.FirstName", Model.candidateModel.tblApplicant.FirstName)

It renders like this:

<input name="formModel.candidateModel.tblApplicant.FirstName" id="formModel_candidateModel_tblApplicant_FirstName" type="text" value="Graeme"/>

This doesn't work:

@Html.TextBoxFor(c => c.candidateModel.tblApplicant.FirstName)

It renders like this:

<input name="candidateModel.tblApplicant.FirstName" id="candidateModel_tblApplicant_FirstName" type="text" value="Graeme"/>

Now I'm assuming the problem lies in the discrepancy of the id's

So please answer me this:

  1. Am i going about this the right way
  2. Why doesn't textboxfor get the right value/id, and how do i make it get the right value/id so i can retrieve it in a POST(if that is even the problem)?
  3. Additionally, it seems that textboxfor is restrictive, in the manner that if you have a date time, how do you use the .toshortdate() method? This makes me think textboxfor isn't useful for me.

Quick clarification: when i say textboxfor isn't working, it IS getting values when i GET the form. So they fill, but on the POST / submission, i can't see them in the formModel in the parameters.

Another side note:
None of the html helpers work, this is the problem. They aren't appearing in modelstate either.


Thanks everyone for the help

Answer:
html.TextBoxFor and html.Textbox, POSTing values, model in parameters

It was a problem in my view somewhere, i replaced all the code with the snippet in this answer and it worked.

Thank you again

Upvotes: 4

Views: 25552

Answers (3)

Darin Dimitrov
Darin Dimitrov

Reputation: 1039508

Am i going about this the right way

Yes.

Why doesn't textboxfor get the right value/id, and how do i make it get the right value/id so i can retrieve it in a POST(if that is even the problem)?

There is something else in your code that makes this not work. It's difficult to say since you haven't shown all your code. Here's a full working example which illustrates and proves that there's something else going on with your code:

Model:

public class FormModel
{
    public CandidateModel candidateModel { get; set; }
}

public class CandidateModel
{
    public Applicant tblApplicant { get; set; }
}

public class Applicant
{
    public string FirstName { get; set; }
}

Controller:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new FormModel
        {
            candidateModel = new CandidateModel
            {
                tblApplicant = new Applicant
                {
                    FirstName = "fn"
                }
            }
        });
    }

    [HttpPost]
    public ActionResult Index(FormModel formModel)
    {
        // the username will be correctly bound here
        return View(formModel);
    }
}

View:

@model FormModel
@using (Html.BeginForm())
{
    @Html.EditorFor(c => c.candidateModel.tblApplicant.FirstName)
    <button type="submit">OK</button>
}

Additionally, it seems that textboxfor is restrictive, in the manner that if you have a date time, how do you use the .toshortdate() method? This makes me think textboxfor isn't useful for me.

I agree that TextBoxFor is restrictive. That's why I would recommend you always using EditorFor instead of TextBoxFor. It will allow you to simply decorate your view model property with the [DisplayFormat] attribute and voilà. You get any format you like.

For example:

public class MyViewModel
{
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    public DateTime CreatedAt { get; set; }
}

and in the view:

@model MyViewModel
@Html.EditorFor(x => x.CreatedAt)

will format the date exactly as you expect.

Upvotes: 7

wnascimento
wnascimento

Reputation: 1959

If your view is strongly typed, try the helper bellow, instead call each helper on each property

@Html.EditorForModel()
@Html.EditorFor(m => m.candidateModel)
@Html.EditorFor(m => m.lookupModel)

Update:

Well, have tried to use viewmodel to simplify this task? And when you get back the data you can map your real models. keep your views clean will give you less headaches in the future. Additionally you could use AutoMapper to help you.

Here a example if you think that will help you. http://weblogs.asp.net/shijuvarghese/archive/2010/02/01/view-model-pattern-and-automapper-in-asp-net-mvc-applications.aspx

Upvotes: 0

Rafay
Rafay

Reputation: 31043

the model binder uses the name to bind the values to the model, and the html helpers e.g. Html.TextBoxFor uses the body of the lambda expression to set the name, however you can specify the name yourself which you are doing by using the Html.TextBox( helper

@Html.TextBoxFor(x=>x.candidateModel.tblApplicant.FirstName),
                 new{@Name="formModel.candidateModel.tblApplicant.FirstName"})

Upvotes: 0

Related Questions