天天看點

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

複制去Google翻譯 翻譯結果 [ HttpPost ]

轉載于:https://www.cnblogs.com/younghan/p/4137207.html

繼續閱讀