2

I have a class that looks like this:

public class UserListVM
{
    public SearchModel SearchModel { get; set; }
    public PagedList<User> Users { get; set; }
}

public class SearchModel
{
    public string Text { get; set; }
    /* other properties */
}

I send UserListVM to my view but the action accepts SearchModel:

public ActionResult Search(SearchModel filter)
{
        UserListVM model = new UserListVM();

        model.Users = userService.GetUsers(filter);
        model.SearchModel = filter;

        return View(model);
}

My view is:

@model UserListVM 

<form>
    @Html.TextBoxFor(m => Model.SearchModel.Text)
</form>

But this generates:

<input id="SearchModel_Text" name="SearchModel.Text" type="text" value="">

Which sends UserListVM to the action instead of SearchModel. How can I get it to generate this:

<input id="Text" name="Text" type="text" value="">
1
  • Why are you passing a UserListVM to the view when it needs a SearchModel? Your view doesn't use the anything but the SearchModel. Commented Feb 15, 2012 at 23:22

4 Answers 4

2
@Html.TextBoxFor(m => m.SearchModel.Text, new { id = "Text" })

Utilize the overloaded TextBoxFor() method that takes a second object parameter (called htmlAttributes). Here you can specify HTML attributes to apply to the DOM element you are currently utilizing (in this case, your input element).

Edit: I believe your lambda expression is wrong. Change:

@Html.TextBoxFor(m => Model.SearchModel.Text)

To

@Html.TextBoxFor(m => m.SearchModel.Text)
// htmlAttributes omitted to show the issue

Edit Edit: it turns out that even with a specified name attribute, it will be rendered according to what the form is requiring for a POST to the necessary field(s).

Edit Edit Edit: Try to be explicit with FormExtensions.BeginForm():

@using (Html.BeginForm("Search", "YourController", FormMethod.Post, null))
{
    @Html.TextBoxFor(m => m.SearchModel.Text)
}

Use this as a substite of your <form /> element.

Sign up to request clarification or add additional context in comments.

5 Comments

With LabelFor, I need to give the Id to it as a string?
@Lolcoder If I am understanding your question correctly, then yes. Think of that object (htmlAttributes) as a direct way to set values for HTML element attributes.
When I tried this, only the id was changed, somehow the name didn't get overridden.
@Lolcoder Oh, I see that as well. I think this probably has to do with MVC overriding that. It has to be generated as "SearchModel.Text" so that it is bound to your Model.
@Lolcoder I think you have a deeper underlying problem. See my edit. Instead of your lambda expression being m => Model.SearchModel.Text, it needs to be m => m.SearchModel.Text. Try that out and see if that fixes your problem.
2

Create a partial view for your SearchModel, and call it using Html.Partial. Then, from within that partial view, do all of the EditorFor/TextBoxFor Extensions

Your view - UserList.cshtml:

@model UserListVM

@using (Html.BeginForm())
{
    @Html.Partial("Search", Model.SearchModel)
}

Your view - Search.cshtml:

@model SearchModel

@Html.TextAreaFor(m => m.Text)

Comments

0

Assumming there is more the the View than you have shown, why not just have your Search method take the UserListVM model. It will just contain a null reference to the users, so there is no extra data sent in the post.

Comments

0

Try doing it manually like this:

@Html.TextBox("Text", Model.SearchModel.Text)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.