控制器、过滤器和路由

一、控制器

ActionResult概述:

(1)在ASP.NET MVC中,一个控制器可以包含多个操作方法。 每一个操作方法都返回一个ActionResult实例对象。

(2)nActionResult是一个抽象的基类,其最常用的派生类如下:

ActionResult派生类型 作用
ViewResult 用于返回标准的视图页面
EmptyResult 不返回任何数据
ContentResult 以字符串的形式指定响应的内容
FileResult 返回任意文档内容
JavaScriptResult 响应一段JavaScript脚本内容
JsonResult 返回一段Json内容

(1)ViewResult

ViewResult:用户返回标准的视图页面。

视图模型类:

public class Student
{
    public string StuId { get; set; }
    public string StuName { get; set; }
}

Action:

public ActionResult Test()
{
    Student stu = new Student();
    stu.StuId = "001";
    stu.StuName = "刘备";
    return View(stu);
}

View:

@model WebApplication2.Controllers.Student
@{
    Layout = null;
}
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Test</title>
</head>
<body>
    <div> 
        <h1>学号: @Model.StuId</h1>
        <h1>姓名: @Model.StuName</h1>
    </div>
</body>
</html>

(2)EmptyResult

EmptyResult:不返回任何数据。

Action:

//此Action即使有对应的视图,也不会显示视图内容,显示空页面
public ActionResult Test()
{
    return new EmptyResult();
}

(3)ContentResult

ContentResult:以字符串的形式指定响应的内容。

Action:

public ActionResult Test()
{
	return Content("<h1>我是ContentResult返回的标题标签!</h1>","text/html");
}

利用ContentResult制作多页面风格切换:

【样式表文件如下】:

spring.css

/*春天风格*/
body {
    background-image:url(/Img/spring.jpg);
    background-repeat:no-repeat;
    background-size:cover;
}

summer.css

/*夏天风格*/
body {
    background-image:url(/Img/summer.jpg);
    background-repeat:no-repeat;
    background-size:cover;
}

autumn.css

/*秋天风格*/
body {
    background-image:url(/Img/autumn.jpg);
    background-repeat:no-repeat;
    background-size:cover;
}

winter.css

/*冬天风格*/
body {
    background-image:url(/Img/winter.jpg);
    background-repeat:no-repeat;
    background-size:cover;
}

【Action:】

#region 使用ContentResult制作多页面风格切换
public ActionResult Demo01()
{
    return View();
}
[HttpPost]
public ActionResult Demo01(string themesName)
{
    HttpCookie c = new HttpCookie("theme", themesName);
    c.Expires = DateTime.MaxValue;
    Response.SetCookie(c);
    //return View();
    //此处Response.SetCookie等页面刷新完了之后才进行设置cooike,必须让页面重新刷新一次
    //下列的脚本让页面重新刷新到Demo01
    return Content("<script>window.location.href='Demo01';</script>", "text/html");
}
public ActionResult Demo01TestPage(string themesName)
{
    return View();
}
public ActionResult CssResult()
{
    string cssFileName = "";
    if (Request.Cookies["theme"] == null || Request.Cookies["theme"].Value.Equals(""))
    	cssFileName = "spring.css";
    else
    	cssFileName = Request.Cookies["theme"].Value + ".css";
    return Content(cssFileName, "text/html");
}
#endregion

【View:】

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Demo01</title>
    <link href="~/Content/themes/@Html.Action("CssResult")" rel="stylesheet" />
</head>
<body>   
    <div> 
        <h1>风格切换</h1>
        <form action="Demo01" method="post">
            <p><input type="radio" name="themesName" value="spring" />春回大地</p>
            <p><input type="radio" name="themesName" value="summer" />烈日当空</p>
            <p><input type="radio" name="themesName" value="autumn" />一叶知秋</p>
            <p><input type="radio" name="themesName" value="winter" />冰天雪地</p>
            <p><input type="submit" value="风格切换"></p>
        </form>
        <a href="Demo01TestPage" target="_blank">跳转到其它页面测试风格</a>
    </div>
</body>
</html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Demo01TestPage</title>
    <link href="~/Content/themes/@Html.Action("CssResult")" rel="stylesheet" />
</head>
<body>
    <div>
        <h1>风格切换测试页面</h1> 
    </div>
</body>
</html>

(4)FileResult

【1】使用FileResult加载图片:

Action:

public ActionResult Demo02()
{
	return View();
}
public ActionResult GetImg(string id)
{
    string path = Server.MapPath("~/Img/" + id + ".png");
    return File(path, "image/png");
}

View:

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Demo02</title>
    <style type="text/css">
        li {
            list-style-type: none;
            float: left;
            margin: 10px 10px 0px 0px;
        }
        img {
            width: 100px;
            height: 100px;
        }
    </style>
</head>
<body>
    <ul>
        <li>
            <img alt="001" src="@Url.Action("GetImg", new { id = "001" })" />
        </li>
        <li>
            <img alt="002" src="@Url.Action("GetImg", new { id = "002" })" />
        </li>
        <li>
            <img alt="003" src="@Url.Action("GetImg", new { id = "003" })" />
        </li>
        <li>
            <img alt="004" src="@Url.Action("GetImg", new { id = "004" })" />
        </li>
        <li>
            <img alt="005" src="@Url.Action("GetImg", new { id = "005" })" />
        </li>
        <li>
            <img alt="006" src="@Url.Action("GetImg", new { id = "006" })" />
        </li>
    </ul>
</body>
</html>

【2】使用FileResult实现文件下载:

Action:

public ActionResult Demo03()
{
	return View();
}
public ActionResult GetFile()
{
    //如需对下载文件进行权限判断
    //1-将文件迁移至Web服务以外的路径(也可以是单独文件服务器)。
    //2-在下载之前进行权限的逻辑判断。
    string path = Server.MapPath("~/File/ASP.NET MVC 5高级编程.rar");
    return File(path, "application/octet-stream", "ASP.NET MVC 5高级编程.rar");
}

View:

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Demo03</title>
</head>
<body>
    <div> 
        学习资料下载
        <a target="_blank" href="@Url.Action("GetFile")">ASP.NET MVC 5高级编程</a>
    </div>
</body>
</html>

(5)JavaScriptResult

JavaScriptResult:用于响应一段JavaScript脚本内容

Action:

public ActionResult Test()
{
	return View();
}
public ActionResult JsResult()
{
	return JavaScript("alert('hello,world!');");
}

View:

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Test</title>
    <script src="~/Script/jquery-3.5.1.js"></script>
    <script>
        $(function () {
            $.getScript("/Home/JsResult");
        })
    </script>
</head>
<body>
    <div> 
        <h1>JavaScriptResult的使用!</h1>
    </div>
</body>
</html>

(6)JsonResult

JsonResult:用于返回Json内容。

模型实体类:

public class Student
{
    public Student() { }
    public Student(string id,string name,string sex)
    {
        this.StuId = id;  this.StuName = name;  this.StuSex = sex;
    }
    public string StuId { get; set; }
    public string StuName { get; set; }
    public string StuSex { get; set; }
}

Action:

public ActionResult Test()
{
    return View();
}

public ActionResult JsonResult()
{
    List<Student> list = new List<Student>();
    list.Add(new Student("001", "刘备", "男"));
    list.Add(new Student("002", "关羽", "男"));
    list.Add(new Student("003", "张飞", "男"));
    return Json(list);
}

View:

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Test</title>
    <style type="text/css">
        div, table, tr, td {margin: 0px;padding: 0px;}
        .myTable {width: 800px; margin: 20px auto; border-collapse: collapse;}
        .myTable td {height: 30px; line-height: 30px; padding: 6px;}
    </style>
    <script src="~/Script/jquery-3.5.1.js"></script>
    <script>
        $(function () {
            $.ajax({
                type: "POST",
                url: "JsonResult",
                //data: "name=John&location=Boston",
                dataType:"json",
                success: function (jarr) {
                    var strTable = "";
                    //for (var i = 0; i < jarr.length; i++) {
                    //    strTable += "<tr>";
                    //    strTable += "<td>" + jarr[i].StuId + "</td>";
                    //    strTable += "<td>" + jarr[i].StuName + "</td>";
                    //    strTable += "<td>" + jarr[i].StuSex + "</td>";
                    //    strTable += "</tr>";
                    //}
                    $.each(jarr,function (i, item) {
                        strTable += "<tr>";
                        strTable += "<td>" + item.StuId + "</td>";
                        strTable += "<td>" + item.StuName + "</td>";
                        strTable += "<td>" + item.StuSex + "</td>";
                        strTable += "</tr>";
                    });
                    $("#myTable").append(strTable);
                }
            });
        })
    </script>
</head>
<body>
    <table class="myTable" id="myTable" border="1">
        <tr>
            <th>学号</th>
            <th>姓名</th>
            <th>性别</th>
        </tr>
    </table>
</body>
</html>

二、过滤器

通常控制器的操作方法在执行前后,需要处理运行过程中所产生的状况,为了满足此要求,ASP.NET MVC提供过滤器来处理。

支持的过滤器类型有四种,分别是:Authorization(授权),Action(行为),Result(结果)和Exception(异常)。

过滤器类型 接口 继承类 描述
Authorization IAuthorizationFilter AuthorizeAttribute 此类型(或过滤器)用于限制执行控制器或控制器的某个操作方法
Exception IExceptionFilter HandleErrorAttribute 用于指定一个操作,用于处理控制器中抛出的异常
Action IActionFilter ActionFilterAttribute 用于执行操作之前或之后的处理
Result IResultFilter ActionFilterAttribute 用于返回结果的之前或之后的处理

(1)授权过滤器

Authorize:授权过滤器是最先运行的过滤器,可以用于对操作方法在正式运行前做一些额外的判断,例如,授权检查、是否为SSL完全链接、验证输入信息是否包含攻击字符串等。

示例1:使用Authorize过滤器实现页面的访问授权

用户登录授权之后才能访问的Action和View:

[Authorize]
public ActionResult Demo04()
{
    return View();
}
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Demo04</title>
</head>
<body>
    <div> 
        <h1>我是授权过滤器的测试页面,未登录情况无法访问,登录之后才能访问!</h1>
        <h1>
            <a href="~/Home/Demo04LoginOut">退出</a>
        </h1>
    </div>
</body>
</html>

用户登录页面的Action和View:

public ActionResult Demo04Login()
{
    //需要在根目录的web.config文件中做默认登录验证页面的设置
    //< authentication mode = "Forms" >
    //   < forms loginUrl = "~/Home/Demo04LoginForm/" timeout = "2000" ></ forms >
    // </ authentication >
    return View();
}
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Demo04Login</title>
    <style type="text/css">
        div, table, tr, td {margin: 0px;padding: 0px;}
        .myTable {width: 800px; margin: 20px auto; border-collapse: collapse;}
        .myTable td {height: 30px; line-height: 30px; padding: 6px;}
    </style>
</head>
<body>
    <form method="post" >
        <div style="text-align:center;">
            <table width="800" class="myTable" border="1">
                <tr>
                    <td colspan="2" align="center" style="font-weight:bold;">用户登录</td>
                </tr>
                <tr>
                    <td width="200" align="right">用户名:</td>
                    <td width="600" align="left"><input type="text" name="txtAccount" /></td>
                </tr>
                <tr>
                    <td width="200" align="right">密码:</td>
                    <td width="600" align="left"><input type="password" name="txtPwd" /></td>
                </tr>
                <tr>
                    <td width="200" align="right"></td>
                    <td width="600" align="left">
                        <input type="submit" value="登录" />
                        @TempData["ErrInfo"]
                    </td>
                </tr>
            </table>
        </div>
    </form>
</body>
</html>

配置文件的配置:(在system.web节点中进行配置)

<authentication mode="Forms">
  <forms loginUrl="~/Home/Demo04Login"  timeout="2000"></forms>
</authentication>

响应登录请求的Action:

[HttpPost]
public ActionResult Demo04Login(string txtAccount,string txtPwd)
{
    //假设用户名 admin,密码 admin 才能登录成功,其它登录失败
    string acc = txtAccount;
    string pwd = txtPwd;
    if (acc.Equals("admin") && pwd.Equals("admin"))
    {
        //第二个参数,true:持久化cookie,false:会话性cookie(即关闭浏览器后消失)
        FormsAuthentication.SetAuthCookie(acc, false);
        //return RedirectToAction("Demo04");
        //此处如果需要优化,跳转到成功登录前的最后历史记录的地址
        if (Request.QueryString["ReturnUrl"] == null)
        {
            return RedirectToAction("Demo04");
        }
        else
        {
            return Redirect("~/" + Request.QueryString["ReturnUrl"]);
        }                            
    }
    else
    {
        TempData["ErrInfo"] = "用户名或密码错误"; //TempData可以在跳转后保存接受数据,但只会在一次跳转中保存。
        return View();
    }
}

退出登录的Action:

public ActionResult Demo04LoginOut()
{
	FormsAuthentication.SignOut();
	return Redirect("Demo04Login");
}

示例2:垃圾话过滤

自己编写一个过滤器实现垃圾话判断:

namespace Chp09_Action_过滤器_路由.Filters
{
    public class MyAuthorizeAttribute: AuthorizeAttribute
    {
        //授权的逻辑处理
        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            //直接跳转到警告页面
            for (int i = 0; i < filterContext.HttpContext.Request.Form.Count; i++)
            {
                if (filterContext.HttpContext.Request.Form[i].ToString().Contains("垃圾"))
                {
                    filterContext.Result = new RedirectResult("~/Home/Demo05WarningForm");
                    return;
                }
            }
        }
    }
}

留言板页面Action和View:

public ActionResult Demo05CommentForm()
{
	return View();
}
<div>
    <form action="~/Home/Demo05" method="post">
        <h2>留言:</h2>
        <p>
            <textarea name="MyWord" id="MyWord" rows="10" cols="80"></textarea>
        </p>
        <p>
            <input type="submit" value="我要留言" />
        </p>
    </form>
</div>

处理留言提交数据的Action和View:

//我们不一定要用MVC默认的Authorize授权验证规则,规则可以自己来定,
//自定义授权过滤器可以继承AuthorizeAttribute这个类,这个类里面有两个重要函数可以重写
// bool AuthorizeCore(HttpContextBase httpContext):这里主要是授权验证的逻辑处理,返回true的则是通过授权,返回了false则不是。
// void HandleUnauthorizedRequest(AuthorizationContext filterContext):这个方法是处理授权失败的事情。
[MyAuthorizeAttribute]
//此示例运行Demo05CommentForm进行测试
public ActionResult Demo05()
{
    ViewBag.Info = Request["MyWord"].Replace("\r", "<br />").Replace("\n", "<br />").Replace("\r\n", "<br />");
    return View();
}
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Demo05</title>
</head>
<body>
    <div>
        <h1>留言内容:</h1>
        <p>@Html.Raw(ViewBag.Info)</p>
    </div>
</body>
</html>

警告信息显示的Action和View:

public ActionResult Demo05WarningForm()
{
    return View();
}
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Demo05WarningForm</title>
</head>
<body>
    <div> 
        <h1>您的留言内容不符合互联网文明规范</h1>
        <h1>警告:如发现您多次违规,将对您进行封号处理!</h1>
    </div>
</body>
</html>

(2)行为过滤器

ActionFilterAttribute是Action过滤类,该属于会在执行一个action之前先执行.而ActionFilterAttribute是 MVC的一个专门处理action过滤的类。

示例一:行为过滤器实现页面访问授权

自己编写一个过滤器实现页面访问授权:

namespace Chp09_Action_过滤器_路由.Filters
{
    public class MyActionFilter : ActionFilterAttribute
    {
        public string LoginOutUrl { get; set; }
        //当请求执行的时候
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (filterContext.HttpContext.Session["Account"] == null)
            {
                string url = filterContext.HttpContext.Request.RawUrl;
                filterContext.Result = new RedirectResult(this.LoginOutUrl+ "?ReturnUrl="+url);
                return;
            }
        }
    }
}

用户登录授权之后才能访问的Action和View:

[MyActionFilter(LoginOutUrl = "/Home/Demo06Login", Order = 1)]
public ActionResult Demo06()
{
    return View();
}
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Demo06</title>
</head>
<body>
    <div>
        <h1>欢迎来到**系统,当前用户:@Session["Account"]</h1>
        <h1>
            <a href="~/Home/Demo06OutForm">退出系统</a>
        </h1>
    </div>
</body>
</html>

用户登录页面的Action和View:

public ActionResult Demo06Login()
{
    return View();
}
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Demo06Login</title>
    <style type="text/css">
        div, table, tr, td {margin: 0px;padding: 0px;}
        .myTable {width: 800px; margin: 20px auto; border-collapse: collapse;}
        .myTable td {height: 30px; line-height: 30px; padding: 6px;}
    </style>
</head>
<body>
    <form method="post">
        <div style="text-align:center;">
            <table width="800" class="myTable" border="1">
                <tr>
                    <td colspan="2" align="center" style="font-weight:bold;">用户登录</td>
                </tr>
                <tr>
                    <td width="200" align="right">用户名:</td>
                    <td width="600" align="left"><input type="text" name="txtAccount" /></td>
                </tr>
                <tr>
                    <td width="200" align="right">密码:</td>
                    <td width="600" align="left"><input type="password" name="txtPwd" /></td>
                </tr>
                <tr>
                    <td width="200" align="right"></td>
                    <td width="600" align="left">
                        <input type="submit" value="登录" />
                        @TempData["ErrInfo"]
                    </td>
                </tr>
            </table>
        </div>
    </form>
</body>
</html>

响应登录请求的Action:

[HttpPost]
public ActionResult Demo06Login(string txtAccount, string txtPwd)
{
    //假设用户名 admin,密码 admin 才能登录成功,其它登录失败
    string acc = txtAccount;
    string pwd = txtPwd;
    if (acc.Equals("admin") && pwd.Equals("admin"))
    {
        Session["Account"] = acc;
        if (Request.QueryString["ReturnUrl"] == null)
        {
            return RedirectToAction("Demo06");
        }
        else
        {
            return Redirect("~/" + Request.QueryString["ReturnUrl"]);
        }
    }
    else
    {
        TempData["ErrInfo"] = "用户名或密码错误"; //TempData可以在跳转后保存接受数据,但只会在一次跳转中保存。
        return View();
    }
}

退出登录的Action:

public ActionResult Demo06OutForm()
{
    Session.Abandon();
    return RedirectToAction("Demo06Login");
}

示例二:行为过滤器实现权限判断

此案例单独执行的时候必须登录成功才能测试其权限,如果没有登录,直接打开需要权限的页面会报错,解决此报错可以和验证是否登录的过滤器结合使用。

用户信息模型实体类:

public class Member
{
    public string Acc { get; set; }
    public string Pwd { get; set; }
    public string Power { get; set; }
    public Member() { }
    public Member(string acc, string pwd, string power)
    {
        this.Acc = acc; this.Pwd = pwd; this.Power = power;
    }
}

自己编写一个过滤器实现权限判断:

public class PowerFilter: ActionFilterAttribute
{
    public string PowerOutUrl { get; set; } //没有权限跳转的地址
    public string PowerName { get; set; }	//当前Action的权限编号
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        string[] arrPower = filterContext.HttpContext.Session["Power"].ToString().Split(',');
        if (!arrPower.Contains(this.PowerName))
        {
            filterContext.Result = new RedirectResult(this.PowerOutUrl);
            return;
        }
    }
}

需要权限才能访问的Action:

// 具有001权限可以进入的Action
[PowerFilter(Order =1,PowerName ="001",PowerOutUrl = "PowerOut")]
public ActionResult Demo01()
{
	return View();
}

//具有002权限可以进入的Action
[PowerFilter(Order = 1, PowerName = "002", PowerOutUrl = "PowerOut")]
public ActionResult Demo02()
{
	return View();
}

具有权限才能访问的View:

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Demo01</title>
</head>
<body>
    <h1> 
        我是具有001权限的人可以进入的页面!
    </h1>
    <a href="LoginOut">退出</a>
</body>
</html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Demo02</title>
</head>
<body>
    <h1> 
        我是具有002权限的人可以进入的页面!
    </h1>
    <a href="LoginOut">退出</a>
</body>
</html>

登录相关的Action:

public ActionResult Login()
{
    return View();
}

[HttpPost]
public ActionResult Login(string Acc, string Pwd)
{
    List<Member> listMem = new List<Member>();
    listMem.Add(new Member("admin", "admin", "001,002"));
    listMem.Add(new Member("liubei", "123456", "001"));
    var result = listMem.SingleOrDefault(p => p.Acc.Equals(Acc) && p.Pwd.Equals(Pwd));
    if (result != null)
    {
        Session["Acc"] = result.Acc;
        Session["Power"] = result.Power;
        return RedirectToAction("Demo01");
    }
    else
    {
        ViewBag.ErrInfo = "用户名或密码错误!";
        return View();
    }
}

登录页面View:

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Login</title>
</head>
<body>
    <form method="post">
        <p>
            账号:<input type="text" name="Acc" />
        </p>
        <p>
            密码:<input type="password" name="Pwd" />
        </p>
        <p>
            <input type="submit" value="登  录" /> @ViewBag.ErrInfo
        </p>
    </form>
</body>
</html>

退出的Action:

public ActionResult LoginOut()
{
    Session.Abandon();
    return RedirectToAction("Login");
}

判断没有权限之后跳转的Action和View:

public ActionResult PowerOut()
{
	return View();
}
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>PowerOut</title>
</head>
<body>
    <h1> 
        对不起,您没有此权限!
    </h1>
</body>
</html>

(3)异常过滤器

在asp.net mvc中除了使用try...catch/finally来处理异常外,它提供了HandleErrorAttribute类,通过在Controller或者Action上添加特性的方式来处理异常。

示例:编写通用的异常处理操作

自己编写处理异常的过滤器:

namespace Chp09_Action_过滤器_路由.Filters
{
    public class MyExceptionFilter : HandleErrorAttribute
    {
        public override void OnException(ExceptionContext filterContext)
        {
            filterContext.Result = new RedirectResult("/Home/Demo07ErrorForm?Message=" + filterContext.Exception.Message.Replace("\r\n", "").Replace("\r", "").Replace("\n", ""));
            filterContext.ExceptionHandled = true;
            return;
        }
    }
}

异常信息显示的Action和View:

public ActionResult Demo07ErrorForm()
{
    ViewBag.Message = Request["Message"];
    return View();
}
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Demo07ErrorForm</title>
</head>
<body>
    <div style="margin-top:10px; text-align:center;">
        <img src="~/Img/error.jpg" />
    </div>
    <div style="height:40px; line-height:40px; font-size:18px; font-weight:bold; text-align:center;">
        不好意思,程序产生异常了,请尽快与本公司进行联系,异常信息如下:
    </div>
    <div style="height:40px; line-height:40px; font-size:18px; font-weight:bold; text-align:center;">
        @ViewBag.Message
    </div>
</body>
</html>

编写异常的Action和View来测试过滤器:

[MyExceptionFilter]
public ActionResult Demo07()
{
    int a = 10;
    int b = 0;
    int c = a / b;
    return View();
}
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Demo07</title>
</head>
<body>
    <div> 
        <h1>测试异常过滤器</h1>
    </div>
</body>
</html>

三、路由

路由用于设计访问的URL地址。

(1)默认路由

.NET MVC默认路由如下(App_Start/RouteConfig.cs):

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

解释:

name:路由的名称;
url:路由URL的格式形式;
defaults:对URL格式进行默认值等的设置;
id = UrlParameter.Optional:代表id为可选参数;

访问规则一:

假设有HomeController控制器,控制器里面有Index操作方法:

public class HomeController : Controller
{
    // GET: Home
    public ActionResult Index()
    {
        return View();
    }
}

那么如下地址都是可以访问到此Action的:

http://localhost:65447/
http://localhost:65447/Home
http://localhost:65447/Home/Index
http://localhost:65447/Home/Index/100      --此地址虽然可以访问,但是在控制器里无法接受最后的id=100

访问规则二:

假设有HomeController控制器,控制器里面有Index操作方法:

public class HomeController : Controller
{
    // GET: Home
    public ActionResult Index(int? id)
    {
        ViewBag.Id = id;
        return View();
    }
}

那么如下地址都是可以访问到此Action的:

http://localhost:65447/
http://localhost:65447/Home
http://localhost:65447/Home/Index
http://localhost:65447/Home/Index/100      --此情况下Action可以接受到id=100的参数

(2)路由冲突

路由代码如下:

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

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

假设有HomeController控制器,有如下控制器:

public ActionResult Index()
{
    return View();
}

public ActionResult Demo01()
{
    return View();
}

那么如下的Action的访问如下:

http://localhost:65447/					--访问Demo01
http://localhost:65447/Home				--访问Demo01
http://localhost:65447/Home/Index		--访问Index

(3)自定义路由规则

案例一:

路由定义如下:

routes.MapRoute(
    name: "News", 
    url: "{controller}/{action}/{year}-{month}-{day}",
    defaults: new { controller = "Home", action = "News", id = UrlParameter.Optional }
);

假设有HomeController控制器,如下Action:

public ActionResult Demo02(int year, int month, int day)
{
    ViewBag.News = "新闻:" + year + "-" + month + "-" + day;
    return View();
}

那么可以通过如下地址访问此Action:

http://localhost:50477/Home/Demo02/2002-8-9

案例二:

路由定义如下:

routes.MapRoute(
    name: "News", 
    url: "{controller}/{action}/{year}/{month}/{day}",
    defaults: new { controller = "Home", action = "News", id = UrlParameter.Optional }
);

如下Action:

public ActionResult Demo02(int year, int month, int day)
{
    ViewBag.News = "新闻:" + year + "-" + month + "-" + day;
    return View();
}

那么可以通过如下地址访问此Action:

http://localhost:50477/Home/Demo02/2002/8/9

案例三:

路由定义如下:

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

假设有ManageController控制器,有如下Action:

public ActionResult Index()
{
	return View();
}

那么可以通过如下地址访问此Action:

http://localhost:50477/Manage/Index
http://localhost:50477/Admin
http://localhost:50477/Admin/Index
posted @ 2022-04-02 17:14  码农阿亮  阅读(54)  评论(0编辑  收藏  举报