当我们使用jQuery异步提交表单数据的时候,需要把部分视图转换成字符串(带验证信息),以json的形式传递给前端视图。
使用jQuery异步加载部分视图,返回内容追加到页面某个div:
jQuery异步提交失败,返回带验证失败信息的部分视图字符串,并追加到页面div:
jQuery异步提交成功,返回显示提交成功的部分视图字符串,并追加到页面div:
一个简单的Model:
using System.ComponentModel.DataAnnotations;
namespace MvcApplication1.Models
{
public class Pet
{
public int Id { get; set; }
[Display(Name = "宠物")]
[Required(ErrorMessage = "必填")]
public string Name { get; set; }
}
}
扩展控制器,把部分视图内容转换成字符串。
using System.IO;
namespace System.Web.Mvc
{
public static class ControllerExtensions
{
//根据部分视图名称,把部分视图内容转换成字符串
public static string RenderPartialViewToString(this Controller controller, string partialViewName)
{
return controller.RenderPartialViewToString(partialViewName, null);
}
//根据部分视图名称和model,把部分视图内容转换成字符串
public static string RenderPartialViewToString(this Controller controller, string partialViewName, object model)
{
//如果partialViewName为空,就把action名称作为部分视图名称
if (string.IsNullOrEmpty(partialViewName))
{
partialViewName = controller.ControllerContext.RouteData.GetRequiredString("action");
}
//把model放到Controller.ViewData.Model属性中
controller.ViewData.Model = model;
using (var sw = new StringWriter())
{
//通过视图引擎,在当前ControllerContext中,根据部分视图名称获取ViewEngineResult类型
var viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, partialViewName);
//创建ViewContext
var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData,
controller.TempData, sw);
//把内容写到StringWriter中
viewResult.View.Render(viewContext, sw);
//StringWriter→string
return sw.GetStringBuilder().ToString();
}
}
}
}
Home/Index.cshtml视图,提交之前,以异步Get方式请求部分视图的html内容;点击提交,以异步Post方式请求从控制器返回的部分视图字符串内容。
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div id="petContent">
</div>
<div>
<input type="button" id="btn" value="提交"/>
</div>
@section scripts
{
<script type="text/javascript">
$(function() {
init();
//提交
$(‘#btn‘).click(function() {
$.ajax({
cache: false,
url: ‘@Url.Action("SaveData", "Home")‘,
type: "POST",
data: $(‘#addForm‘).serialize(),
success: function (data) {
$(‘#petContent‘).empty();
$(‘#petContent‘).append(data.message);
},
error: function (jqXhr, textStatus, errorThrown) {
alert("出错了 ‘" + jqXhr.status + "‘ (状态: ‘" + textStatus + "‘, 错误为: ‘" + errorThrown + "‘)");
}
});
});
});
function init() {
$.ajax({
cache: false,
url: ‘@Url.Action("GetPet", "Home")‘,
contentType: ‘application/html;charset=utf-8‘,
type: "GET",
success: function(result) {
$(‘#petContent‘).append(result);
},
error: function(xhr, status) {
alert("加载内容失败" + status);
}
});
}
</script>
}
HomeController部分:
using System.Web.Mvc;
using MvcApplication1.Models;
namespace MvcApplication1.Controllers
{
public class HomeController : Controller
{
//主页面
public ActionResult Index()
{
return View();
}
//接收异步Get请求,部分视图以html返回给前端视图
public ActionResult GetPet()
{
return PartialView();
}
//接收异步Post请求,部分视图转换成字符串,以json返回给前端视图
[HttpPost]
public ActionResult SaveData(Pet pet)
{
if (ModelState.IsValid)
{
//TODO: insert into database
return Json(new {msg = true, message = this.RenderPartialViewToString("Success", pet)});
}
return Json(new { msg = false, message = this.RenderPartialViewToString("GetPet", pet) });
}
}
}
Home/GetPet.cshtml部分视图:
@model MvcApplication1.Models.Pet
@using (Html.BeginForm("SaveData", "Home", FormMethod.Post, new {id = "addForm"}))
{
@Html.LabelFor(model => model.Name)
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
}
Home/Success.cshtml部分视图:
@model MvcApplication1.Models.Pet
@Model.Name 提交成功!