我们常常有这样的需求:控制器Save方法接收一个复杂的类型,例如:
public class VisitDetailViewModel { public WordViewModel Word { get; set; } public IEnumerable<PhotoViewModel> Photos { get; set; } } public class WordViewModel { public Guid Id { get; set; } [Required] [Display(Name = "姓名")] [MaxLength(10)] public string Name { get; set; } [Required] [Display(Name = "留言")] [MaxLength(100)] public string Filepath { get; set; } [Display(Name = "时间")] public DateTime CreateTime { get; set; } [Display(Name = "置顶")] public bool IsTop { get; set; } } public class PhotoViewModel { public Guid Id { get; set; } public Guid PhotoId { get; set; } [Required] [MaxLength(100)] public string FilePath { get; set; } public string AccessFilePath { get { return MediaService.GetFileAccessUrl(FilePath); } } [MaxLength(200)] public string Description { get; set; } }
对于单个属性,前端页面表单控件的name属性为XX.XX,对于数组属性,其控件name属性设置为XX[N].XX
代码如下:
@{ Layout = null; } <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>编辑会议</title> @Styles.Render("~/bundles/global/css") @Styles.Render("~/bundles/bootstrap-datetimepicker/css") <style type="text/css"> body { overflow-x: hidden; } </style> </head> <body> <section id="container"> <div class="panel"> <div class="panel-body"> <div class="col-xs-12"> <form class="form-horizontal" role="form"> @Html.HiddenFor(x => x.Word.Id) @Html.HiddenFor(x => x.Word.Filepath) <div class="form-group"> @Html.LabelFor(model => model.Word.Name, new { @class = "control-label col-xs-2" }) <div class="col-xs-5"> @Html.EditorFor(model => model.Word.Name, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Word.Name, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Word.AccessPath, new { @class = "control-label col-xs-2" }) <div class="col-xs-10"> <img src="@Model.Word.AccessPath" /> </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Word.CreateTime, new { @class = "control-label col-xs-2" }) <div class="col-xs-5"> @Html.EditorFor(model => model.Word.CreateTime, new { htmlAttributes = new { @class = "form-control", @readonly = "readonly" } }) @Html.ValidationMessageFor(model => model.Word.CreateTime, "", new { @class = "text-danger" }) </div> @Html.LabelFor(model => model.Word.IsTop, new { @class = "control-label col-xs-2" }) <div class="col-xs-3"> @Html.CheckBoxFor(x => x.Word.IsTop) </div> </div> <div class="form-group"> <label class="control-label col-xs-2">留影</label> <div class="col-xs-10"> <div class="col-xs-11"> <table id="table"></table> </div> <div class="col-xs-1"> <button class="btn btn-sm" id="btn-add"><i class="fa fa-plus"></i></button> </div> </div> </div> <div class="form-group"> <div class="col-xs-offset-5 col-xs-6"> <button type="submit" class="btn btn-primary"> <i class="fa fa-check"></i> 保存 </button> </div> </div> </form> </div> </div> </div> </section> </body> </html> @Scripts.Render("~/bundles/jquery") @Scripts.Render("~/bundles/global/js") @Scripts.Render("~/bundles/jqueryval") @Scripts.Render("~/bundles/bootstrap-datetimepicker/js") <script src="~/Scripts/jquery.form.min.js"></script> <script> var updateRowIndex; $(function() { var i = dialog.getFrameIndex(); // 提交表单 $("form").submit(function() { // 将table中的数据写到form中 var data = $('#table').bootstrapTable('getData'); var ok = true; $(data).each(function(index, item) { if (!item.FilePath || item.FilePath == '') { dialog.alert('请上传照片,点击【照片单元格】上传,点击【描述单元格】添加描述。', 2); ok = false; return false; } $('input[name="Photos[' + index + '].Id"]').remove(); $('input[name="Photos[' + index + '].PhotoId"]').remove(); $('input[name="Photos[' + index + '].FilePath"]').remove(); $('input[name="Photos[' + index + '].Description"]').remove(); $('form').append('<input type="hidden" name="Photos[' + index + '].Id" value="@Model.Word.Id"/>'); $('form').append('<input type="hidden" name="Photos[' + index + '].PhotoId" value="' + item.PhotoId + '"/>'); $('form').append('<input type="hidden" name="Photos[' + index + '].FilePath" value="' + item.FilePath + '"/>'); $('form').append('<input type="hidden" name="Photos[' + index + '].Description" value="' + item.Description + '"/>'); }); if (!ok) return false; $(this).ajaxSubmit({ type: "post", url: "@Url.Action("Save")", beforeSubmit: function (formData, jqForm) { return jqForm.validate().form(); }, success: function (responseText, statusText) { if (responseText.errCode == 0) { dialog.msg(responseText.errMsg); top.frames['ifr'].window.Visitor.refresh(); dialog.close(i); return; } dialog.alert(responseText.errMsg, 2); } }); return false; }); }); </script>