现在做网站用mvc越来越普及了,其好处就不说了,在这里只记录一些很多人都容易忽视的地方。

引用本地css和js文件的写法

这应该是最不受重视的地方,有同事也说我有点小题大作,但我觉得用mvc还是得有一个好习惯,对于维护那肯定是有帮助的。

首先是下面的代码(推荐写法)

<link href="@Url.Content("~/content/style.css")" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="@Url.Content("~/scripts/jquery-1.9.1.min.js")"></script>

很少人会这样写,大多数人应该是这样

<link href="/content/style.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/scripts/jquery-1.9.1.min.js"></script>

有什么区别,推荐的写法会要多一点代码,我也发现很多人都喜欢能省就省,而且也会说渲染出来的html代码和第二种没啥区别。是的,但是如果部署成站点下的虚拟目录情况就不一样了,第二种写法可能就会给你带来灾难了,所以还是开始就勤快点吧,以后就不会痛苦了。

超链接的写法

推荐写法

<a href="@Url.Action("index","home")">首页</a>

很多人会这样写

<a href="/home/index">首页</a>

两者的区别还是在于维护,一旦改变了路由规则,那么第二种方式改起来还是头疼的,第一种方式就不需要作任何改动了。

模型验证

尽管mvc自带的验证方式已经有很多了,但是在开发过程中总会有一些特殊的地方。举例:用户的手机号为非必填项,如果用户填写了手机号则需验证其合法性。

[Required]
[RegularExpression(@"^1[3|4|5|8]\d{9}$")]
public string Cellphone { get; set; }

上面的代码不能满足非必填项这个要求,最直接的办法就是这样写(先去掉上面的验证方式)

public ActionResult Create(UserModel model)
{
if (ModelState.IsValid) {
if (!string.IsNullOrEmpty(model.Cellphone) && !Regex.IsMatch(model.Cellphone, @"^1[3|4|5|8]\d{9}$")) {
return View(model);
}
}
}

这种方式总感觉很笨笨的,而且也不美观,职责也有点乱,验证规则也最好不应该出现在Controller中。怎么解决?很简单,往往很多人都忽略了CustomValidation

[CustomValidation(typeof(ValidationUtil), "ValidateCellphone")]
public string Cellphone { get; set; }

再定义一个验证类

public static class ValidationUtil
{
public static ValidationResult ValidateCellphone(string cellphone)
{
if (!string.IsNullOrEmpty(cellphone) && !Regex.IsMatch(cellphone, @"^1[3|4|5|8]\d{9}$")) {
return new ValidationResult("错误的手机号码。示例:13800000000");
} return ValidationResult.Success;
}
}

这样就可以在Controller中去掉那块难看的代码了,验证也可以集中维护了,代码也显得优雅一些了。当然还有其他的方式,就是在Model中实现IValidatableObject也可以达到效果。

模型绑定

当一个表单可能是维护多个模型时,我发现之前有同事是这样做的

public ActionResult Create()
{
var domain = new DomainModel() {
Name = Request.Form["domainName"],
...
}; var channel = new ChannelModel() {
Name = Request.Form["channelName"],
...
};
}

看上去有点丑陋还要写好多代码哦,而且模型变化,改动的代码还是蛮多的,其实mvc是支持绑定多个模型的,只需要这样写

[HttpPost]
public ActionResult Create([Bind(Prefix = "domain")]DomainModel domain, [Bind(Prefix = "channel")]ChannelModel channel)
{
}

前端代码只需要简单变动一下

域名:@Html.TextBox("domain.name", string.Empty)
频道名称:@Html.TextBox("channel.name", string.Empty)

这样就可以将元数据绑定到不同的模型上去了

其他细节点

对于Action的参数也尽量这样使用

[HttpPost]
public ActionResult Bandwidth(DateTime start, DateTime end, string serviceId)
{
}

而不是这样

[HttpPost]
public ActionResult Bandwidth()
{
DateTime start = DateTime.Parse(Request.Form["start"]);
DateTime end = DateTime.Parse(Request.Form["end"]);
string serviceId = Request.Form["serviceId"];
} [HttpPost]
public ActionResult Bandwidth(FormCollection form)
{
DateTime start = DateTime.Parse(form.Get("start"));
DateTime end = DateTime.Parse(form.Get("end"));
string serviceId = form.Get("serviceId");
}

mvc自带的json序列化功能比较弱,所以会引入第三方类库,这时会出现这样的用法

return Content(JsonConvert.SerializeObject(data));

当然不建议这样使用,还是那个要素,不利于维护,推荐的做法就是覆写Json方法

protected override JsonResult Json(object data, string contentType, Encoding contentEncoding, JsonRequestBehavior behavior)
{
return new NewJsonResult {
Data = data,
ContentType = contentType,
ContentEncoding = contentEncoding,
JsonRequestBehavior = behavior
};
} class NewJsonResult : JsonResult
{
public override void ExecuteResult(ControllerContext context)
{
context.MustNotNull("context"); if (JsonRequestBehavior == JsonRequestBehavior.DenyGet &&
String.Equals(context.HttpContext.Request.HttpMethod, "GET", StringComparison.OrdinalIgnoreCase)) {
throw new InvalidOperationException("若要允许 GET 请求,请将 JsonRequestBehavior 设置为 AllowGet。");
} HttpResponseBase response = context.HttpContext.Response; if (!String.IsNullOrEmpty(ContentType)) {
response.ContentType = ContentType;
}
else {
response.ContentType = "application/json";
} if (ContentEncoding != null) {
response.ContentEncoding = ContentEncoding;
}
else {
response.ContentEncoding = System.Text.Encoding.UTF8;
} if (Data != null) {
response.Write(JsonConvert.SerializeObject(Data,
new DataTableConverter(), new JavaScriptDateTimeConverter()));
}
}
}

再配合过滤器,如将异常捕获统一写在OnException(ExceptionContext filterContext)中,操作日志写在OnActionExecuting(ActionExecutingContext filterContext)和OnActionExecuted(ActionExecutedContext filterContext)中,认证写在OnAuthorization(AuthorizationContext filterContext)中等等,经过一番考虑之后相信一个mvc项目变得可维护性就更高了,代码也整洁清爽,职责也比较明确。

暂时就想到这么多,后续再慢慢补充。总之要用好mvc是需要深入了解的,啃一下源码也是有收获的。欢迎大家补充。

[HttpPost]

asp.net mvc开发过程中的一些小细节的更多相关文章

  1. [2014-09-21]如何在 Asp.net Mvc 开发过程中更好的使用Enum

    场景描述 在web开发过程中,有时候需要根据Enum类型生成下拉菜单: 有时候在输出枚举类型的时候,又希望输出对应的更具描述性的字符串. 喜欢直接用中文的请无视本文 不多说,直接看代码. 以下代码借鉴 ...

  2. asp.net mvc route 中新发现的小技巧

    在发现这个小技巧之前,我经常被某些问题困扰,我们以博客园为例 1:是分类名称 2:是分类url 3:点击分类,进入的页面,要显示分类的名称 4:点击分类,进入的页面,要用分类相关参数 在日常web的开 ...

  3. asp.net MVC开发过程中,使用到的方法(内置方法及使用说明)

    ® 视图的返回使用案例: [HttpGet] [SupportFilter] public ActionResult UserTopic(string type, string TopPicId, s ...

  4. [转]在 ASP.NET MVC 4 中创建为移动设备优化的视图

    原文链接 https://msdn.microsoft.com/zh-cn/magazine/dn296507.aspx 如果深入探讨有关编写移动设备网站的常识性考虑因素,会发现其中有一种内在矛盾.  ...

  5. 【初学者指南】在ASP.NET MVC 5中创建GridView

    介绍 在这篇文章中,我们将会学习如何在 ASP.NET MVC 中创建一个 gridview,就像 ASP.NET Web 表单中的 gridview 一样.服务器端和客户端有许多可用的第三方库,这些 ...

  6. ASP.NET MVC 4中如何为不同的浏览器自适应布局和视图

    在ASP.NET MVC 4中,可以很简单地实现针对不同的浏览器自适应布局和视图.这个得归功于MVC中的"约定甚于配置"的设计理念. 默认的自适应 MVC 4自动地为移动设备浏览器 ...

  7. 在ASP.NET MVC环境中使用加密与解密

    在.NET Framework 4.5的NET框架中,在程序中加密与解密很方便.现在均学习ASP.NET MVC程序了,因此Insus.NET也在此写个学习的例子.在需要时可以参考与查阅. 写一个Ut ...

  8. 在 ASP.NET MVC 应用中使用 NInject 注入 ASMX 类型的 Web Service

    这几天,有同学问到为什么在 ASP.NET MVC 应用中,无法在 .ASMX 中使用 NInject 进行注入. 现象 比如,我们定义了一个接口,然后定义了一个实现. public interfac ...

  9. 在 ASP.NET MVC 项目中使用 WebForm、 HTML

    原文地址:http://www.cnblogs.com/snowdream/archive/2009/04/17/winforms-in-mvc.html ASP.NET MVC和WebForm各有各 ...

随机推荐

  1. 深度学习项目——基于卷积神经网络(CNN)的人脸在线识别系统

    基于卷积神经网络(CNN)的人脸在线识别系统 本设计研究人脸识别技术,基于卷积神经网络构建了一套人脸在线检测识别系统,系统将由以下几个部分构成: 制作人脸数据集.CNN神经网络模型训练.人脸检测.人脸 ...

  2. 分布式01-Dubbo基础背景

    分布式01-Dubbo基础 1-分布式基础理论 分布式系统是由一组通过网络进行通信.为了完成共同的任务而协调工作的计算机节点组成的系统.分布式系统的出现是为了用廉价的.普通的机器完成单个计算机无法完成 ...

  3. 187. Repeated DNA Sequences重复的DNA子串序列

    [抄题]: All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: &qu ...

  4. pushf和popf

    pushf的功能是将标志寄存器的值压栈,而popf是从栈中弹出数据,送入标志寄存器中.

  5. Less入门及知识点整理

    LESS « 一种动态样式语言 文档链接:http://www.bootcss.com/p/lesscss/ 百科 Less 是一门 CSS 预处理语言,它扩充了 CSS 语言,增加了诸如变量.混合( ...

  6. cpp 区块链模拟示例(一)工程建立

    /* 作 者: itdef 欢迎转帖 请保持文本完整并注明出处 技术博客 http://www.cnblogs.com/itdef/ 技术交流群 群号码:432336863欢迎c c++ window ...

  7. ScrollView嵌套Linearlayout显示不全的解决办法

    以为ScrollView只能嵌套一个元素,所以把几个控件都包裹在了一个LinearLayout中了.但是发现底部显示不全,滑动不到最底下. 代码: <ScrollView android:id= ...

  8. maven +bootstrap+ssm

    http://blog.csdn.net/yangwenxue_admin/article/details/71757505

  9. Something of HTTP

    学习发现所需且所欠知识: 参考:  1.一堆博客   2.HTTP图解(链接奉上,自取)提取码: n6jq http简介 http返回状态码 http方法(点击查看) GET POST PATCH H ...

  10. AI for VS ,美团创新之处分析

    微软在2017中发布了VS Tools for AI,旨在提升用户对于深度学习的需求体验.AI组件可以让我们迅速构建和训练深度学习的Project,其功能主要有开发,调试和部署深度学习和人工智能的解决 ...