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

Posted

技术标签:

【中文标题】通过表单将复杂类型从部分视图传递到控制器操作【英文标题】:Passing complex type from partial view to controller action via form 【发布时间】:2012-05-05 04:20:15 【问题描述】:

所以,我正在使用 ASP.NET MVC 开发一个新项目。老实说,我之前对它(或任何 Web 开发)没有太多经验,所以这可能是一个简单的问题。

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

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

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

问题是如果我用new id = "something" 替换new id = search (更改发送参数的类型,然后一个字符串到达​​(它有效)或者如果我写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();
        

搜索过滤器模型

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; 

【问题讨论】:

似乎您想将 SearchFilterModel 对象从局部视图传递给索引控制器 @COLDTOLD 这就是标题所说的 :) ¿ 有什么想法吗? 能否分享一下SearchFilterModel类的定义 【参考方案1】:

您必须构建一个语法与类定义匹配的 JSON,然后将此数据发送到您的操作,MVC 应该处理 JSON 到您的类的转换,或者您可以使用 @987654322 的 Deserialize 方法@class 并将对象创建为字符串。

因此将一个事件处理程序绑定到您的提交函数,然后使用一些 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();

让我知道这是否适合你..

【讨论】:

我在想,这是唯一的方法吗?我的问题是,因为我正在尝试,结果如果我将 SearchFilterModel 设置为部分视图的模型(而不是另一个对象),那么它甚至不需要设置为表单声明中的参数就可以工作。或者,假设这是框架自动构建的“模型”?【参考方案2】:

使用表单发布复杂对象时,属性“名称”与对象属性匹配很重要。

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

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

【讨论】:

【参考方案3】:

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

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

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

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

【讨论】:

以上是关于通过表单将复杂类型从部分视图传递到控制器操作的主要内容,如果未能解决你的问题,请参考以下文章

通过 AJAX 将表单发布到部分视图

在 Laravel 5.1 中通过 AJAX 将用户输入数据从视图传递到控制器

将 ManagedObjectContext 传递/注入到视图控制器中

C# MVC .Net Core Form,强类型化的Form,无法使用(404错误)。

将字符串从控制器传递到部分视图作为 javascript 函数参数

如何使用 json 将复杂类型传递给 ASP.NET MVC 控制器