ASP.NET MVC添加新控制器示例
ASP.NET MVC高效构建Web应用- 商品搜索 - 京东
控制器(Controllers)是一个协调视图和模型直接关系的特殊类。它响应用户输入,与模型进行对话,并决定呈现哪个视图(如果有的话)。在ASP.NET MVC中,这个类文件通常以后缀名Controller表示。让我们从新建一个控制器类开始动手。
3.2.1 新建项目添加控制器源文件
我们首先将新建一个MVC项目,后续内容就基于此项目逐渐新增内容展开讲解。
【例3.1】添加一个新控制器
(1)打开VS,新建一个基于MVC的ASP.NET项目,项目名称是test。
(2)我们从创建控制器类开始。在解决方案资源管理器中,右键单击 Controllers文件夹,然后单击“添加”,再单击“控制器”,此时出现“添加已搭建基架的新项”,在该对话框上,我们单击“MVC 5 控制器- 空”,如图3-2所示。
图3‑2
然后单击“添加”。将新控制器命名为“HelloWorldController”,如图3-3所示。
图3‑3
然后单击“添加”。此时,解决方案资源管理器将创建名为HelloWorldController.cs的新文件和一个新文件夹Views\HelloWorld,位置如图3-4所示。
图3‑4
(3)在控制器中准备添加代码。我们在解决方案资源管理器中双击打开控制器源文件HelloWorldController.cs,然后删除类HelloWorldController下的Index函数,并添加两个新函数,代码如下:
public class HelloWorldController : Controller{// 访问方式:/HelloWorldpublic string Index() {return "This is my <b>default</b> action..."; //该字符串显示在网页上,<b>是粗体的意思}// 访问方式:/HelloWorld/Welcome/public string Welcome(){return "This is the Welcome action method..."; //该字符串显示在网页上}}
我们新增的控制器名称是HelloWorldController,第一个方法是Index,当我们访问控制器(http://localhost:xxxx/HelloWorld)时候,将默认调用这个Index方法,此时它返回一个字符串,因此在网页浏览器中能看到这个字符串。另外一个方法是Welcome,当我们在浏览器中访问URL地址“http://localhost:xxxx/HelloWorld/Welcome”时,将调用该方法,该方法也是返回一个字符串,因此我们可以在浏览器中看到这个字符串。
(4)按ctrl+F5运行项目,然后在弹出的浏览器的地址栏中输入“https://localhost:44308/HelloWorld”,此时就可以在页面上看到方法Index中返回的字符串了,如图3-5所示。
访问https://localhost:44308/HelloWorld相当于访问https://localhost:44308/HelloWorld/index,index可以省略不写。可以看出,网页上显示的字符串正是Index方法中返回的字符串,而且返回的字符串中带有的html标记<b></b>也起作用了,它的作用就是让<b>和</b>之间的字符变粗体。接着,我们再在浏览器地址栏中输入“https://localhost:44308/HelloWorld/Welcome”,此时将调用HelloWorldController控制器中的Welcome方法,该方法也是返回一个字符串,因此网页上也能看到一个字符串,如图3-6所示。
可见结果正确。另外,在ASP.NET MVC中,默认情况下,路由解析是不区分大小写的,因此我们在地址栏中把“HelloWorld/Welcome”全部写成小写,也是可以正常显示网页。如果需要让MVC的路由匹配变得大小写敏感,你可以通过在RouteConfig.cs中定义路由的时候使用正则表达式来实现,但通常没有必要。
现在我们理解了,ASP.NET MVC 根据传入 URL 调用不同的控制器类,并调用不同的操作方法(比如我们例子中的Index方法和Welcome方法)。
3.2.2 基于路由为方法增加一个参数
至此,我们并没有传递参数给Welcome方法,实际开发中,通常会在URL中传递一些数据给内部方法,那我们要传数据给方法,URL如何写呢?可以这样写:
/[Controller]/[ActionName]/[Parameters]
Controller表示控制器名称,ActionName表示方法名称,Parameters表示要传给方法的参数,比如http://localhost:xxx/HelloWorld/Welcome/1,这个1就是可以传给Welcome方法的参数。那为何可以这样写呢?这个url格式在哪里指定呢?我们可以打开App_Start/RouteConfig.cs文件查看路由格式,该函数如下:
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 });}
原来是在这个自动生成的函数中规定了这样的url格式,而且参数的名称也规定了,即id。那么我们在方法中也要定义一个名称为id的参数,然后就可以得到URL中的参数值了。
我们看url那一行,{id}处在参数的位置上,表示要传给方法action的参数,我们只需要在。defaults表示如果URL中不写具体的方法名称,那么默认访问的方法就是Home控制器中Index,而且参数是可选的(UrlParameter.Optional),也就是可以没有,这样我们运行应用程序但不提供任何 URL 段时,它默认为在上述代码的defaults 节中指定的Home控制器和Index操作方法。注意:Home控制器是新建项目就默认生成的,我们手动添加的控制器是HelloWorld。
了解了格式后,我们趁热打铁,赶紧在Welcome方法中添加一个参数,代码如下:
public string Welcome(int id){return HttpUtility.HtmlEncode("data from url:"+ id);}
我们要把参数id在网页上显示出来。HttpUtility.HtmlEncode用于将字符串转换为HTML编码格式的字符串,目的是为了保护应用程序免受恶意输入(因为我们的程序通过URL接收输入参数,所以要做好一定的防护),因此我们需要通过对字符串应用HTML 编码以防在Web应用程序中受到脚本攻击。
运行项目,然后在浏览器的地址栏中输入URL:https://localhost:44308/HelloWorld/Welcome/100,回车后,网页就出现了“data from url:100”,如图3-7所示。
图3-7
可以看到,参数100传给了Welcome方法,然后在网页上显示出来,有兴趣的朋友还可以改100为其他数字,都可以正确显示出来。值得注意,Welcome方法中的参数名id必须和RegisterRoutes方法中{id}一致,如果Welcome方法中的参数名不是id,那就会出错了。但如果Welcome方法中写成了大写ID,那是没事的,结果照样正确,说明此方法对大小写不敏感。
有朋友可能会执拗,就偏要在Welcome方法中用其他参数名称,咋办?很简单,在RegisterRoutes方法中,把{id}改为你想要的名称,比如我们改为{age},那么我们在Welcome方法中就可以用age作为参数名了,我们马上试试。修改RegisterRoutes方法如下:
public static void RegisterRoutes(RouteCollection routes){ routes.IgnoreRoute("{resource}.axd/{*pathInfo}");//把两处id改为ageroutes.MapRoute(name: "Default",url: "{controller}/{action}/{age}", defaults: new { controller = "Home", action = "Index", age = UrlParameter.Optional });}
然后再修改Welcome方法如下:
public string Welcome(int age){return HttpUtility.HtmlEncode("data from url:"+ age);}
也就是把参数名改为了age,返回的字符串也用了age。
马上运行项目,输入URL:https://localhost:44308/HelloWorld/Welcome/66,运行结果如图3-8所示。
图3‑8
运行正确,现在我们知道如何使用自己想用的参数名了,原来需要在注册路由方法RegisterRoutes中修改一下。
3.2.3 基于路由为方法增加多个参数
刚刚我们把URL上的参数传递给了方法Welcome,但我们只是传递了一个参数,现在我们来传递多个参数。首先我们要在路由配置文件RouteConfig.cs中添加一个新路由,添加代码如下:
routes.MapRoute(name: "abc",url: "{controller}/{action}/{name}/{height}/{age}");
这里的路由名称name随便取,比如abc;最关键的是url,这里我们在{action}后面添加了3个参数,分别是name、height和age,它们将传入方法Welcome中,因此接下来我们要为Welcome方法添加参数,打开HelloWorldController.cs,修改Welcome方法如下所示:
public string Welcome(string name,float height, int age = 10){return HttpUtility.HtmlEncode("Hello " + name + ", your height:"+height+" and age:"+age);}
马上运行项目,输入URL:https://localhost:44308/HelloWorld/Welcome/Tom/1.81/20,运行结果如图3-9所示。
图3-9
运行正确,我们把3个参数值都显示出来了。现在,我们知道如何传多个参数给方法了。
在路由配置文件RouteConfig.cs中,拥有2个条路由,一条是名为Default的路径,另外一条是名为abc的路径。我们可以按两种url来访问,但前提是要定义好和url参数对应的方法。比如现在按照Default中的url(url: "{controller}/{action}/{age}")方式来访问就出错了,输入URL:https://localhost:44308/helloWorld/Welcome/22,运行结果如图3-10所示。
这是因为Welcome需要3个参数呢,而我们在URL中就给了一个参数,所以报错了。我们可以在HelloWorldController类中增加一个方法,使其拥有一个参数,代码如下:
public string howold(int age){return HttpUtility.HtmlEncode("age:" + age);}
然后运行项目,输入URL:https://localhost:44308/helloWorld/howold/22,运行结果如图3-11所示。
运行正确。现在我们既可以输入1个参数,也可以输入3个参数给不同的方法了,两种URL路径都能使用到。
3.2.4 不改变路由为方法增加多个参数
刚刚我们为了传递多个参数给方法,还特意添加了一条新路由,略显繁琐,其实也可以不新增路由来传递多个参数的。方法是通过查询字符串。现在我们基于已经存在的路由Default,来为Welcome方法添加多个参数,目前Default路由是这样的:
routes.MapRoute(name: "Default",url: "{controller}/{action}/{age}",defaults: new { controller = "Home", action = "Index", age = UrlParameter.Optional });
age已经是一个参数了,它所需要的URL如下:
http://localhost:xxx/HelloWorld/Welcome/20
现在,我们可以在1后面加问号(?),然后再加查询字符串,比如:
http://localhost:xxx/HelloWorld/Welcome/20?name=Tom&height=1.81
“name=Tom&height=1.81”就是查询字符串,name和height是参数名,必须和Welcome方法中的参数名相同,Tom和1.81是参数值,也就是传给Welcome方法的实参。而Welcome方法目前的代码是这样的:
public string Welcome(string name,float height, int age = 10){return HttpUtility.HtmlEncode("Hello " + name + ", your height:"+height+" and age:"+age);}
正好3个参数,name和height对应查询字符串中name和height,age对应Default路径中url规定的age。运行项目,输入URL:https://localhost:44308/helloWorld/Welcome/20?name=Alice&height=1.68,运行结果如图3-12所示。
图3-12
运行正确。通过查询字符串的方式,我们即使不新增路由,也可以给方法传递多个参数值。不信的话,可以把路由abc删除,结果依然正确。但要注意,查询字符串会在URL中暴露参数名称。
这个实例写到这里该结束了,否则太长了。在整个实例中,控制器一直在执行 MVC的VC部分,即视图和控制器的工作。控制器将直接返回 HTML。通常,人们不希望控制器直接返回 HTML,因为这会使代码变得非常繁琐。相反,我们通常使用单独的视图模板文件来帮助生成HTML响应,后续我们将实现这个效果。