2009-07-23 24 views
2

这个问题可能听起来很奇怪,但我发现它真的难以消化ASP.NET MVC应用程序中的典型aspx页面。例如:ASP.NET MVC应用程序的aspx文件中的代码如何执行?

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %> 

<asp:Content ID="aboutTitle" ContentPlaceHolderID="TitleContent" runat="server"> 
    About Us 
</asp:Content> 

<asp:Content ID="aboutContent" ContentPlaceHolderID="MainContent" runat="server"> 
    <h2>About</h2> 
    <p> 
<% var cookie = Request.Cookies["mvcData"]; 
    string lastRefreshValue = cookie == null? "Unknown": cookie["lastRefresh"]; 
%> 
<%= Html.Encode ("Last Refreshed: " + lastRefreshValue) %> 
<% var newCookie = new HttpCookie ("mvcData"); 
    newCookie["lastRefresh"] = DateTime.Now.ToString(); 
    newCookie.Expires = DateTime.Now.AddSeconds (10); 
    Response.Cookies.Add (newCookie); 
%> 

     <%= Html.Encode (ViewState["hello"] ?? "") %> 
    </p> 
</asp:Content> 

写在<%的代码...%>运作良好,并预期,但我怎么能在一个类可视化代码?当然,它是从ViewPage继承而来的,它是一个类,所以无论代码写在<%..%>是否从某种方法执行。对?

编辑:编写在<%..%>中的代码是不相关。我写它来测试cookie。关键是这个代码如何映射到一个类中?

+0

有很多关于MVC如何工作的东西,我认为你可能希望你有一个页面后面的代码,但你不需要它MVC。我也经历了这一点,这是值得的努力:) – 2009-07-23 12:43:20

回答

1

当您创建一个ASP.Net MVC视图(页面)时,它从一个类继承,就如您所说的ViewPage - 它返回从Page.Net WebForms(System.Web.UI.Page)的Page类继承而来,并实现IViewDataContainer接口(来自MVC)。

Page类实现IIS“会谈”到的IHttpHandler接口。

总而言之,IHttpHandler有一个名为ProcessRequest的方法,它接受一个HttpContext实例。 (好吧,它的不是魔法,但你明白了) - 这个类是新的(你的ViewPage),它有几个被调用的方法 - 一些钩子主页等等,其中一个会以某种方式读取.aspx页面,并将所有普通输出包装在对Response.Write的调用中,其余部分将作为C#代码运行(并且<%= ...%>)将会变成Response.Write调用) - 我相信这个解析是通过正则表达式完成的。

请注意,我不是这方面的专家,很可能在技术上是错误的(嘿,有人可以对此发表更好的回答,我试图给出一般的理解),但它应该给予总体和全面的理解这个的。

编辑:另外我可以补充说,当你通过你的Controller类返回一个ViewResult时,它最终会有一个方法被调用(我相信它被称为Execute),它来自它继承的ActionResult类,然后它将启动一个选择正确的ViewEngine的过程,默认的一个是WebForms,然后调用整个过程来说明上面所有这些巨大的编辑混乱。

@ Hermant的评论 正如我所说的,如果你把母版页的东西,你需要考虑整个.aspx页面中的是,所有没有被包裹在<%和%的东西>是C#的方法如下所示的代码:

Response.Write("<html> ... <head> ..."); 

每过一段时间,你有你的<%...%>所有这些的Response.Write调用之间执行的呼叫。

哪个说采取以下的.aspx

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage" %> 
<html> 
    <head> 
     <title><%= MyMethodCallToFindTitle() %></title> 
    </head> 
    <body> 
     <ul> 
     <% for(int i = 0; i < 10; i++){ %> 
     <li><%= i %></li> 
     <% } %> 
     </ul> 
    </body> 
</html> 

这将一定程度上转化为一种方法寻找“有点”像这样:

Response.Write(@"<html> 
    <head> 
     <title>"); 
Response.Write(MyMethodCallToFindTitle()); 
Response.Write(@"</title> 
    </head> 
    <body> 
     <ul>"); 
for(int i = 0; i < 10; i++){ 
    Response.Write(@"<li>"); 
    Response.Write(i); 
    Response.Write(@"</li>"); 
} 
Response.Write(@"</ul> 
    </body> 
</html>"); 

注:当然还有一大堆的东西继续以防万一“在HTML中挂着,还有换行符,制表符缩进等等,但这是总体概述。

我希望这有助于。

+0

只是像<%int i = 0; %>对HTML输出没有影响!有趣的是,如果我再次重复同一个块,我会得到这个错误:一个名为'i'的局部变量已经在这个范围内定义了!也许所有的代码都按照相同的方法依次包装起来...... – Hemant 2009-07-23 13:02:33

1

您在页面上拥有的所有代码都可以放在控制器类中。基本上发生的事情是,你的控制器得到一个模型对象,它传递给视图。您可以即时创建该模型,也可以使用ASP.Net MVC模型文件夹来保存模型类。控制器应该处理任何想要过滤模型的参数,并将简单的对象放回到视图中。这样,你只需要在其中可以放置在一个简单的块这样

<%= myModelStringProperty %> 

的观点并继承的ViewPage模型类的一些字符串,但你不想把它作为它自己的一个类对。您应该针对您的模型进行编程,并将其传递给视图。 Visual Studio将提供强类型视图以一个特定的模式,这样就可以使用

<%= Model.MyProperty %> 

要输出的地方需要的数据。只要将视图本身视为数据的html模板即可。

+0

woa!我认为它从ViewPage继承,所以它必须是**类**以某种方式在它自己的方面。这个代码如何成为控制器类的一部分?请你详细说明一下吗? – Hemant 2009-07-23 12:44:43

+0

假设您有一个带有名为MyPage的ActionResult的控制器类。在这个动作集中ViewData [“MyKey”] =“Hi Hemant”。然后创建一个名为MyPage的视图并在其中包含<%= ViewData [“MyKey”]%>。 – 2009-07-23 12:49:49

1

你似乎正在通过WebForms的角度来看待这个 - MVC不是!当你的代码工作时,MVC很大程度上是关于问题的分离:你的控制器应该包含使用这些cookie的逻辑/代码,而View只负责渲染页面(以及控制器传递给它的任何ViewData)。

马克只是指出了这一点,但使用您的代码示例你有这样的事情在你的控制器:

public ActionResult About() { 
    var cookie = Request.Cookies["mvcData"]; 
    //rest of cookie code here 
    Response.Cookies.Add(newCookie); 
    ViewData["hello"] = "hi there..."; //add something to viewdata 

    return View(); 
} 

和视图内,您可以用<%=计算机[渲染消息“你好”]%>。 Cookie代码最好保存在控制器中,而不是视图中。

相关问题