我的应用程序包含搜索框很少的页面。当用户点击相应的搜索按钮时,预计会加载结果网格。该网格具有很少的可编辑控件,用户可以在其中修改并点击保存按钮以保存数据。
我们已使用AjaxForm和部分视图实现了该功能。
已经尝试了很多技巧,但没有成功。任何工作实例都证明了这一点可行吗? Web上有很多例子解释了AjaxForm用于加载数据的用法,但没有找到多个(或嵌套?)
提前致谢。
编辑 - 2月24日
以下是我使用Visual Studio默认MVC模板创建的示例,它与上面解释的实际标准类似,在提交部分页面时也存在同样的问题。
查看:
Index.cshtml
@using MvcApplication1.Models
@model SearchModel
@{
ViewBag.Title = "Home Page";
}
<script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.min.js")" ></script>
<h2>@ViewBag.Message</h2>
<p>
To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.
</p>
@Ajax.BeginForm("Search", "Home", new AjaxOptions { HttpMethod = "Post",
InsertionMode = InsertionMode.Replace,UpdateTargetId = "SearchResults"})
{
<table>
<tr>
<td>
First Name:
</td>
<td>
@Html.TextBoxFor(m => m.SearchString)
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Submit" />
</td>
</tr>
</table>
}
<div id="SearchResults" style="color: Green;"></div>
部分视图 - _SearchResult.cshtml
@using MvcApplication1.Models
@model MvcApplication1.Models.SearchModel
@{
ViewBag.Title = "Result Partial";
}
<h2>
testPartial</h2>
@Ajax.BeginForm("SearchResult", "Home", new AjaxOptions
{
HttpMethod = "Post"
})
{
<table>
@foreach (ResultModel item in Model.Result)
{
<tr>
<td>
Name:
</td>
<td>
@Html.DisplayFor(m => item.Name)
</td>
</tr>
<tr>
<td>
Address:
</td>
<td>
@Html.TextAreaFor(m => item.Address)
</td>
</tr>
}
<tr>
<td colspan="2">
<input type="submit" value="Submit" />
</td>
</tr>
</table>
}
型号:
SearchModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcApplication1.Models
{
public class SearchModel
{
public string SearchString { get; set; }
public List<ResultModel> Result { get; set; }
}
}
ResultModel.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcApplication1.Models
{
public class ResultModel
{
public string Name { get; set; }
public string Address { get; set; }
}
}
控制器:
HomeController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcApplication1.Models;
namespace MvcApplication1.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Welcome to ASP.NET MVC!";
return View();
}
public ActionResult About()
{
return View();
}
[HttpPost]
public ActionResult Search(SearchModel model)
{
//dummy search for result
List<ResultModel> result = new List<ResultModel>();
ResultModel res1 = new ResultModel();
res1.Name = model.SearchString + " 1";
res1.Address = "Dummy address";
result.Add(res1);
ResultModel res2 = new ResultModel();
res2.Name = model.SearchString + " 2";
res2.Address = "Rummy address";
result.Add(res2);
//assign seach results to model
model.Result = result;
return PartialView("_SearchResult", model);
}
[HttpPost]
public ActionResult SearchResult(SearchModel model)
{
//do something with results
List<ResultModel> res = model.Result; // null here !!
return RedirectToAction("Index");
}
}
}
所以,上面的样本
希望,这可以解释我的问题。
答案 0 :(得分:1)
现在您已经用完整的示例展示了您的实际代码,您的问题可以得到解答。
您获得null
的原因是因为您不遵守默认模型绑定器所期望的输入字段的标准命名约定。请阅读Phil Haack的following article
以熟悉这些惯例。
您的代码存在的问题是您在部分内部使用foreach
循环来渲染结果而不是使用编辑器模板。因此,请使用以下内容替换_SearchResult.cshtml
中的代码:
@using MvcApplication1.Models
@model SearchModel
@{
ViewBag.Title = "Result Partial";
}
<h2>testPartial</h2>
@using(Ajax.BeginForm("SearchResult", "Home", new AjaxOptions()))
{
<table>
@Html.EditorFor(x => x.Result)
<tr>
<td colspan="2">
<input type="submit" value="Submit" />
</td>
</tr>
</table>
}
然后为ResultModel
类型定义自定义编辑器模板(~/Views/Shared/EditorTemplates/ResultModel.cshtml
- 警告,编辑器模板的名称和位置很重要,因为它按惯例工作):
@using MvcApplication1.Models
@model ResultModel
<tr>
<td>
Name:
</td>
<td>
@Html.DisplayFor(m => m.Name)
@Html.HiddenFor(m => m.Name)
</td>
</tr>
<tr>
<td>
Address:
</td>
<td>
@Html.TextAreaFor(m => m.Address)
</td>
</tr>
需要注意的事项:
Ajax.BeginForm
帮助器包装在using
语句中。您应该在Index.cshtml
视图@Html.HiddenFor(m => m.Name)
)中为Name属性添加了一个隐藏字段,以便在提交表单时将此值发送到服务器,因为您只有一个TextArea用于Address字段含义将永远不会将名称发送到您的服务器。