2
votes

I can't for the life of me figure out what I'm doing wrong.

I have a SearchModel class that my view inherits from

 public class SearchModel
    {
        public String Something { get; set; }
        public List<SearchField> SearchFields { get; set; }
    }

public class SearchField
{
    [XmlIgnore]
    public Boolean Include { get; set; }

    [XmlAttribute("Required")]
    public Boolean Required { get; set; }

    [XmlAttribute("Field")]
    public String FieldName { get; set; }

    [XmlText]
    public String DisplayName { get; set; }

    [XmlIgnore]
    public FilterMethod FilterOperator { get; set; }

    [XmlIgnore]
    public String Value { get; set; }
}

I have a controller called SearchController

 public ActionResult Index()
        {
            SearchModel model = new SearchModel
                                    {
                                        Something = "Hello",
                                        SearchFields = customer.Config.Fields
                                    };

            return View(model);
        }

        [AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Index(SearchModel searchModel)
        {            
            return View("Index", searchModel);
        }

The SearchController index page has this to render the fields

<% using (Html.BeginForm())
   {%>
<%= Html.TextBox("Something", Model.Something) %>
<% for (int i = 0; i < Model.SearchFields.Count; i++)
   {

%>              
<%= Html.Label(Model.SearchFields[i].DisplayName) %>
<%= Html.DropDownListFor(x => x.SearchFields[i].FilterOperator, Model.SearchFields[i].FilterOperator.ToSelectList(), new { @class = "textField" })%>
<%= Html.TextBoxFor(x => x.SearchFields[i].Value) %>

<%= Html.ValidationMessageFor(x => x.SearchFields[i].Value) %>

<% } %>
<button type="submit" value="Search" class="SearchBtn">
    Search</button>
<% } %>

When I modify the value of the SearchField .Value property and press the submit button, it posts to the public ActionResult Index(SearchModel searchModel) method.

The searchModel variable contains the collection SearchFields, however only the "Value" and "FilterOperator" properties are not null.

How can I include the other properties in the post, even if I don't want to explicitly list them in the form?

This image below shows the values being sent to the "index" display page enter image description here

This image below shows the output from POST Output From POST

2
How does the HTML output look when you use that template? Do you get indexed input fields? i.e. something like <input name="[1].DisplayName" ...? - CodingInsomnia
If you don't want to list them in the form, we can assume you don't want the user to change them. If that's the case you can populate those values in the controller upon return, based on whatever selection criteria you needed. Or do like Rene shows. - Webjedi
@CodingInsomnia: yes, they are indexed input fields: name="SearchFields[0].Value" - Michael G

2 Answers

3
votes

If you want to have those values postbacked you need to either provide them in the view by having the fields as Hidden fields

Html.HiddenFor(m => m.searchFields[i].FilterOperator)

Or have some sort of factory that fills your Model with default values

1
votes

How can I include the other properties in the post, even if I don't want to explicitly list them in the form?

You'll have to fetch them again or stuff them in a hiddenfield and basically let the user define your readonly data.

This is why I like to keep the PostModel as a property of the ViewModel. Then my post action method only needs the PostModel parameter. Otherwise, like in your example, you get back this hybrid ViewModel/PostModel and you need to figure out which properties to use.