• VS2012_MVC4入门例子、代码视图分离办法、需要注意的坑爹问题等_被坑后不断更新此贴,要转载的话,请使用链接,不要转载内容


    因为此贴会不断更新,所以,要转载的话,请使用链接,不要转载内容。

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

    题外话:

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

    1.基于WebForm的:

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

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

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

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

    2.基于Mvc4 + Razor:

        缺点:1.可以混编的Razor页面,做小网站不方便,没有能直接拖动的控件(Mvc4里不仅仅可以创建Razor页面,也可以继续使用WebForm页面,这样就可以拖控件)。

                2.VS对Razor页面不提供可是支持,因此你只能写代码,没办法马上就看到网页的样子。比如运行后,才能看到网页的最终效果。

        优点:1.非常容易实现代码与界面分离,因为MVC4就是干这个事情的。因此利于大家合作,利于做大型BS项目。 

                2.Razor可以让html与程序的混编,变得非常优雅,就像PHP一样,可以直接在xx.php里混入程序代码与html/css/js代码。最后,Mvc4提供一种类似于php框架的开发方式,也有利于php程序员的加入。

                3.最重要的是,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 : Controller
    10     {
    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 : Controller
    10     {
    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     else
    10     {
    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的方法名字),才能看到报错页面,而且也无法调试。

  • 相关阅读:
    Linux系统管理之进程管理
    Linux交换空间swap讲解
    Linux物理存储结构以及磁盘划分
    Linux 文件系统挂载mount命令
    Linux文件系统df、du、fsck命令讲解
    Linux yum源配置以及yum命令讲解
    Linux rpm查询命令以及RPM包验证
    02Python常用模块_01math
    00_python常见用法笔记
    02_python闯关练习_02Max&Min
  • 原文地址:https://www.cnblogs.com/xxxteam/p/3006256.html
Copyright © 2020-2023  润新知