亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

控制器介紹

系統(tǒng) 2010 0

新建立MVC3項目,名為12-1ControllersAndActions,使用空模板。

Global.asax中默認的路由定義為:

      
        public
      
      
        static
      
      
        void
      
      
         RegisterRoutes(RouteCollection routes)

        {

            routes.IgnoreRoute(
      
      
        "
      
      
        {resource}.axd/{*pathInfo}
      
      
        "
      
      
        );



            routes.MapRoute(

                
      
      
        "
      
      
        Default
      
      
        "
      
      , 
      
        //
      
      
         Route name
      
      
        "
      
      
        {controller}/{action}/{id}
      
      
        "
      
      , 
      
        //
      
      
         URL with parameters
      
      
        new
      
       { controller = 
      
        "
      
      
        Home
      
      
        "
      
      , action = 
      
        "
      
      
        Index
      
      
        "
      
      , id = UrlParameter.Optional } 
      
        //
      
      
         Parameter defaults
      
      
                    );



        }
      
    

一、兩種方法實現(xiàn)自己的控制器

1、用IController創(chuàng)建控制器

在MVC框架中,控制器類必須實現(xiàn)System.Web.Mvc命名空間的IController接口。

System.Web.Mvc.IController接口如下所示:

      
        public
      
      
        interface
      
      
         IController

{

    
      
      
        void
      
      
         Execute(RequestContext requestContext);

}
      
    

接口只有一個方法Execute,在請求目標控制器時將被調(diào)用。

通過實現(xiàn)IController,就可以創(chuàng)建控制器類,但這是一個相當?shù)图壍慕涌冢龃罅抗ぷ鞑拍茏屪约簞?chuàng)建的控制器有效,下面只是一個簡單的演示。

鼠標右擊項目中的Controllers文件夾,選擇 Add -> Class,創(chuàng)建新類,取名為BasicController,代碼如下:

      
        namespace
      
      
         _12_1ControllersAndActions.Controllers

{

    
      
      
        public
      
      
        class
      
      
         BasicController:IController

    {

        
      
      
        public
      
      
        void
      
      
         Execute(RequestContext requestContext)

        {

            
      
      
        string
      
       controller = (
      
        string
      
      )requestContext.RouteData.Values[
      
        "
      
      
        controller
      
      
        "
      
      
        ];

            
      
      
        string
      
       action = (
      
        string
      
      )requestContext.RouteData.Values[
      
        "
      
      
        action
      
      
        "
      
      
        ];

            requestContext.HttpContext.Response.Write(

                
      
      
        string
      
      .Format(
      
        "
      
      
        Controller:{0}, Action:{1}
      
      
        "
      
      
        , controller, action));

        }

    }

}
      
    

?如果運行程序,導航到"~/Basic/Index",根據(jù)路由定義,也可以導航到"~/Basic",產(chǎn)生的結(jié)果為:

Controller:Basic,Action:Index

?

2、一般的做法是創(chuàng)建派生于Controller類的控制器

鼠標右擊項目中的Controllers文件夾,選擇 Add -> Controller,新建控制器,命名為DerivedController,代碼如下:

      
        namespace
      
      
         _12_1ControllersAndActions.Controllers

{

    
      
      
        public
      
      
        class
      
      
         DerivedController : Controller

    {

        
      
      
        //
      
      
        //
      
      
         GET: /Derived/
      
      
        public
      
      
         ActionResult Index()

        {

            ViewBag.Message 
      
      = 
      
        "
      
      
        Hello from the DerivedController Index method.
      
      
        "
      
      
        ;

            
      
      
        return
      
       View(
      
        "
      
      
        MyView
      
      
        "
      
      
        );

        }



    }

}
      
    

在方法Index上鼠標右鍵,添加視圖,視圖取名為MyView

/Views/Derived/MyView.cshtml

      
        @{

    ViewBag.Title = "MyView";

}




      
      
        <
      
      
        h2
      
      
        >
      
      MyView
      
        </
      
      
        h2
      
      
        >
      
      
        <
      
      
        h1
      
      
        >
      
      Message: @ViewBag.Message
      
        </
      
      
        h1
      
      
        >
      
    

?運行程序,導航到"~/Derived/Index",或者根據(jù)路由定義,也可以導航到"~/Derived",產(chǎn)生的結(jié)果為:

MyView

Message:Hello from the DerivedController Index method.

?

二、控制器接收輸入

控制器常常需要訪問輸入數(shù)據(jù),也就是在請求控制器的動作方法時傳遞進來的輸入數(shù)據(jù),如查詢字符串值(指url尾部帶問號?后面跟的部分,稱為url的查詢字符串)、表單值、以及路由系統(tǒng)根據(jù)輸入url解析所得到的參數(shù)。

訪問這些數(shù)據(jù)有三種方式:

通過上下文對象(Context Objects)獲取數(shù)據(jù)。

通過參數(shù)傳遞給動作方法。

使用模型綁定(Model Binding)。

這里主要討論前兩種,模型綁定在后面討論。

1、通過上下文對象獲取數(shù)據(jù)

訪問上下文對象,通過使用一組便利屬性(Convenience Property)來進行訪問。所謂上下文對象,實際上就是訪問的與請求相關的信息。

如果要使用便利屬性來訪問與請求相關的信息,要注意一點,就是只能在派生于Controller的自定義控制器中才能使用。即,如果是通過實現(xiàn)IController接口來完成的自定義控制器里面不能使用這些便利屬性。這些便利屬性包括Request、Response、RouteData、HttpContext、Server等,每個屬性都包含了請求不同方面的信息。見p305,表12-1。

(1)下面通過一個例子來表現(xiàn)這種通過上下文對象獲取數(shù)據(jù)的方式。

在12-1ControllersAndActions項目中,HomeController控制器定義如下:

      
        namespace
      
      
         _12_1ControllersAndActions.Controllers

{

    
      
      
        public
      
      
        class
      
      
         HomeController : Controller

    {

        
      
      
        public
      
      
         ActionResult Index()

        {

            
      
      
        //
      
      
        訪問上下文對象的各個屬性
      
      
        string
      
       userName =
      
         User.Identity.Name;

            
      
      
        string
      
       serverName =
      
         Server.MachineName;

            
      
      
        string
      
       clientIP =
      
         Request.UserHostAddress;

            DateTime dateStamp 
      
      =
      
         HttpContext.Timestamp;

            ViewBag.userName 
      
      =
      
         userName;

            ViewBag.serverName 
      
      =
      
         serverName;

            ViewBag.clientIP 
      
      =
      
         clientIP;

            ViewBag.dateStamp 
      
      =
      
         dateStamp;

            
      
      
        //
      
      
        接收Request.Form所遞交的數(shù)據(jù)

            
      
      
        //
      
      
        string oldProductName = Request.Form["OldName"];

            
      
      
        //
      
      
        string newProductName = Request.Form["NewName"];
      
      
        return
      
      
         View();

        }



    }

}
      
    

?

/Views/Home/Index.cshtml內(nèi)容如下:

      
        @{

    ViewBag.Title 
      
      = 
      
        "
      
      
        Index
      
      
        "
      
      
        ;

}




      
      <h2>Index</h2>

<h2>userName=@ViewBag.userName</h2>

<h2>serverName=@ViewBag.serverName</h2>

<h2>clientIP=@ViewBag.clientIP</h2>

<h2>dataStamp=@ViewBag.dateStamp</h2>
    

這里可以注意,如果希望顯示出一些上下文數(shù)據(jù),而又不想有對應的cshtml文件,那么可以用response.write,例如:

      
        namespace
      
      
         _12_1ControllersAndActions.Controllers

{

    
      
      
        public
      
      
        class
      
      
         HomeController : Controller

    {

        
      
      
        public
      
      
         ActionResult Index()

        {

            
      
      
        //
      
      
        訪問上下文對象的各個屬性
      
      
        string
      
       userName =
      
         User.Identity.Name;

            
      
      
        string
      
       serverName =
      
         Server.MachineName;

            
      
      
        string
      
       clientIP =
      
         Request.UserHostAddress;

            DateTime dateStamp 
      
      =
      
         HttpContext.Timestamp;

            ViewBag.userName 
      
      =
      
         userName;

            ViewBag.serverName 
      
      =
      
         serverName;

            ViewBag.clientIP 
      
      =
      
         clientIP;

            ViewBag.dateStamp 
      
      =
      
         dateStamp;

            
      
      
        //
      
      
        接收Request.Form所遞交的數(shù)據(jù)

            
      
      
        //
      
      
        string oldProductName = Request.Form["OldName"];

            
      
      
        //
      
      
        string newProductName = Request.Form["NewName"];
      
      
        return
      
      
         View();

        }



        
      
      
        public
      
      
        void
      
      
         Index2()

        {

            
      
      
        //
      
      
        訪問上下文對象的各個屬性
      
      
        string
      
       userName =
      
         User.Identity.Name;

            
      
      
        string
      
       serverName =
      
         Server.MachineName;

            
      
      
        string
      
       clientIP =
      
         Request.UserHostAddress;

            DateTime dateStamp 
      
      =
      
         HttpContext.Timestamp;

            Response.Write(
      
      
        string
      
      .Format(
      
        "
      
      
        userName:{0}<br>serverName:{1}<br>clientIP:{2}<br>dataStamp:{3}
      
      
        "
      
      
        , 

                userName, serverName, clientIP, dateStamp));

        }



    }

}
      
    

這里的Index2就沒有對應的cshtml文件對應。程序運行后,輸入地址:"~/Home/Index2"就可以查看到用Response.Write寫出的內(nèi)容。

?

?上下文對象常用的有Request.QueryString、Request.Form和RouteData.Values

(2)通過上下文對象訪問RouteData.Values的例子

上面例子中的項目12-1ControllersAndActions,在HomeController控制器中添加了一個TestInput動作方法,如下:

      
        namespace
      
      
         _12_1ControllersAndActions.Controllers

{

    
      
      
        public
      
      
        class
      
      
         HomeController : Controller

    {

        
      
      
        public
      
      
         ActionResult Index()

        {

            
      
      
        //
      
      
        訪問上下文對象的各個屬性
      
      
        string
      
       userName =
      
         User.Identity.Name;

            
      
      
        string
      
       serverName =
      
         Server.MachineName;

            
      
      
        string
      
       clientIP =
      
         Request.UserHostAddress;

            DateTime dateStamp 
      
      =
      
         HttpContext.Timestamp;

            ViewBag.userName 
      
      =
      
         userName;

            ViewBag.serverName 
      
      =
      
         serverName;

            ViewBag.clientIP 
      
      =
      
         clientIP;

            ViewBag.dateStamp 
      
      =
      
         dateStamp;

            
      
      
        //
      
      
        接收Request.Form所遞交的數(shù)據(jù)

            
      
      
        //
      
      
        string oldProductName = Request.Form["OldName"];

            
      
      
        //
      
      
        string newProductName = Request.Form["NewName"];
      
      
        return
      
      
         View();

        }



        
      
      
        public
      
      
        void
      
      
         Index2()

        {

            
      
      
        //
      
      
        訪問上下文對象的各個屬性
      
      
        string
      
       userName =
      
         User.Identity.Name;

            
      
      
        string
      
       serverName =
      
         Server.MachineName;

            
      
      
        string
      
       clientIP =
      
         Request.UserHostAddress;

            DateTime dateStamp 
      
      =
      
         HttpContext.Timestamp;

            Response.Write(
      
      
        string
      
      .Format(
      
        "
      
      
        userName:{0}<br>serverName:{1}<br>clientIP:{2}<br>dataStamp:{3}
      
      
        "
      
      
        , 

                userName, serverName, clientIP, dateStamp));

        }



        
      
      
        public
      
      
        void
      
      
         TestInput()

        {

            
      
      
        string
      
       inputController = (
      
        string
      
      )RouteData.Values[
      
        "
      
      
        controller
      
      
        "
      
      
        ];

            
      
      
        string
      
       inputAction = (
      
        string
      
      )RouteData.Values[
      
        "
      
      
        action
      
      
        "
      
      
        ];

            
      
      
        int
      
       inputId = Convert.ToInt32(RouteData.Values[
      
        "
      
      
        id
      
      
        "
      
      
        ]);

            Response.Write(
      
      
        string
      
      .Format(
      
        "
      
      
        inputController={0}<br>inputAction={1}<br>inputId={2}
      
      
        "
      
      
        ,

                inputController, inputAction, inputId));

        }



    }

}
      
    

在TestInput動作方法中,通過RouteData.Values["controller"]讀取到當前請求的控制器名字,通過RouteData.Values["action"]讀取到當前請求的動作方法的名字,通過RouteData.Values["id"]訪問到當前請求中的 URL里對應到路由中的自定義變量id的值讀取出來。那么這里RouteData.Values中的controller、action、id屬性來自于哪里,RouteData.Values中還有哪些屬性可用,就取決于在Global.asax中的路由定義。

先看一下為當前這個例子設計的路由定義:

      
        public
      
      
        static
      
      
        void
      
      
         RegisterRoutes(RouteCollection routes)

        {

            routes.IgnoreRoute(
      
      
        "
      
      
        {resource}.axd/{*pathInfo}
      
      
        "
      
      
        );



            
      
      
        //
      
      
        這是本身的默認路由,現(xiàn)在需要如果有id要限定它只能是數(shù)字,用正則表達式

            
      
      
        //
      
      
        routes.MapRoute(

            
      
      
        //
      
      
            "Default", 
      
      
        //
      
      
         Route name

            
      
      
        //
      
      
            "{controller}/{action}/{id}", 
      
      
        //
      
      
         URL with parameters

            
      
      
        //
      
      
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
      
      
        //
      
      
         Parameter defaults

            
      
      
        //
      
      
        );
      
      
        

            routes.MapRoute(

                
      
      
        "
      
      
        Default
      
      
        "
      
      , 
      
        //
      
      
         Route name
      
      
        "
      
      
        {controller}/{action}
      
      
        "
      
      , 
      
        //
      
      
         URL with parameters
      
      
        new
      
       { controller = 
      
        "
      
      
        Home
      
      
        "
      
      , action = 
      
        "
      
      
        Index
      
      
        "
      
       } 
      
        //
      
      
         Parameter defaults
      
      
                    );



            routes.MapRoute(

                
      
      
        "
      
      
        Default2
      
      
        "
      
      , 
      
        //
      
      
         Route name
      
      
        "
      
      
        {controller}/{action}/{id}
      
      
        "
      
      , 
      
        //
      
      
         URL with parameters
      
      
        new
      
       { controller = 
      
        "
      
      
        Home
      
      
        "
      
      , action = 
      
        "
      
      
        Index
      
      
        "
      
       }, 
      
        //
      
      
         Parameter defaults
      
      
        new
      
       { id=
      
        @"
      
      
        \d+
      
      
        "
      
      
        }

            );

        }
      
    

現(xiàn)在這個例子,希望路由在原來的默認路由的基礎上增加一個約束,就是如果url中輸入了id,那么希望將id的值約束在數(shù)字上,如果id輸入的是非數(shù)字的值,比如字母之類就不能匹配路由。

用正則表達式加約束條件,生成匿名對象new { id=@"\d+" },但是這個約束不能直接加在原來的默認路由上,原來的默認路由為:

      
                    routes.MapRoute(

                
      
      
        "
      
      
        Default
      
      
        "
      
      , 
      
        //
      
      
         Route name
      
      
        "
      
      
        {controller}/{action}/{id}
      
      
        "
      
      , 
      
        //
      
      
         URL with parameters
      
      
        new
      
       { controller = 
      
        "
      
      
        Home
      
      
        "
      
      , action = 
      
        "
      
      
        Index
      
      
        "
      
      , id = UrlParameter.Optional } 
      
        //
      
      
         Parameter defaults
      
      

            );
    

在這個默認路由中,定義了url模式里的變量有3個,分別是controller、action和id,并用new設置了這三個變量的默認參數(shù)值,其中id設置的是UrlParameter.Optional,設置為這個值,表示在匹配url時,id可以有也可以沒有,如果沒有id,那么就沒有id這個變量。如果希望有id的時候把它的值限定在數(shù)字上,不能直接在參數(shù)默認值的后面添加約束,比如:

      
                    routes.MapRoute(

                
      
      
        "
      
      
        Default
      
      
        "
      
      , 
      
        //
      
      
         Route name
      
      
        "
      
      
        {controller}/{action}/{id}
      
      
        "
      
      , 
      
        //
      
      
         URL with parameters
      
      
        new
      
       { controller = 
      
        "
      
      
        Home
      
      
        "
      
      , action = 
      
        "
      
      
        Index
      
      
        "
      
      , id = UrlParameter.Optional }, 
      
        //
      
      
         Parameter defaults
      
      
        new
      
       { id=
      
        @"
      
      
        \d+
      
      
        "
      
      
        }

            );
      
    

加上這個約束,就表示id必須要有值,而且要是數(shù)字,否則就不匹配。這樣一來,下面的url都不能再匹配了:

"~/"

"~/Home/Index"

"~/Home/TestInput"

也就是說id=UrlParameter.Optional就失去了意義。

解決方法就是把路由定義成兩個:

      
                routes.MapRoute(

                
      
      
        "
      
      
        Default
      
      
        "
      
      , 
      
        //
      
      
         Route name
      
      
        "
      
      
        {controller}/{action}
      
      
        "
      
      , 
      
        //
      
      
         URL with parameters
      
      
        new
      
       { controller = 
      
        "
      
      
        Home
      
      
        "
      
      , action = 
      
        "
      
      
        Index
      
      
        "
      
       } 
      
        //
      
      
         Parameter defaults
      
      
                    );



            routes.MapRoute(

                
      
      
        "
      
      
        Default2
      
      
        "
      
      , 
      
        //
      
      
         Route name
      
      
        "
      
      
        {controller}/{action}/{id}
      
      
        "
      
      , 
      
        //
      
      
         URL with parameters
      
      
        new
      
       { controller = 
      
        "
      
      
        Home
      
      
        "
      
      , action = 
      
        "
      
      
        Index
      
      
        "
      
       }, 
      
        //
      
      
         Parameter defaults
      
      
        new
      
       { id=
      
        @"
      
      
        \d+
      
      
        "
      
      }
      
);

按照順序依次匹配,沒有寫id的匹配第一個路由定義,寫了id的匹配第二個路由定義。

那么沒有寫id的時候,匹配第一個路由定義,就是{controller}/{action},就只有controller和action兩個變量,這個時候在動作方法中訪問RouteData.Values["id"]得到的結(jié)果就為null,但是這里的類型轉(zhuǎn)換用的是Convert.ToInt32(),當括號內(nèi)的對象為null時,得到的結(jié)果就為0。如果用的是int.Parse()遇到這種情況就會拋出異常。

int inputId = Convert.ToInt32(RouteData.Values["id"]);

當然,如果取到id的值,如果只想要字符類型,那就不用這么復雜, 可以直接用

string inputId = (string)RouteData.Values["id"];

?

對于本例,如果在url中輸入的是"~/Home/TestInput/325",那么顯示的結(jié)果為:

inputController=Home
inputAction=TestInput
inputId=325

?

(3)通過上下文對象訪問Request.QueryString的例子

Request.QueryString查詢字符串就是跟在url后面帶問號之后的內(nèi)容。例如:

http://localhost:1943/Home/TestInput2?var1=abc&var2=123

問號后面的var1=abc&var2=123就是QueryString。

?

例,假設跟上一個例題同樣的路由定義:

      
        public
      
      
        static
      
      
        void
      
      
         RegisterRoutes(RouteCollection routes)

        {

            routes.IgnoreRoute(
      
      
        "
      
      
        {resource}.axd/{*pathInfo}
      
      
        "
      
      
        );



            
      
      
        //
      
      
        這是本身的默認路由,現(xiàn)在需要如果有id要限定它只能是數(shù)字,用正則表達式

            
      
      
        //
      
      
        routes.MapRoute(

            
      
      
        //
      
      
            "Default", 
      
      
        //
      
      
         Route name

            
      
      
        //
      
      
            "{controller}/{action}/{id}", 
      
      
        //
      
      
         URL with parameters

            
      
      
        //
      
      
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
      
      
        //
      
      
         Parameter defaults

            
      
      
        //
      
      
        );
      
      
        

            routes.MapRoute(

                
      
      
        "
      
      
        Default
      
      
        "
      
      , 
      
        //
      
      
         Route name
      
      
        "
      
      
        {controller}/{action}
      
      
        "
      
      , 
      
        //
      
      
         URL with parameters
      
      
        new
      
       { controller = 
      
        "
      
      
        Home
      
      
        "
      
      , action = 
      
        "
      
      
        Index
      
      
        "
      
       } 
      
        //
      
      
         Parameter defaults
      
      
                    );



            routes.MapRoute(

                
      
      
        "
      
      
        Default2
      
      
        "
      
      , 
      
        //
      
      
         Route name
      
      
        "
      
      
        {controller}/{action}/{id}
      
      
        "
      
      , 
      
        //
      
      
         URL with parameters
      
      
        new
      
       { controller = 
      
        "
      
      
        Home
      
      
        "
      
      , action = 
      
        "
      
      
        Index
      
      
        "
      
       }, 
      
        //
      
      
         Parameter defaults
      
      
        new
      
       { id=
      
        @"
      
      
        \d+
      
      
        "
      
      
        }

            );

        }
      
    

?

在HomeController中新增了名為TestInput2的動作方法:

      
                public
      
      
        void
      
      
         TestInput2()

        {

            
      
      
        string
      
       inputController = (
      
        string
      
      )RouteData.Values[
      
        "
      
      
        controller
      
      
        "
      
      
        ];

            
      
      
        string
      
       inputAction = (
      
        string
      
      )RouteData.Values[
      
        "
      
      
        action
      
      
        "
      
      
        ];

            
      
      
        int
      
       inputId = Convert.ToInt32(RouteData.Values[
      
        "
      
      
        id
      
      
        "
      
      
        ]);

            
      
      
        string
      
       queryVar1 = Request.QueryString[
      
        "
      
      
        var1
      
      
        "
      
      
        ];

            
      
      
        string
      
       queryVar2 = Request.QueryString[
      
        "
      
      
        var2
      
      
        "
      
      
        ];

            Response.Write(
      
      
        string
      
      .Format(
      
        "
      
      
        inputController={0}<br>inputAction={1}<br>
      
      
        "
      
       + 

                
      
        "
      
      
        inputId={2}<br>queryVar1={3}<br>queryVar2={4}
      
      
        "
      
      
        ,

                inputController, inputAction, inputId, queryVar1, queryVar2));

        }
      
    

這里用了兩句話

string queryVar1 = Request.QueryString["var1"];
string queryVar2 = Request.QueryString["var2"];

來讀取查詢字符串中變量的值。

如果輸入的url是"~/Home/TestInput2?var1=abc&var2=123"則顯示的結(jié)果為:

inputController=Home
inputAction=TestInput2
inputId=0
queryVar1=abc
queryVar2=123

這個輸入的url,沒有匹配id,所以RouteData.Values["id"]為空,經(jīng)過Convert.ToInt32()轉(zhuǎn)換后值為0。QueryString里如果有多個變量,之間用符號&間隔。

?

擴充下這個例題,現(xiàn)在假設在/Views/Home/Index.cshtml,也就是HomeController中Index產(chǎn)生的視圖上添加:

@Html.ActionLink("Navigate", "TestInput2", new { id="123" })

這時,如果路由定義為:

      
                    routes.MapRoute(

                
      
      
        "
      
      
        Default
      
      
        "
      
      , 
      
        //
      
      
         Route name
      
      
        "
      
      
        {controller}/{action}/{id}
      
      
        "
      
      , 
      
        //
      
      
         URL with parameters
      
      
        new
      
       { controller = 
      
        "
      
      
        Home
      
      
        "
      
      , action = 
      
        "
      
      
        Index
      
      
        "
      
      , id = UrlParameter.Optional } 
      
        //
      
      
         Parameter defaults
      
      

            );
    

那么ActionLink產(chǎn)生的html為:

<a href="/Home/TestInput2/123">Navigate</a>

點擊該超鏈接后顯示的結(jié)果為:

inputController=Home
inputAction=TestInput2
inputId=123
queryVar1=
queryVar2=

?

但是,如果路由定義為:

      
                    routes.MapRoute(

                
      
      
        "
      
      
        Default
      
      
        "
      
      , 
      
        //
      
      
         Route name
      
      
        "
      
      
        {controller}/{action}
      
      
        "
      
      , 
      
        //
      
      
         URL with parameters
      
      
        new
      
       { controller = 
      
        "
      
      
        Home
      
      
        "
      
      , action = 
      
        "
      
      
        Index
      
      
        "
      
       } 
      
        //
      
      
         Parameter defaults
      
      
                    );



            routes.MapRoute(

                
      
      
        "
      
      
        Default2
      
      
        "
      
      , 
      
        //
      
      
         Route name
      
      
        "
      
      
        {controller}/{action}/{id}
      
      
        "
      
      , 
      
        //
      
      
         URL with parameters
      
      
        new
      
       { controller = 
      
        "
      
      
        Home
      
      
        "
      
      , action = 
      
        "
      
      
        Index
      
      
        "
      
       }, 
      
        //
      
      
         Parameter defaults
      
      
        new
      
       { id = 
      
        @"
      
      
        \d+
      
      
        "
      
      
         }

            );
      
    

那么@Html.ActionLink("Navigate", "TestInput2", new { id="123" })產(chǎn)生的html為:

<a href="/Home/TestInput2?id=123">Navigate</a>

這是因為按定義順序,會首先去匹配第一個路由定義,那么反推回url。第一個路由定義中沒有id,那就認為new { id="123" }產(chǎn)生的就是查詢字符串。點擊這個超鏈接后,產(chǎn)生的顯示結(jié)果為:

inputController=Home
inputAction=TestInput2
inputId=0
queryVar1=
queryVar2=

?

這樣一來,如果是第二種路由定義,既想生成的url中產(chǎn)生id,又有查詢字符串,那就需要使用:

@Html.ActionLink("Navigate", "TestInput2/123", new { var1="ABC", var2="325" })

產(chǎn)生的html為:

<a href="/Home/TestInput2/123?var1=ABC&amp;var2=325">Navigate</a>

注意html中的&amp;就是&,最后產(chǎn)生的url就是"~/Home/TestInput2/123?var1=ABC&var2=325"

點擊該超鏈接后,產(chǎn)生的顯示結(jié)果為:

inputController=Home
inputAction=TestInput2
inputId=123
queryVar1=ABC
queryVar2=325

?

(4)通過上下文對象訪問Request.Form中數(shù)據(jù)的例子

利用Request.Form可以讀取提交過來的表單中的數(shù)據(jù),通過Name的屬性值來進行識別訪問。下面構(gòu)造一個例子來說明用Request.Form來讀取表單數(shù)據(jù)的情況。

假設使用的路由定義為:

      
        public
      
      
        static
      
      
        void
      
      
         RegisterRoutes(RouteCollection routes)

        {

            routes.IgnoreRoute(
      
      
        "
      
      
        {resource}.axd/{*pathInfo}
      
      
        "
      
      
        );
      
      
        

            routes.MapRoute(

                
      
      
        "
      
      
        Default
      
      
        "
      
      , 
      
        //
      
      
         Route name
      
      
        "
      
      
        {controller}/{action}
      
      
        "
      
      , 
      
        //
      
      
         URL with parameters
      
      
        new
      
       { controller = 
      
        "
      
      
        Home
      
      
        "
      
      , action = 
      
        "
      
      
        Index
      
      
        "
      
       } 
      
        //
      
      
         Parameter defaults
      
      
                    );



            routes.MapRoute(

                
      
      
        "
      
      
        Default2
      
      
        "
      
      , 
      
        //
      
      
         Route name
      
      
        "
      
      
        {controller}/{action}/{id}
      
      
        "
      
      , 
      
        //
      
      
         URL with parameters
      
      
        new
      
       { controller = 
      
        "
      
      
        Home
      
      
        "
      
      , action = 
      
        "
      
      
        Index
      
      
        "
      
       }, 
      
        //
      
      
         Parameter defaults
      
      
        new
      
       { id = 
      
        @"
      
      
        \d+
      
      
        "
      
      
         }

            );

        }
      
    

在HomeController中添加了TestInput3()動作方法的兩個重載版本:

      
                [HttpGet]

        
      
      
        public
      
      
         ViewResult TestInput3()

        {

            
      
      
        return
      
      
         View();

        }



        [HttpPost]

        
      
      
        public
      
       ViewResult TestInput3(
      
        string
      
      
         dummy)

        {

            
      
      
        string
      
       inputController = (
      
        string
      
      )RouteData.Values[
      
        "
      
      
        controller
      
      
        "
      
      
        ];

            
      
      
        string
      
       inputAction = (
      
        string
      
      )RouteData.Values[
      
        "
      
      
        action
      
      
        "
      
      
        ];

            
      
      
        int
      
       inputId = Convert.ToInt32(RouteData.Values[
      
        "
      
      
        id
      
      
        "
      
      
        ]);

            
      
      
        string
      
       city = Request.Form[
      
        "
      
      
        City
      
      
        "
      
      
        ];

            DateTime forDate 
      
      = DateTime.Parse(Request.Form[
      
        "
      
      
        forDate
      
      
        "
      
      
        ]);

            ViewBag.inputController 
      
      =
      
         inputController;

            ViewBag.inputAction 
      
      =
      
         inputAction;

            ViewBag.inputId 
      
      =
      
         inputId;

            ViewBag.city 
      
      =
      
         city;

            ViewBag.forDate 
      
      =
      
         forDate;

            
      
      
        return
      
       View(
      
        "
      
      
        TI3Result
      
      
        "
      
      
        );

        }
      
    

這里用了兩個注解屬性[HttpGet]和[HttpPost]來指定一個TestInput3用于Get請求,另一個TestInput3動作方法用于Post請求。在本例中,希望在Post請求的TestInput3動作方法中利用上下文對象Request.Form來訪問表單數(shù)據(jù),本部需要指定參數(shù)。但是同名的兩個動作方法TestInput3看來是通過重載來實現(xiàn)的,如果名字相同,返回類型相同,參數(shù)又完全一致的話,程序就不能通過編譯。所以,為了演示這個例子,就在Post請求的動作方法TestInput3上加了一個啞元參數(shù)dummy,目的就是為了完成同名的TestInput3函數(shù)的重載。

接下來,在由Get請求TestInput3時,返回的視圖是默認視圖/Views/Home/TestInput3.cshtml,在里面構(gòu)造了表單:

      
        @{

    ViewBag.Title = "TestInput3";

}




      
      
        <
      
      
        h2
      
      
        >
      
      TestInput3
      
        </
      
      
        h2
      
      
        >
      
      
        

@using (Html.BeginForm())

{

    
      
      
        <
      
      
        p
      
      
        >
      
      city:
      
        <
      
      
        input 
      
      
        type
      
      
        ="text"
      
      
         name
      
      
        ="City"
      
      
        /></
      
      
        p
      
      
        >
      
      
        <
      
      
        p
      
      
        >
      
      forDate:
      
        <
      
      
        input 
      
      
        type
      
      
        ="text"
      
      
         name
      
      
        ="forDate"
      
      
        /></
      
      
        p
      
      
        >
      
      
        <
      
      
        input 
      
      
        type
      
      
        ="submit"
      
      
         value
      
      
        ="提交"
      
      
        />
      
      
           

}
      
    

表單由

@using (Html.BeginForm())

{

? ? ...

}

指定。里面有是三個元素,第一個是文本框,name為City,第二個也是文本框,name屬性為forDate。Request.Form就依賴這些元素的name來識別和訪問指定的元素值。第三個元素是按鈕,類型為submit,按鈕顯示的文字為“提交”。點擊該按鈕后,默認將表單Post到與產(chǎn)生當前視圖同名的動作方法上,本例子中,產(chǎn)生這個視圖的動作方法是TestInput3,那么Post回去的時候,也就是傳遞給同名的TestInput3動作方法。

在響應Post的TestInput3動作方法通過:

string city = Request.Form["City"];
DateTime forDate = DateTime.Parse(Request.Form["forDate"]);

讀取到表單中元素的值后,再利用ViewBag傳遞給顯示結(jié)果的視圖,該動作方法返回時指定了視圖名return View("TI3Result").

那么,就在/Views/Home/TI3Result.cshtml中產(chǎn)生輸出顯示的結(jié)果。添加視圖文件/Views/Home/TI3Result.cshtml如下:

      
        @{

    ViewBag.Title = "TI3Result";

}




      
      
        <
      
      
        h2
      
      
        >
      
      TI3Result
      
        </
      
      
        h2
      
      
        >
      
      
        <
      
      
        p
      
      
        >
      
      inputController=@ViewBag.inputController
      
        </
      
      
        p
      
      
        >
      
      
        <
      
      
        p
      
      
        >
      
      inputAction=@ViewBag.inputAction
      
        </
      
      
        p
      
      
        >
      
      
        <
      
      
        p
      
      
        >
      
      inpuId=@ViewBag.inputId
      
        </
      
      
        p
      
      
        >
      
      
        <
      
      
        p
      
      
        >
      
      city=@ViewBag.city
      
        </
      
      
        p
      
      
        >
      
      
        <
      
      
        p
      
      
        >
      
      forDate=@ViewBag.forDate
      
        </
      
      
        p
      
      
        >
      
    

執(zhí)行程序后,在url上輸入"~/Home/TestInput3,顯示為:

控制器介紹

?在文本框中輸入數(shù)據(jù)如下:

控制器介紹

點擊提交按鈕后,顯示結(jié)果為:

控制器介紹

?

2、為動作方法設定參數(shù)傳遞數(shù)據(jù)

上下文對象常用的Request.QueryString、Request.Form和RouteData.Values等數(shù)據(jù)也可以通過動作方法的參數(shù)來設定。這里有個約定,就是參數(shù)名跟要訪問的屬性名或元素名同名,系統(tǒng)是根據(jù)名字自動去匹配。

(1)先看一個常規(guī)的例子,假設路由定義為:

      
                public
      
      
        static
      
      
        void
      
      
         RegisterRoutes(RouteCollection routes)

        {

            routes.IgnoreRoute(
      
      
        "
      
      
        {resource}.axd/{*pathInfo}
      
      
        "
      
      
        );
      
      
                    routes.MapRoute(

                
      
      
        "
      
      
        Default
      
      
        "
      
      , 
      
        //
      
      
         Route name
      
      
        "
      
      
        {controller}/{action}/{id}
      
      
        "
      
      , 
      
        //
      
      
         URL with parameters
      
      
        new
      
       { controller = 
      
        "
      
      
        Home
      
      
        "
      
      , action = 
      
        "
      
      
        Index
      
      
        "
      
      , id = UrlParameter.Optional } 
      
        //
      
      
         Parameter defaults
      
      
                    );
      
      

        }
    

在HomeController中新加了名為TestInput4()的動作方法:

      
                public
      
      
        void
      
       TestInput4(
      
        int
      
      
         id)

        {

            Response.Write(
      
      
        string
      
      .Format(
      
        "
      
      
        id={0}
      
      
        "
      
      
        , id));

        }
      
    

在動作方法TestInput()上設定了參數(shù),整型的名為id的參數(shù)。動作方法的參數(shù)會用名字自動去匹配Request.QueryString、Request.Form和RouteData.Values中的屬性和元素的值,依賴的就是名字。

接下來,在/Views/Home/Index.cshtml中添加ActionLink來生成超鏈接,指向HomeController中的TestInput4()動作方法。添加的代碼為:

@Html.ActionLink("NavTestInput4", "TestInput4", new{ id=325 })

請注意ActionLink是怎么根據(jù)路由定義來生成html的。

第一個參數(shù)"NavTestInput4"是超鏈接文本,第二個參數(shù)是要訪問的動作方法名字。沒有給出控制器名字,則默認為產(chǎn)生當前視圖頁面的控制器,在本例子中就是Home控制器。第三個參數(shù)用new生成匿名對象,其中有id=325,根據(jù)路由定義,id匹配路由模式中的id變量。倒退回url,生成的超鏈接為:

      
        <
      
      
        a 
      
      
        href
      
      
        ="/Home/TestInput4/325"
      
      
        >
      
      NavTestInput4
      
        </
      
      
        a
      
      
        >
      
    

點擊該超鏈接后,根據(jù)路由定義,匹配路由模式"{controller}/{action}/{id}",訪問到Home控制器中的TestInput4動作方法,動作方法的參數(shù)id匹配路由模式中的{id},也就是RouteData.Values["id"]就通過匹配的動作方法參數(shù)id被傳遞到了動作方法中。而且可以看到,類型也自動匹配,參數(shù)中的int id,不需要做任何類型那個轉(zhuǎn)換。顯示結(jié)果為:

id=325

(2)跟上一個例題一樣的路由定義,現(xiàn)在將HomeController中的TestInput4修改為:

      
                public
      
      
        void
      
       TestInput4(
      
        int
      
       id, 
      
        string
      
      
         var1)

        {

            Response.Write(
      
      
        string
      
      .Format(
      
        "
      
      
        id={0}<br>var1={1}
      
      
        "
      
      
        , id, var1));

        }
      
    

也就是說TestInput4的參數(shù)可以去匹配Request.QueryString、Request.Form和RouteData.Values等數(shù)據(jù)中的id和var1的值。將/Views/Home/Index.cshtml中ActionLink修改為:

@Html.ActionLink("NavTestInput4", "TestInput4", new{ id=325, var1="ABC" })

根據(jù)路由定義,在ActionLink中的第三個參數(shù)new{ id=325, var1="ABC" },id匹配路由模式"{controller}/{action}/{id}"中的{id},而var1在路由模式中沒有變量叫這個名字,那就以問號?跟在url的最后面作為QueryString。本例子中的ActionLink產(chǎn)生的html為:

      
        <
      
      
        a 
      
      
        href
      
      
        ="/Home/TestInput4/325?var1=ABC"
      
      
        >
      
      NavTestInput4
      
        </
      
      
        a
      
      
        >
      
    

點擊該超鏈接后,訪問到Home控制器中的TestInput4動作方法。TestInput4動作方法中的參數(shù)id,接收RouteData.Values["id"]的值,參數(shù)var1接收Request.QueryString["var1"]的值。顯示的結(jié)果為:

id=325
var1=ABC

(3)注意路由變化,如果將路由定義改為:

      
        public
      
      
        static
      
      
        void
      
      
         RegisterRoutes(RouteCollection routes)

        {

            routes.IgnoreRoute(
      
      
        "
      
      
        {resource}.axd/{*pathInfo}
      
      
        "
      
      
        );
      
      
        

            routes.MapRoute(

                
      
      
        "
      
      
        Default
      
      
        "
      
      , 
      
        //
      
      
         Route name
      
      
        "
      
      
        {controller}/{action}
      
      
        "
      
      , 
      
        //
      
      
         URL with parameters
      
      
        new
      
       { controller = 
      
        "
      
      
        Home
      
      
        "
      
      , action = 
      
        "
      
      
        Index
      
      
        "
      
       } 
      
        //
      
      
         Parameter defaults
      
      
                    );



            routes.MapRoute(

                
      
      
        "
      
      
        Default2
      
      
        "
      
      , 
      
        //
      
      
         Route name
      
      
        "
      
      
        {controller}/{action}/{id}
      
      
        "
      
      , 
      
        //
      
      
         URL with parameters
      
      
        new
      
       { controller = 
      
        "
      
      
        Home
      
      
        "
      
      , action = 
      
        "
      
      
        Index
      
      
        "
      
       }, 
      
        //
      
      
         Parameter defaults
      
      
        new
      
       { id = 
      
        @"
      
      
        \d+
      
      
        "
      
      
         }

            );

        }
      
    

假設HomeController中的動作方法TestInput4()與第(1)個例子中一樣:

      
        public
      
      
        void
      
       TestInput4(
      
        int
      
      
         id)

        {

            Response.Write(
      
      
        string
      
      .Format(
      
        "
      
      
        id={0}
      
      
        "
      
      
        , id));

        }
      
    

在/Views/Home/Index.cshtml中的ActionLink也與第(1)個例子一樣,代碼為:

@Html.ActionLink("NavTestInput4", "TestInput4", new{ id=325 })

注意,由于路由的不同,這個例子中ActionLink生成html就與第(1)個例子不一樣了。根據(jù)本例子中的路由定義,按照順序,匹配第一個路由。在第一個路由中,路由的url模式為"{controller}/{action}",路由模式中沒有id變量。那么ActionLink的第三個參數(shù)new{ id=325 }中的id就沒有路由模式中的變量與其對應,就只能跟在問號后面,放在url的最后作為QueryString。所以,本例中生成的html為:

      
        <
      
      
        a 
      
      
        href
      
      
        ="/Home/TestInput4?id=325"
      
      
        >
      
      NavTestInput4
      
        </
      
      
        a
      
      
        >
      
    

需要注意的是,雖然產(chǎn)生的url不一樣,但是在訪問Home控制器里的TestInput4動作方法時,仍然可以讓TestInput4的參數(shù)id正確讀取到url中的id的值。這就是與前面直接通過上下文對象RouteData.Values["id"],或Request.QueryString["id"]來訪問id值不一樣的地方。動作方法TestInput4中的參數(shù)id,會自動去匹配Request.QueryString、Request.Form和RouteData.Values中與參數(shù)同名的數(shù)據(jù)。所以本例子中TestInput4的參數(shù)id,接收的是Request.QueryString["id"]的值,顯示的結(jié)果為:

id=325

RouteData.Values和Request.QueryString中如果都有與動作方法的參數(shù)相同的變量,優(yōu)先匹配的是RouteData.Values。例如,假設在Index.cshtml中的ActionLink代碼為:

      @Html.ActionLink(
      
        "
      
      
        NavTestInput4
      
      
        "
      
      , 
      
        "
      
      
        TestInput4/123
      
      
        "
      
      , 
      
        new
      
      { id=
      
        325
      
       })
    

路由匹配本例子中的第二個路由定義,路由模式為"{controller}/{action}/{id}",產(chǎn)生的html為:

      
        <
      
      
        a 
      
      
        href
      
      
        ="/Home/TestInput4/123?id=325"
      
      
        >
      
      NavTestInput4
      
        </
      
      
        a
      
      
        >
      
    

根據(jù)匹配的第二個路由,這里既有RouteData.Values["id"]值為123,又有Request.QueryString["id"]值為325,傳遞給Home控制器的動作方法TestInput4的時候,TestInput4的參數(shù)id優(yōu)先接收RouteData.Values["id"],顯示結(jié)果為:

id=123

(4)提交的表單,Request.Form中各元素的值也可以通過動作方法的參數(shù)傳遞。

例如,前面TestInput3的例子,其他不變,將HomeController中接收Post請求的TestInput3動作方法修改為:

      
                [HttpPost]

        
      
      
        public
      
       ViewResult TestInput3(
      
        string
      
       controller, 
      
        string
      
      
         action,

            
      
      
        string
      
       city, DateTime forDate, 
      
        int
      
       id = 
      
        0
      
      
        )

        {

            
      
      
        string
      
       inputController =
      
         controller;

            
      
      
        string
      
       inputAction =
      
         action;

            
      
      
        int
      
       inputId =
      
         id;
      
      
        

            

            ViewBag.inputController 
      
      =
      
         inputController;

            ViewBag.inputAction 
      
      =
      
         inputAction;

            ViewBag.inputId 
      
      =
      
         inputId;

            ViewBag.city 
      
      =
      
         city;

            ViewBag.forDate 
      
      =
      
         forDate;

            
      
      
        return
      
       View(
      
        "
      
      
        TI3Result
      
      
        "
      
      
        );

        }
      
    

效果跟上一個TestInput3的例子一樣。而且forDate的類型自動就給轉(zhuǎn)換為DateTime類型。

?

三、從控制器產(chǎn)生輸出

1、不要視圖,直接用Response.Write輸出

只要是派生于Controller的類里面的動作方法,就可以直接用Response.Write().

例如,前面的例子Index2()

      
        namespace
      
      
         _12_1ControllersAndActions.Controllers

{

    
      
      
        public
      
      
        class
      
      
         HomeController : Controller

    {
      
      
        public
      
      
        void
      
      
         Index2()

        {

            
      
      
        //
      
      
        訪問上下文對象的各個屬性
      
      
        string
      
       userName =
      
         User.Identity.Name;

            
      
      
        string
      
       serverName =
      
         Server.MachineName;

            
      
      
        string
      
       clientIP =
      
         Request.UserHostAddress;

            DateTime dateStamp 
      
      =
      
         HttpContext.Timestamp;

            Response.Write(
      
      
        string
      
      .Format(
      
        "
      
      
        userName:{0}<br>serverName:{1}<br>clientIP:{2}<br>dataStamp:{3}
      
      
        "
      
      
        , 

                userName, serverName, clientIP, dateStamp));

        }
      
      
        

    }

}
      
    

以及直接用Response.Redirect("/Some/Other/Url")也是屬于這一種。

例如,在HomeController中添加動作方法TestRe

      
        public
      
      
        void
      
      
         TestRe()

        {

            Response.Redirect(
      
      
        "
      
      
        /Home/Index
      
      
        "
      
      
        );

        }
      
    

執(zhí)行后,若輸入"~/Home/TestRe",則會自動轉(zhuǎn)移到"~/Home/Index"

?

2、理解Action Result

在動作方法中不直接使用Response對象,而是返回一個派生于ActionResult類的對象,它描述控制器要完成的操作,例如產(chǎn)生一個視圖、重定向到另一個url或動作方法等。

不同的操作用不同的派生類,它們都是ActionResult的派生類。例如,重定向:

      
        public
      
      
         ActionResult TestRe()

        {

            
      
      
        return
      
      
        new
      
       RedirectResult(
      
        "
      
      
        /Home/Index
      
      
        "
      
      
        );

        }
      
    

結(jié)果就返回RedirectResult的一個對象,因為RedirectResult派生于ActionResult,所以動作方法的返回類型可以用ActionResult,當然也可以明確使用RedirectResult作為該動作方法的返回類型。另外,各派生類也有一些控制器輔助器方法,可以簡化調(diào)用,例如RedirectResult類有輔助器方法Redirect

      
        public
      
      
         ActionResult TestRe()

        {

            
      
      
        return
      
       Redirect(
      
        "
      
      
        /Home/Index
      
      
        "
      
      
        );

        }
      
    

跟上面直接使用return new RedirectResult("/Home/Index");產(chǎn)生的效果是一樣的。

各個常用的派生類和用到的控制器輔助方法見p313。

?

3、從動作方法中產(chǎn)生視圖作為輸出

      
            public
      
      
        class
      
      
         HomeController : Controller

    {

        
      
      
        public
      
      
         ViewResult Index()

        {
      
      
        return
      
      
         View();

        }
        
}

產(chǎn)生視圖 /Views/Home/Index.cshtml

再如

      
        public
      
      
        class
      
      
         HomeController : Controller

    {

        
      
      
        public
      
      
         ViewResult Index()

        {

            
      
      
        return
      
       View(
      
        "
      
      
        HomePage
      
      
        "
      
      
        );

        }

    }
      
    

產(chǎn)生的視圖為 /Views/Home/HomePage.cshtml

return View("HomePage")參數(shù)里加上雙引號,表示給出指定的視圖名。就不是默認跟動作方法同名的視圖了。

另外,這里動作方法的返回類型用的是ViewResult,因為在知道方法返回的類型時,傾向于使用具體的類型,當然直接使用ActionResult也可以的。MVC框架在搜索視圖時,先搜索Areas再搜索Views。僅以cshtml為例,下面是搜索順序:

/Areas/<AreaName>/Views/<ControllerName>/視圖名.cshtml

/Areas/<AreaName>/Views/Shared/視圖名.cshtml

/Views/<ControllerName>/視圖名.cshtml

/Views/Shared/視圖名.cshtml

?

視圖文件在生成html時會用到/Views/Shared/_Layout.cshtml布局文件作為默認布局文件,如果要用另一個布局文件可以用?

      
        return
      
       View(
      
        "
      
      
        HomePage
      
      
        "
      
      , 
      
        "
      
      
        _OtherLayout);
      
    

?當然,先要保證這個布局文件在/Views/Shared/目錄中,也就是/Views/Shared/_OtherLayout.cshtml

?

四、把數(shù)據(jù)從動作方法傳遞給視圖

1、使用視圖模型對象

@model 類型

在HomeController中添加動作方法VMO(),如下:

      
        public
      
      
         ViewResult VMO()

        {

            DateTime date 
      
      =
      
         DateTime.Now;

            
      
      
        return
      
      
         View(date);

        }
      
    

注意,這里的return View(date);參數(shù)里的date沒有加雙引號,這表示要傳遞給視圖的數(shù)據(jù),而不是指定要渲染的視圖名,這里如果將date加上雙引號,含義就變了,就表示該動作方法要產(chǎn)生一個名為date.cshtml的視圖來進行顯示。

這里使用return View(date);就表示把對象date傳遞到與當前動作方法同名的視圖上,也就是/Views/Home/VMO.cshtml

      
        @model DateTime

@{

    ViewBag.Title 
      
      = 
      
        "
      
      
        VMO
      
      
        "
      
      
        ;

}




      
      <h2>VMO</h2>
      
        

the day 
      
      
        is
      
      :@Model.DayOfWeek
    

在開頭指定模型類型時,要用小寫的m,這里是@model DateTime。而在文中讀取模型值時,要用大寫的M,如這里的@Model.DayOfWeek.

剛才強調(diào),在動作方法中,返回View帶參數(shù)時,不要加雙引號,才表示返回的數(shù)據(jù)對象。如果要直接返回字符串對象,就需要在前面加上(object)指明這是模型對象。

      
        public
      
      
         ViewResult VMO()

        {

            DateTime date 
      
      =
      
         DateTime.Now;

            
      
      
        return
      
       View((
      
        object
      
      )
      
        "
      
      
        hello, world.
      
      
        "
      
      
        );

        }
      
    

在VMO.cshtml中,就使用string來指定模型類型。

      
        @model string

@{

    ViewBag.Title = "VMO";

}




      
      
        <
      
      
        h2
      
      
        >
      
      VMO
      
        </
      
      
        h2
      
      
        >
      
      
        

the day is:@Model
      
    

2、使用ViewBag傳遞數(shù)據(jù)

ViewBag允許你在這個動態(tài)對象上定義任意屬性,并在視圖中訪問它們 ,就相當于鍵/值對。

只是vs對它不提供智能感應支持。

?

3、執(zhí)行重定向

(1)重定向到字面url

假設在HomeController中有動作方法TestRe

      
        public
      
      
         RedirectResult TestRe()

        {

            
      
      
        return
      
       Redirect(
      
        "
      
      
        /Home/Index
      
      
        "
      
      
        );

        }
      
    

當訪問"~/Home/TestRe"時,就會重定向到"~/Home/Index"

(2)重定向到路由系統(tǒng)的url

在HomeController中,假設有前面例子中的動作方法TestInput2()

      
        public
      
      
        void
      
      
         TestInput2()

        {

            
      
      
        string
      
       inputController = (
      
        string
      
      )RouteData.Values[
      
        "
      
      
        controller
      
      
        "
      
      
        ];

            
      
      
        string
      
       inputAction = (
      
        string
      
      )RouteData.Values[
      
        "
      
      
        action
      
      
        "
      
      
        ];

            
      
      
        int
      
       inputId = Convert.ToInt32(RouteData.Values[
      
        "
      
      
        id
      
      
        "
      
      
        ]);

            
      
      
        string
      
       queryVar1 = Request.QueryString[
      
        "
      
      
        var1
      
      
        "
      
      
        ];

            
      
      
        string
      
       queryVar2 = Request.QueryString[
      
        "
      
      
        var2
      
      
        "
      
      
        ];

            Response.Write(
      
      
        string
      
      .Format(
      
        "
      
      
        inputController={0}<br>inputAction={1}<br>
      
      
        "
      
       + 

                
      
        "
      
      
        inputId={2}<br>queryVar1={3}<br>queryVar2={4}
      
      
        "
      
      
        ,

                inputController, inputAction, inputId, queryVar1, queryVar2));

        }
      
    

下面定義動作方法TestRe()來重定向到TestInput2()

      
        public
      
      
         RedirectToRouteResult TestRe()

        {

            
      
      
        return
      
       RedirectToRoute(
      
        new
      
      
        

            {

                Controller 
      
      = 
      
        "
      
      
        Home
      
      
        "
      
      
        ,

                Action 
      
      = 
      
        "
      
      
        TestInput2
      
      
        "
      
      
        ,

                id 
      
      = 
      
        "
      
      
        123
      
      
        "
      
      
        ,

                var1 
      
      = 
      
        "
      
      
        ABC
      
      
        "
      
      
        ,

                var2 
      
      = 
      
        "
      
      
        999
      
      
        "
      
      
        

            });

        }
      
    

執(zhí)行程序后,當輸入"~/Home/TestTe",將產(chǎn)生重定向。注意,產(chǎn)生的url取決于所使用的路由定義。如果路由定義為

      
                    routes.MapRoute(

                
      
      
        "
      
      
        Default
      
      
        "
      
      , 
      
        //
      
      
         Route name
      
      
        "
      
      
        {controller}/{action}/{id}
      
      
        "
      
      , 
      
        //
      
      
         URL with parameters
      
      
        new
      
       { controller = 
      
        "
      
      
        Home
      
      
        "
      
      , action = 
      
        "
      
      
        Index
      
      
        "
      
      , id = UrlParameter.Optional } 
      
        //
      
      
         Parameter defaults
      
      

            );
    

則重定向產(chǎn)生的url為

"~/Home/TestInput2/123?var1=ABC&var2=999"

但這個路由定義,如果沒有加以處理,在id處如果輸入的不是數(shù)字,那么將會拋出異常。

如果路由定義用的是下面的定義

      
                    routes.MapRoute(

                
      
      
        "
      
      
        Default
      
      
        "
      
      , 
      
        //
      
      
         Route name
      
      
        "
      
      
        {controller}/{action}
      
      
        "
      
      , 
      
        //
      
      
         URL with parameters
      
      
        new
      
       { controller = 
      
        "
      
      
        Home
      
      
        "
      
      , action = 
      
        "
      
      
        Index
      
      
        "
      
       } 
      
        //
      
      
         Parameter defaults
      
      
                    );



            routes.MapRoute(

                
      
      
        "
      
      
        Default2
      
      
        "
      
      , 
      
        //
      
      
         Route name
      
      
        "
      
      
        {controller}/{action}/{id}
      
      
        "
      
      , 
      
        //
      
      
         URL with parameters
      
      
        new
      
       { controller = 
      
        "
      
      
        Home
      
      
        "
      
      , action = 
      
        "
      
      
        Index
      
      
        "
      
       }, 
      
        //
      
      
         Parameter defaults
      
      
        new
      
       { id = 
      
        @"
      
      
        \d+
      
      
        "
      
      
         }

            );
      
    

那么產(chǎn)生的重定向url為

"~/Home/TestInput2?id=123&var1=ABC&var2=999"

(3)重定向到一個動作方法

      
        public
      
      
         RedirectToRouteResult TestRe()

{

    
      
      
        return
      
       RedirectToAction(
      
        "
      
      
        TestInput2
      
      
        "
      
      
        );

}
      
    

?

      
        public
      
      
         RedirectToRouteResult TestRe()

{

    
      
      
        return
      
       RedirectToAction(
      
        "
      
      
        TestInput2
      
      
        "
      
      , 
      
        new
      
       { id=
      
        "
      
      
        123
      
      
        "
      
      , var1=
      
        "
      
      
        ABC
      
      
        "
      
      , var2=
      
        "
      
      
        999
      
      
        "
      
      
        });

}
      
    

?

      
        public
      
      
         RedirectToRouteResult TestRe()

{

    
      
      
        return
      
       RedirectToAction(
      
        "
      
      
        TestInput2
      
      
        "
      
      , 
      
        "
      
      
        Home
      
      
        "
      
      
        );

}
      
    

?

      
        public
      
      
         RedirectToRouteResult TestRe()

{

  
      
      
        return
      
       RedirectToAction(
      
        "
      
      
        TestInput2
      
      
        "
      
      , 
      
        "
      
      
        Home
      
      
        "
      
      , 
      
        new
      
       { id=
      
        "
      
      
        123
      
      
        "
      
      , var1=
      
        "
      
      
        ABC
      
      
        "
      
      , var2=
      
        "
      
      
        999
      
      
        "
      
      
        });

}
      
    

?

?4、返回文件及二進制數(shù)據(jù)

(1)返回文件

文件下載

      
        public
      
      
         FileResult TestFile()

        {

            
      
      
        string
      
       fPath = AppDomain.CurrentDomain.BaseDirectory + 
      
        "
      
      
        DownloadTest/
      
      
        "
      
      
        ;

            
      
      
        //
      
      
        string fileName = @"c:\log.txt";
      
      
        string
      
       fileName = fPath + 
      
        "
      
      
        log.txt
      
      
        "
      
      
        ;

            
      
      
        string
      
       contentType = 
      
        "
      
      
        text/plain
      
      
        "
      
      
        ;

            
      
      
        string
      
       downloadName = 
      
        "
      
      
        Test.txt
      
      
        "
      
      
        ;

            
      
      
        return
      
      
         File(fileName, contentType, downloadName);     

        }
      
    

這里的AppDomain.CurrentDomain.BaseDirectory表示讀取到當前項目的根物理路徑,末尾帶反斜杠。要下載的文件log.txt放在根目錄下的DownloadTest文件夾中。在出現(xiàn)另存為對話框的時候,下載名被改為Test.txt。

(2)發(fā)送字節(jié)數(shù)組

      
        public
      
      
         FileContentResult TestFile()

        {

            
      
      
        byte
      
      [] data = ... 
      
        //
      
      
        二進制內(nèi)容
      
      
        return
      
       File(data, 
      
        "
      
      
        text/plain
      
      
        "
      
      , 
      
        "
      
      
        Test.txt
      
      
        "
      
      
        );

        }
      
    

(3)發(fā)送流內(nèi)容

如果所處理的數(shù)據(jù)可以通過一個打開的System.IO.Stream進行操作,可以把這個流傳遞給File方法的一個重載版本。這個流得內(nèi)容將被讀取并發(fā)送給瀏覽器。

      
        public
      
      
         FileStreamResult TestFile()

        {

            Stream stream 
      
      = ... 
      
        //
      
      
        打開某種流
      
      
        return
      
       File(stream, 
      
        "
      
      
        text/html
      
      
        "
      
      
        );

        }
      
    

5、返回錯誤及http錯誤代碼

(1)指定錯誤碼

      
        public
      
      
         HttpStatusCodeResult StatusCode()

        {

            
      
      
        return
      
      
        new
      
       HttpStatusCodeResult(
      
        404
      
      , 
      
        "
      
      
        url cannot be serviced.
      
      
        "
      
      
        );

        }
      
    

?

(2)發(fā)送404錯誤

      
        public
      
      
         HttpStatusCodeResult StatusCode()

        {

            
      
      
        return
      
      
         HttpNotFound();

        }
      
    

?

(3)發(fā)送401錯誤

      
        public
      
      
         HttpStatusCodeResult StatusCode()

        {

            
      
      
        return
      
      
        new
      
      
         HttpUnauthorizedResult();

        }
      
    

?

?

-lyj

控制器介紹


更多文章、技術交流、商務合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 波多野结衣一区在线观看 | 国产成人在线小视频 | 奇米奇米色 | 日韩爱爱 | 国产成人亚洲综合在线 | 国产1000部成人免费视频 | 欧美特级毛片a够爽 | 伊人色美文情网址 | 99精品国产自产在线观看 | 国产精品一久久香蕉产线看 | 欧美一级暴毛片 | 亚洲日本在线观看视频 | 久久国产精品自线拍免费 | 国产美女精品在线 | 99精品国产久热在线观看66 | 成人毛片在线观看 | 中文字幕日韩高清 | 97色在线观看 | 甜心女孩泰剧在线观看 | a级免费网站 | 99这里只有精品在线 | www中文字幕 | 亚洲欧洲成人 | 亚洲狠狠婷婷综合久久久久网站 | 国产主播福利在线 | 综合亚洲一区二区三区 | 久久久久久噜噜噜久久久精品 | 欧洲一级做a爱在线观看 | 一级毛片免费观看久 | 久久在线影院 | 青青草a | 亚洲午夜片子大全精品 | 男人的天堂免费在线观看 | 国产成社区在线视频观看 | 天天玩夜夜操 | 成年女人免费视频 | 99影视网| 久久青青草原精品国产麻豆 | 一本伊大人香蕉高清在线观看 | 欧美一级特黄乱妇高清视频 | 综合网天天操天天射 |