Передача сложного типа из частичного представления в действие контроллера через форму
Итак, я работаю над новым проектом с использованием 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)
@Html.DropDownListFor(s => search.SelectedSearchFilter, new SelectList(search.SearchFilter))
@Html.LabelFor(s => search.SearchQuery)
@Html.TextBoxFor(s => search.SearchQuery)
@Html.ValidationMessageFor(s => search.SearchQuery)
<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))