【ASP.NET MVC】個人復習整理


1、為 Action 標注 Attribute 限制訪問

public class HomeController : Controller
{
    [HttpPost]
    public ActionResult Index()
    {
        return View();
    }
}

那么該 Index 的 Action 就只能夠通過 Post 方法請求,其它例如 Get 方法請求則響應 404。

2、設置 View 所使用的 Model

假設有 Person 類。

則 Controll 代碼:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new Person();// 構建或從數據庫獲取一個 Person 類實例。
        return View(model);
    }
}

或者可以設置 ViewData 的 Model 屬性。

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new Person();
        ViewData.Model = model;
        return View();
    }
}

View 代碼:

@* 聲明該 View 的 Model 類型 *@
@model Namespace.Person

……
    @* 輸出 Person 對象的 Name 屬性 *@
    @Model.Name
……

當然不聲明 View 的 Model 類型也是可以的,但是這會失去 Model 類型約束以及語法提示等功能。

在聲明了 Model 類型的情況下,View 繼承自 WebViewPage<TModel> 抽象類。

而不聲明 Model 類型的情況下,View 則繼承自 WebViewPage<dynamic> 抽象類。

3、Model 驗證

修改 Person 類,添加相應的 ValidationAttribute

public class Person
{
    [Required]
    [StringLength(5)]
    public string Name
    {
        get;
        set;
    }

    [Range(0, 150)]
    public int Age
    {
        get;
        set;
    }

    [Required]
    [EmailAddress]
    [DataType(DataType.EmailAddress)]
    public string Email
    {
        get;
        set;
    }
}

Controller 驗證:

public class HomeController : Controller
{
    [HttpPost]
    public ActionResult Create(Person person)
    {
        if (ModelState.IsValid)
        {
            return Content("驗證成功");
        }
        else
        {
            return Content("驗證失敗");
        }
    }
}

View 中的客戶端驗證:

<body>
    @* 引用 jquery 以及客戶端驗證腳本 *@
    <script src="~/Scripts/jquery-1.8.2.min.js"></script>
    <script src="~/Scripts/jquery.validate.min.js"></script>
    <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>

    @using (Html.BeginForm())
    {
        <div>
            @Html.LabelFor(model => model.Name)
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>
        <div>
            @Html.LabelFor(model => model.Age)
            @Html.EditorFor(model => model.Age)
            @Html.ValidationMessageFor(model => model.Age)
        </div>
        <div>
            @Html.LabelFor(model => model.Email)
            @Html.EditorFor(model => model.Email)
            @Html.ValidationMessageFor(model => model.Email)
        </div>
        <div>
            <input type="submit" value="提交" />
        </div>
    }
</body>

效果:

QQ截圖20150909163453

4、修改 Route 路由偽裝成 php

查找項目中的 RegisterRoutes 方法。默認路由如下:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new
        {
            controller = "Home",
            action = "Index",
            id = UrlParameter.Optional
        }
    );
}

主要關心 MapRoute 這個擴展方法的 url 參數和 defaults 參數。在 url 參數中,通過花括號映射參數名,例如 {controller} 則映射到 controller,{id} 則映射到 id。所以如果有 /A/B/C 的 url 傳入,則映射到 AController 的 B 方法並傳入 C 作為 id 參數的值。

當然我們也可以簡單修改路由來簡單偽造成 php 頁面。

修改 url 為 "{controller}-{action}-{id}.php"。

然后在項目根目錄的 Web.config 中添加一項,如下圖:

QQ截圖20150909171426

然后就可以訪問了,輸入例如 /Home-Index-0.php 之類的 url。效果:

QQ截圖20150909171750

當然也可以改成 jsp 或者其它來裝逼。

5、Route 路由中的 UrlParameter.Optional

接下來講解 defaults 參數,這個參數需要構造一個匿名類,並且這個匿名類的屬性的名稱需要跟 url 中相同。(當然多出一些沒用到的屬性也可)

默認路由中,controller 和 action 兩個都很好懂,就是沒有值的時候,分別使用 Home 和 Index。但 id 這個就不太好懂了。

經過查閱 msdn 及前人相關的資料我們可以知道,UrlParameter.Optional 是指假若沒有提供值,則給予默認值。還是舉個例子吧。

例如:

public class HomeController : Controller
{
    public ActionResult Index(int id)
    {
        return View();
    }
}

那么這里的 id 就是 0。

public class HomeController : Controller
{
    public ActionResult Index(string id)
    {
        return View();
    }
}

那么現在這個的 id 就是 null。

可見,UrlParameter.Optional 就相當於 default 關鍵字的作用。

6、繼承 ActionFilterAttribute 實現 AOP 面向切面編程

首先我們需要新建一個 Attribute 並繼承 ActionFilterAttribute。我就叫 TestActionAttribute 好了。

public class TestActionAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        Debug.WriteLine("OnActionExecuted");
        base.OnActionExecuted(filterContext);
    }

    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Debug.WriteLine("OnActionExecuting");
        base.OnActionExecuting(filterContext);
    }

    public override void OnResultExecuted(ResultExecutedContext filterContext)
    {
        Debug.WriteLine("OnResultExecuted");
        base.OnResultExecuted(filterContext);
    }

    public override void OnResultExecuting(ResultExecutingContext filterContext)
    {
        Debug.WriteLine("OnResultExecuting");
        base.OnResultExecuting(filterContext);
    }
}

然后標注到 Action 上,運行。

我們可以見到按順序輸出:

OnActionExecuting

OnActionExecuted

OnResultExecuting

OnResultExecuted

在前面兩個方法間是執行我們的 Action,在后面兩個方法間是執行我們 Action 返回的 ActionResult。

那么這東西有什么用呢。舉個小例子,可以用做驗證。

修改 OnActionExecuting 方法。

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    var request = filterContext.HttpContext.Request;
    var userAgent = request.UserAgent;        
    if (userAgent.IndexOf("chrome",StringComparison.OrdinalIgnoreCase)>=0)
    {
        filterContext.Result = new ContentResult()
        {
            Content = "chrome 禁止訪問"
        };
    }
}

這里我們檢測 UserAgent,如果是 chrome 那么就不能訪問了。

運行之后,我們會發現 chrome 輸出禁止訪問,而 ie 等其它瀏覽器則仍然能繼續訪問。同時我們也可以通過斷點驗證到,chrome 訪問的情況下,標注的 Action 的方法體不會再執行,即設置了 filterContext 的 Result 屬性之后,就不再往下執行 Action 的流程了。(ActionResult 的流程還是依然執行的,也就是說 OnResultExecuting 和 OnResultExecuted 還是會繼續執行的說)

這個只是個小例子,具體實際業務情況可以做用戶登錄驗證、日志記錄等等。

 

好久沒碰 ASP.NET MVC,算是簡單復習下。


免責聲明!

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



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