asp.net mvc開發過程中的一些小細節


現在做網站用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是需要深入了解的,啃一下源碼也是有收獲的。歡迎大家補充。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM