通过表单将复杂类型从局部视图传递到控制器操作

时间:2012-05-05 04:20:15

标签: asp.net-mvc-3 forms razor partial-views form-submit

所以,我正在使用ASP.NET MVC开发一个新项目。老实说,我之前没有相关的经验(或任何网络开发),所以也许这是一个简单的问题。

我有一个局部视图,这是一个在各种Web视图之间共享的搜索框。该视图有一个下拉列表和一个文本框。我需要一旦用户发布表单(使用搜索按钮),值作为SearchFilterModel对象到达搜索控制器的索引操作。

现在,表单正在Search Search上调用索引操作。这是有效的(见附件)。但问题是,索引方法的id参数(必须是SearchFilterModel)不会到达(它为空)。

我不知道如何将对象从表单传递给控制器​​。 ¿我做错了什么?

问题是如果我用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 个答案:

答案 0 :(得分:1)

您必须构建一个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();
}

请告诉我这是否适合您..

答案 1 :(得分:0)

使用表单发布复杂对象时,重要的是“name”属性与objects属性匹配。

使用@Html.TextBoxFor(s => search.SearchQuery) mvc将为您创建必要的属性。

您应该替换表单标记,因为表单包含创建对象所需的信息using (Html.BeginForm("Index", "Search", FormMethod.Post))

答案 2 :(得分:0)

所有发布的答案都不起作用,所以最终解决方案是:

在“Home”控制器中(其视图呈现“搜索”部分视图)我声明了SearchViewModel的新实例,将其传递给“Home”视图(通过ViewBag)恢复它位于“主页”视图中,并通过Render方法将其传递给“搜索”局部视图:

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

现在,在“搜索”视图中,只需像往常一样声明Begin表单,现在它可以完美运行。似乎(对我而言)这个问题与对象的生命周期有关(在我的问题和我最初的尝试中,我试图在表单之前声明它,在我看来,这是不可能的) 。现在,它运作良好,但我担心这样做的性能影响。任何建议将不胜感激。