MVC 小结(转载)

来源:互联网 发布:360软件中心下载 编辑:程序博客网 时间:2024/05/16 09:54

因为是转载文章 在此标明出处,以前有文章是转的没标明的请谅解,因为有些已经无法找到出处,或者与其它原因。

如有冒犯请联系本人,或删除,或标明出处。

因为好的文章,以前只想收藏,但连接有时候会失效,所以现在碰到好的直接转到自己这里。

原文 出处http://www.cnblogs.com/xxxteam/archive/2013/04/07/3006256.html

 

 

用C#做网站,目前主要有两种模式:Asp.net网站,基于WebForm,和Mvc4 (mvc3、其他自定义框架就不谈了)。也就是做 xx.aspx页面,并且工具栏有一堆现成的.net服务器控件 和 html控件可用。浏览器直接访问 xx.aspx页面。

1.基于WebForm的:

  优点:1. 做小网站方便,现成控件直接拖动

           2. VS对aspx提供可视支持,可以像DW(DreamWare)那样看到代码的同时,能看到网页的样子。

  缺点:1.不容易实现代码与界面分离,因此程序员之间合作不变,程序与美工合作也不方便,因此不利于做大项目。

          2.面对定制的需求,不容易实现。因为现成的.net服务端控件,可定制性差。比如,客户说,这个按钮,要做成某个图案,甚至图案要能变化。这些要求,会超出.net服务端本身控件的能力范围,因此只能找别的解决方案。比如html控件,或flash控件等。

2.基于Mvc4 + Razor:优点和缺点刚好与WebForm相反。同事,Razor可以让html与程序的混编,变得非常优雅。最后,Mvc4提供一种类似于php框架的开发方式,也有利于php程序员的加入。

但是,最重要的是,Mvc4工程同时支持Razor 与 WebForm!所以,能用Mvc4,尽量用。当然,有一些第三方控件,最好在Mvc4环境下测一下。对于服务器环境,也做一个mvc4例子,测一下。

---------------------------------------------

正文:

1.创建一个项目

  1.1 文件 -> 菜单 -> 新建项目 -> 已安装 -> 模板 -> Visual C# -> Web -> ASP.NET MVC 4 Web 应用程序

  1.2 选择“空” (空MVC项目)

2.创建首页。注意,按照业界规范,首页的名字,默认应该为Index,但这里为了说明问题,一律不用规范名字。假设首页名字为 MvcMain。

   2.1 对 解决方案资源管理器 -> Controllers 单击鼠标右键,选择 添加 -> 控制器

   2.2 控制器名称填“MvcMainController”。注意,这里有一个格式规范问题。控制器名称,一律严格按照 “网页URL节点名称 + Controller”方式来命名。

          比如 http://www.baidu.com/Node1/Node2,这里,Node1与Node2,就是网页URL节点名称。如果访问入口为:http://www.baidu.com/ABC/ ,则网页URL节点名称为ABC,因此控制器的名称为“ABCController”。

   2.3 该页面其他栏目不填,点“添加”。

         此时出现:

复制代码
 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6  7 namespace Mvc4Test2.Controllers 8 { 9     public class MvcMainController : Controller10     {11         //12         // GET: /MvcMain/13 14         public ActionResult Index()15         {16             return View();17         }18 19     }20 }
复制代码

      2.4 说明:

            2.4.1 Controller是URL的入口。如果这个项目被部署到 http://www.mvc.com/,则上面创建的这个控制器的URL为 http://www.mvc.com/MvcMain 。

            2.4.2 当浏览器访问 http://www.mvc.com/MvcMain 时,读取的是 public ActionResult Index() 这个方法。

            2.4.3 你可以添加一个方法:About() 与 MailMe(),这个控制器代码就变成了这个样子:

复制代码
 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.Mvc; 6  7 namespace Mvc4Test2.Controllers 8 { 9     public class MvcMainController : Controller10     {11         //12         // GET: /MvcMain/13 14         public ActionResult Index()15         {16             return View();17         }18 19         public ActionResult About()20         {21             return View();22         }23 24         public ActionResult MailMe()25         {26             return View();27         }28     }29 }
复制代码

            2.4.4 此时,About的入口URL为 http://www.mvc.com/MvcMain/About/ ,MailMe的入口URL为:http://www.mvc.com/MvcMain/MailMe/ ,当浏览器访问这个URL时,实际上是上面这个控制器,执行相应的方法。

            2.4.5 既然执行的是方法,那就可以加参数。对于参数,刚好是 GET 格式:http://..../NodeName/?ValueName1=Value2&ValueName2=Value2,这个表达式拆开:

                     http://..../NodeName/  +  ?   +   ValueName1=Value2   +   &   +  ValueName2=Value2

                    意思是,访问http://..../NodeName/,并且给入两个参数,第一个参数名字为ValueName1,值为Value2;第二个参数名字为ValueName2,值为Value2。

                    为了快速说明问题,把控制器的 Index方法修改为:

1 public string Index(string arg_strValue, int arg_intValue = 2)2 {3     return "MvcMain Index:arg_strValue = [" + arg_strValue + "], arg_intValue = [" + arg_intValue.ToString() + "]";4 }

                   然后按F5调试。此时,打开的应该是:http://localhost:随机端口号/ ,并且是一个错误页面。不慌,在这个URL后面添加“MvcMain/”,整个URL变成:http://localhost:3343/MvcMain/ ,就可以看到效果了。此时,参数还未赋值,使用的是默认值。注意,你应该观察到,参数为默认值的情况下,string为null,mvc没报错,说明它允许null的string作为参数值。但int就不行。如果把Index方法 public string Index(string arg_strValue,int arg_intValue = 2)
  改为 public string Index(string arg_strValue,int arg_intValue) ,不给入参数,则会报错。
                   现在,测试一下给入参数:  http://localhost:3343/MvcMain/?arg_strValue=1235&arg_intValue=999 ,看到效果没?

                     2.4.6 把Index方法恢复为:

1 public ActionResult Index()2 {3     return View();4 }

3.为控制器添加网页内容。由于控制器只是一个入口,因此需要添加网页内容View。

    3.1 对 解决方案资源管理器 -> Views 单击鼠标右键,选择  添加 -> 新建文件夹,这个文件夹名字,要与控制器的名字相对应。上文建立的控制器名字为 MvcMainController,它的名字就是MvcMain。所以,这个文件夹的名字也应该是MvcMain。如果你建立了一个控制器,名字是ABCController,则这个新建文件夹的名字应该为ABC。

    3.2 对这个 MvcMain 文件夹,单机鼠标右键,选择 添加 -> 新建项 -> MVC 4 视图页(Razor),下方的“名称(N):”填Index.cshtml。首先,为什么名字是Index?因为Index刚好对应控制器MvcMainController的Index方法。这个是一一对应关系。你可以为控制器的About方法和MailMe方法,建立 About.cshtml 和 MailMe.cshtml 的视图页。其次,为什么后缀为 .cshtml ?这是微软规定的。

    3.3 创建好Index.cshtml后,内容设置为:

复制代码
 1 @{ 2     Layout = null; 3 } 4  5 <!DOCTYPE html> 6  7 <html> 8 <head> 9     <meta name="viewport" content="width=device-width" />10     <title></title>11 </head>12 <body>13     <div>14     这就是传说中的视图页。浏览器先通过URL访问控制器,然后控制器执行里面的Index方法,最后Index方法再执行与控制器同名的MvcMain文件夹内的,与控制器的Index方法同名的Index.cshtml.15     </div>16 </body>17 </html>
复制代码

    3.4 F5执行。URL还是填 http://localhost:随机端口号/MvcMain/ ,看到效果了吧。

    3.5 现在,在MvcMain文件夹下,按刚才步骤,创建About.cshtml 和 MailMe.cshtml。内容随便写。然后F5调试,访问 http://localhost:随机端口号/MvcMain/About/ 和 http://localhost:随机端口号/MvcMain/MailMe/ ,看到效果了吧?

4.最后一步,让这个控制器成为首页。刚才F5调试时,打开的是 http://localhost:随机端口号/ ,这个本来应该是首页,但出现的是一个错误页面。必须通过http://localhost:随机端口号/MvcMain/ 才能打开这个页面。现在,我们希望让http://localhost:随机端口号/ 直接跳转到这个页面。

    4.1 解决方案资源管理器 -> 工程 -> 展开App_Start文件夹 -> 鼠标左键双击 RouteConfig.cs

    4.2 在这个文件里,找到 controller = "Home", action = "Index"。把Home改成MvcMain就可以了。如果你有一个叫 ABCController的控制器,你也可以把 Home 改为 ABC。

    4.3 后面有一个action = "Index",你也可以把Index改为About或MailMe。

    4.4 现在F5试试, http://localhost:随机端口号/  这个URL,现在不是错误页面了吧?而是MvcMain的界面吧。

----------------------------------------------------------------------------------

开发说明:

1.Razor搞出了一堆名堂,什么母版页、布局页、分部页等完全没有存在的必要,把简单问题搞复杂了。Razor比aspx搞定了include和混编,这就足够了。 内容页(视图页) + include + Razor风格混编,已经搞定所有事情,PHP就是这么做的。

2.事实上,大家可以发现,Razor的母版页、布局页和分部页等,最后生成的都是cshtml后缀,说明他们是同一种东西。aspx至少还把内容页aspx和母版页Master用后缀给区分开了。

3.因此,只要掌握了Razor的@单语句,@{ 多语句 } 以及include指令(@RenderPage( page path ) )就可以了。什么模板啊,布局啊,自己就用命名 + 路径来区分开。

4.以上三点只是让大家清楚,这些概念并不是需要一定使用的。但是,VS搞出这些,规范了命名风格,所以,尽量使用它们来遵守这个命名约定,对于规范化开发还是有好处的。此点与上面3点矛盾。总的来说,微软把这些东西弄复杂,但却给出了命名规范。因此大家没必要特意去墨守成规这些概念,能用尽量用,以提高命名规范性,如果有自己的命名规范,不用也行。

----------------------------------------------------------------------------------

后续资料:(以下代码全部为简写)

1.Razor的控制器与视图传值

http://msdn.microsoft.com/zh-cn/library/dd394711(v=vs.100).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1

2.Razor利用Model,进行更方便的传值:

  2.1 建立一个Model,为Info:

       class Info

       {

            InfoID : int;

            InfoName : string;

       }

  2.2 控制器传给视图:

        2.2.1 控制器Controller:(参数Arg_info的作用,在后面给出)

复制代码
1         public ActionResult Index(Info arg_info)2         {3             Info newInfo = new Info();4             newInfo.InfoID = 2;5             newInfo.InfoName = "newInfo : 2";6             return View(newInfo);7         }
复制代码

    

          2.2.2 视图View:

复制代码
 1 @model MvcTest.Models.Info 2  3 @{ 4     Layout = null; 5 } 6  7 <!DOCTYPE html> 8  9 <html>10 <head>11     <meta name="viewport" content="width=device-width" />12     <title></title>13 </head>14 <body>15     <div>16         <form method="post" action="~/MvcMain/Index_ReceiveData1">17             <p>18                 <input type="text" name="InfoID" id="InfoID" value="@Model.InfoID" />19             </p>20 21             <p>22                 <textarea name="InfoName" id="InfoName" cols="45" rows="5">@Model.InfoName</textarea>23             </p>24 25             <p>26                 <input type="submit" name="WebUI_Name_Form_Btn_Submit" id="WebUI_ID_Form_Btn_Submit" value="提交 Form" />27             </p>28         </form>29     </div>30 </body>31 </html>
复制代码

        发现没,html控件的ID和Name,与Info类的属性的名字是一样的。这种高耦合,实现了方便性。WCF也是因为这种耦合,才让开发变得更方便。当然,耦合带来的缺点,我们也应该重视。


    2.3 视图View传回给控制器

复制代码
 1 [HttpPost] 2 public ActionResult Index_ReceiveData1(Info arg_info) 3 { 4     if (ModelState.IsValid) 5     { 6         int id = arg_info.InfoID; 7         int name = arg_info.InfoName; 8     } 9     else10     {11          throw new Excetion(.....);12      }13     return RedirectToAction("Index", arg_info);//把这个东东传回index,当然,不传回,做别的事情也可以。如果传回,则控制器的这个方法就不需要些View视图了。14 15 }
复制代码

-------------------------------------------------------------------------------------------------------

路径问题

    对于一个网站,令人讨厌的就是路径问题。由于MVC4的路由比较特殊,因此,网页与外码之外的所有资源文件,不要放在Controller、Models以及Views这几个特殊目录下。自己在工程目录下,另建一个Resource文件夹。Resource文件夹应该与Controller、Models以及Views目录为同一级。然后,可以把Resource里的结构,设置为与Views内部结构一致。

  比如:主页:

  ~/Views/Main/Index.cshtml

  主页的相关资源,最好是放在

  ~/Resource/Main/下面

  实例:

  工程 / Views / Main / LayoutPage_Index.cshtml 母版页

  工程 / Views / Main / Index.cshtml 主页的内容页

  然后,在 LayoutPage_Index.cshtml 里,使用 @RenderPage("~/Views/Main/Index.cshtml"); 来渲染 Index.cshtml 内容。

-------------------------------------------------------------------------------------------------------

Razor + C#混编问题

  1.在PHP中,在xx.php里,把一个php的字符串,输出为html的方法是:echo 'PHPStr'; 或 $phpStr = "PHPStr"; echo $phpStr;

     在Razor里,

    1.1 单行

        1.1.1 输出一个C# string变量(假设 string cSharpStr = "123"):@cSharpStr 这样就可以了

        1.1.2 输出一个C# 字符串:@("CSharpString") ,注意这个字符串外面要加括号。

   1.2 多行

        1.2.1 输出一个C# string变量:

                @{

                      string str = "123";

                     @str;//这样就在这个位置输出123了

                }

        1.2.2 输出一个C#字符串:

               同上,也是:

              @{

                   @("123");

                }

        1.2.3 直接嵌入HTML代码:

                @{

                        <div>

                           @("输出内容");

                       </div>

                   }

      对于html新手来说,需要注意的是,如果要输出的是用户输入的文本,并且用户会输入比如"<script>"这些会引起浏览器执行的代码,那在输出时就需要做html的Encode处理了(或Url的Encode处理)。

-------------------------------------------------------------------------------------------------------

要注意的坑爹问题 (虽然微软的东西用起来很方便,但基本上它的产品都有一些坑爹的小问题)

1. 混编时,Razor指令,一定要在前面加 "@",即使是在@的代码段里。

    比如:单独在Html代码里使用:

1 <p> @RenderPage("~/Views/Main/Index_Login_NotLogin.cshtml")</p>

    接着,在代码段里使用:

复制代码
1 <p>2  @{3     //这里就是Razor代码段4    int a = 0;5     //使用Razor的RenderPage指令,依然要在前面加@,否则不起作用6     @RenderPage("~/Views/Main/Index_Login_NotLogin.cshtml");7 }8 </p>
复制代码

    Razor的指令有一堆,RenderXXX,Html.XXX,Url.XXX,等等...

3.Razor的自动推断功能有各种Bug,导致开发者不得不每次写稍微复杂的内容,都需要用 “@” + “大括号”的方式来使用。

4.在Razor开发环境下,不会有自动引用功能,因此需要手动using,或写明class的绝对路径。比如,如果XX是System.Object.XX,则需要手动写全System.Object.XX。

5.在Razor开发环境下,以下IDE功能变得残缺:

    5.1 自动完成

    5.2 自动提示

    5.3 自动格式化(自动格式化的对齐功能总是出问题)

6.如果Razor里的代码有错误,不会提示,也无法访问,也无法调试。只能通过在浏览器的地址栏,输入该View的绝对URL后(View对应的Controller的方法名字),才能看到报错页面,而且也无法调试。

 

原创粉丝点击