关于后台的说明:
后台将会用easyui + ajax模式。
这里涉及两个问题,一个是使用easyui如何在前台验证模型的问题,另一个是ajax提交后返回数据。
一、Easyui验证
前台验证采用easyui控件的ValidateBox验证,通过自定义htmlhelper的方式建立与模型的联系。
1、到http://www.jeasyui.com/download/index.php下载EasyUi的最新版本,将js文件解压到~/script文件夹
将式样放到~/Areas/Admin/Content/Easyui/
然后打开BundleConfig.cs,添加如下代码
bundles.Add(new ScriptBundle("~/Scripts/Easyui").Include("~/Scripts/Easyui/jquery.easyui.js", "~/Scripts/Easyui/locale/easyui-lang-zh_CN.js"));bundles.Add(new StyleBundle("~/Css/Admin/Easyui").Include("~/Areas/Admin/Content/Easyui/icon.css", "~/Areas/Admin/Content/Easyui/metro-blue/easyui.css"));
2、在~/Extensions文件夹中添加类EasyuiExtensions.cs
此类的目的是利用ModelMetadata元数据获取Model的验证Attribute然后生成带ValidateBox验证输入控件。
思路为:使用ModelMetadata.FromLambdaExpression获取模型字段的元数据->使用ModelValidatorProviders.Providers.GetValidators获取元数据中验证属性->根据属性生成ValidateBox的validType。
代码如下:
//////////////////////Easyui控件Mvc扩展//版本v1//创建日期2013-09-28////////////////////using System.Collections.Generic;using System.Linq;using System.Linq.Expressions;namespace System.Web.Mvc.Html{/// <summary>/// EasyUi控件/// </summary>public static class EasyuiExtensions{public static MvcHtmlString EasyuiInput<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, string type = "input"){return htmlHelper.EasyuiInput(expression, null,type:type);}public static MvcHtmlString EasyuiInput<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes, string type = "input"){return htmlHelper.EasyuiInput(expression, htmlAttributes: HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes),type:type);}public static MvcHtmlString EasyuiInput<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes, string type = "input"){ModelMetadata _metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);string _name = ExpressionHelper.GetExpressionText(expression);string _fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(_name);string _htmlCtrlstr = string.Empty;//控件Html字符if (String.IsNullOrEmpty(_fullName)){throw new ArgumentException(_name + " 字段不存在!", "name");}TagBuilder tagBuilder = new TagBuilder(type);tagBuilder.MergeAttributes(htmlAttributes);tagBuilder.MergeAttribute("name", _fullName, true);tagBuilder.MergeAttribute("id", _fullName, true);//值if (_metadata.Model != null){if (type.ToLower() == "input") tagBuilder.MergeAttribute("value", (string)_metadata.Model);else if (type.ToLower() == "textarea") tagBuilder.InnerHtml = (string)_metadata.Model;}///验证部分代码开始Dictionary<string, object> _results = new Dictionary<string, object>();string _validType = string.Empty;if (htmlHelper.ViewContext.UnobtrusiveJavaScriptEnabled){IEnumerable<ModelClientValidationRule> _clientRules = ModelValidatorProviders.Providers.GetValidators(_metadata ?? ModelMetadata.FromStringExpression(_name, htmlHelper.ViewData), htmlHelper.ViewContext).SelectMany(v => v.GetClientValidationRules());if (_clientRules.Count() > 0){_validType = string.Empty;foreach (ModelClientValidationRule rule in _clientRules){switch (rule.ValidationType){case "required":break;case "length":if (!string.IsNullOrEmpty(_validType)) _validType += ",";if (rule.ValidationParameters.ContainsKey("min")) _validType += "'" + rule.ValidationType + "[" + rule.ValidationParameters["min"].ToString() + "," + rule.ValidationParameters["max"].ToString() + "]'";else _validType += "'" + rule.ValidationType + "[0," + rule.ValidationParameters["max"].ToString() + "]'";break;default:if (!string.IsNullOrEmpty(_validType)) _validType += ",";_validType += "'" + rule.ValidationType + "'";break;}}if(!string.IsNullOrEmpty(_validType)) _validType = "validType:["+_validType+"]";if (_metadata.IsRequired){if (string.IsNullOrEmpty(_validType)) _validType = "required:true";else _validType = "required:true," + _validType;}if (!string.IsNullOrEmpty(_validType)) tagBuilder.MergeAttribute("data-options", _validType);}}///验证部分代码结束if (type.ToLower() == "input") _htmlCtrlstr = tagBuilder.ToString((TagRenderMode.SelfClosing));else if (type.ToLower() == "textarea") _htmlCtrlstr = tagBuilder.ToString();return new MvcHtmlString(_htmlCtrlstr);}}}
二、ajax返回数据
ajax提交后返回数据包含是否成功,及消息提示,另外如果服务器验证失败的话还要返回一个失败字段列表,干脆建一个类。
在~/Models文件夹中添加类JsonData,代码如下:
///////////////////版本:V1//创建日期:2013-10-23/////////////////using System.Collections.Generic;namespace Ninesky.Models{public class JsonData{/// <summary>/// 操作成功/// </summary>public bool Success { get; set; }/// <summary>/// 消息/// </summary>public string Msg { get; set; }/// <summary>/// 消息列表/// </summary>public Dictionary<string, string> MsgLsit { get; set; }public JsonData(){MsgLsit = new Dictionary<string, string>();}}}
后台ajax提交后固定返回JsonData的json类型。
三、开始搭架子
1、添加布页
在~/Areas/Admin/Views/Shared中添加_Layout.cshtml。
后台页面采用easyui的layout,分north、south、west、center四个部分。代码如下:
<!DOCTYPE html><html><head><meta name="viewport" content="width=device-width" /><title>@ViewBag.Title</title>@Styles.Render("~/Css/Admin")@Styles.Render("~/Css/Admin/Easyui")@Scripts.Render("~/bundles/jquery")@Scripts.Render("~/Scripts/Easyui")@Scripts.Render("~/Areas/Admin/Scripts/global.js")</head><body class="easyui-layout"><div id="north" data-options="region:'north'">@Html.Action("PartialNorth","Home")</div><div id="south" data-options="region:'south'"></div>@RenderBody()</body></html>
2、后台管理的主页——Home
在~/Areas/Admin/Controllers 添加【HomeController】
为[Index] action添加视图
@{ViewBag.Title = "管理中心";}<div id="west" data-options="region:'west',title:' ',split:true" style="border-top:solid 1px #1BA1E2;border-right:solid 1px #1BA1E2;border-bottom:solid 1px #1BA1E2"></div><div id="center" data-options="region:'center'"><div id="tabs" class="easyui-tabs" data-options="fit:true" style="margin-left: auto; margin-right: auto"><div title="欢迎" style="padding:20px;">欢迎使用后台管理……</div></div></div>
这里用到了easyui的layout和tabs。
添加返回分部视图的action [PartialNorth] 这个在布局也中调用,显示layout的North部分,也就是页面的头部(图中1的位置)。
/// <summary>/// 顶部视图/// </summary>/// <returns></returns>public PartialViewResult PartialNorth(){return PartialView();}
添加相应视图。
<div class="admininfo_bar">欢迎您:洞庭夕照 修改密码 退出 </div><div class="tools_bar"><a id="home" href="#"><img src="~/Areas/Admin/Content/images/home.png" /> 首页</a><a id="cagegory_cfg" href="#"><img src="~/Areas/Admin/Content/images/folder.png" /> 栏目管理</a><a id="system_cfg" href="javascript:void(0)"><img src="~/Areas/Admin/Content/images/config.png" /> 系统设置</a></div>
完成后界面如下:
联系客服