Передача сложного типа из частичного представления в действие контроллера через форму

Итак, я работаю над новым проектом с использованием ASP.NET MVC. Честно говоря, у меня не было большого опыта с этим (или любой веб-разработкой) прежде, поэтому, возможно, это простой вопрос.

У меня есть частичное представление, это окно поиска, которое совместно используется различными веб-представлениями. Представление имеет выпадающий список и текстовое поле. Мне нужно, чтобы после публикации пользователем формы (с помощью кнопки поиска) значения поступали в действие index контроллера поиска как SearchFilterModel объект.

Теперь форма вызывает действие index на контроллере поиска. Это работает (см. Прикрепленный код). Но дело в том, что id-параметр (это должно быть SearchFilterModel) метода index не прибывает (это нуль).

Я не знаю, как передать объект из формы в контроллер. I'm Что я делаю не так?

Дело в том, если я заменю new { id = search } с new { id = "something" } (изменяя тип отправляемого параметра, тогда прибывает строка (это работает) или, если я пишу new { id = 1 } тогда прибывает int Я думаю, что-то связано с тем, что SearchFilterModel не нативный тип, а сложный.

Любая идея?

@using Hermes.Models.Helpers

@{
    var search = CacheHelper.Instance.SearchFilter;
    using (Html.BeginForm("Index", "Search", new { id = search  }, FormMethod.Post))
    {
        @Html.ValidationSummary(true, "No se creó la cuenta. Corrija los errores e inténtelo de nuevo.")
        <div>
            <fieldset>
                <legend>Búsqueda por tipo de producto</legend>

                <div class="editor-label">
                    @Html.LabelFor(s => search.SearchFilter)
                    &nbsp;&nbsp;&nbsp;
                    @Html.DropDownListFor(s => search.SelectedSearchFilter, new SelectList(search.SearchFilter))
                    &nbsp;&nbsp;&nbsp;
                    @Html.LabelFor(s => search.SearchQuery)
                    &nbsp;&nbsp;&nbsp;
                    @Html.TextBoxFor(s => search.SearchQuery)
                    @Html.ValidationMessageFor(s => search.SearchQuery)
                    &nbsp;&nbsp;&nbsp;&nbsp;
                    <input type="submit" value="Buscar" />
                </div>
            </fieldset>
        </div>
    }
}

Действие контроллера поиска

[HttpPost]
        public ActionResult Index(SearchFilterModel id)
        {
            var x = CacheHelper.Instance.SearchFilter;

            ViewBag.Filter = id.SelectedSearchFilter;
            ViewBag.msg = String.Format("Se están buscando {0}, con el filtro {1}", id.SelectedSearchFilter, id.SearchQuery);
            ViewBag.ResultsCount = 0;

            return View();
        }

SearchFilterModel

public class SearchFilterModel
{
    [Required]
    [DataType(DataType.Text)]
    [Display(Name = "¿Qué características?")]
    public string SearchQuery { get; set; }

    [Required]
    [DataType(DataType.Text )]
    [Display(Name = "¿Qué buscar?")]
    public List<String> SearchFilter { get; set; }

    [Required]
    [DataType(DataType.Text)]
    [Display(Name = "¿Qué buscar?")]
    public string SelectedSearchFilter { get; set; }
}

3 ответа

Решение

Ни один из опубликованных ответов не сработал, поэтому, наконец, решение было:

В контроллере "Home" (его представление отображает частичное представление "Search") я объявляю новый экземпляр SearchViewModel, передать его в вид "Домой" (через ViewBag) восстановить его в представлении "Домой" и передать его частичному представлению "Поиск" через Render метод:

SearchFilterModel searchFilter = ViewBag.SearchFilter;
@Html.Partial("SearchProduct", searchFilter)

Теперь в представлении "Поиск" просто объявите форму "Начало" как обычно, и теперь она работает отлично. Мне кажется, что проблема связана с временем жизни объекта (по моему вопросу и моей первоначальной попытке я пытался объявить его непосредственно перед формой, и мне кажется, что это невозможно сделать), Теперь, это прекрасно работает, но я беспокоюсь о влиянии производительности на это. Любое предложение будет с благодарностью.

Вы должны создать JSON, синтаксис которого соответствует определению класса, а затем отправить эти данные в ваше действие, и MVC должен обработать преобразование JSON в ваш класс, или вы можете использовать Deserialize метод JavaScriptSerializer Класс и создать объект в виде строки.

Таким образом, свяжите обработчик событий с вашей функцией отправки, а затем используйте ajax api для передачи данных. Вот пример использования jquery:

var searchFilter=[];
for each( value in the dropdown)
   searchFilter.push(value);

var searchFilterModel={
SearchQuery: "value1", //get the data from the textbox
SelectedSearchFilter: "value2", //get the value from dom
SearchFilter: searchFilter
}

$.ajax(
{
url: url //your action method
data: {
SearchFilterModel:searchFilterModel
},
success:function(){} //callback function
})

Действие подписи остается прежним.

и использовать метод JavaScriptSerializer:

var searchFilter=[];
for each( value in the dropdown)
   searchFilter.push(value);

var searchFilterModel={
SearchQuery: "value1", //get the data from the textbox
SelectedSearchFilter: "value2", //get the value from dom
SearchFilter: searchFilter
}

$.ajax(
{
url: url //your action method
data: {
id1: searchFilterModel
},
success:function(){} //callback function
})

[HttpPost]   
public ActionResult Index(string id1)
{
var id=new JavaScriptSerializer().Deserialize<SearchFilterModel>(id1);
var x = CacheHelper.Instance.SearchFilter;
ViewBag.Filter = id.SelectedSearchFilter;
ViewBag.msg = String.Format("Se están buscando {0}, con el filtro {1}", id.SelectedSearchFilter, id.SearchQuery);
ViewBag.ResultsCount = 0;
return View();
}

Дайте мне знать, если это сработает для вас..

При публикации сложного объекта с формами важно, чтобы атрибут "имя" совпадал со свойством объектов.

Используя @Html.TextBoxFor(s => search.SearchQuery) MVC создаст необходимые атрибуты для вас.

И вы должны заменить тег формы, так как форма содержит необходимую информацию для создания объекта using (Html.BeginForm("Index", "Search", FormMethod.Post))

Другие вопросы по тегам