避免ASP.NET MVC中的意大利面条代码

时间:2009-11-06 12:54:34

标签: asp.net-mvc model-view-controller

可能是一个愚蠢的问题,但是这里有。在我看来,我有以下代码......

   <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Learner.MvcApplication.ViewModels.PagerViewModel>" %><% 

for (int i = Model.StartPage; i <= Model.EndPage; i++)
{
    %>
    <% =Html.Label(ViewData.Model.Controller + i.ToString()) %>
    <%
} %> 

我是否必须关闭并重新打开对Html.Label“%&gt;&lt;%”等的调用?

我宁愿做点什么......

for (int i = Model.StartPage; i <= Model.EndPage; i++)
{
    Html.Label(ViewData.Model.Controller + i.ToString());
} 

...但标签未显示。

你能猜出我是新来的吗?

非常感谢,

ETFairfax。

6 个答案:

答案 0 :(得分:26)

<%=x %>只是Response.Write(x)的快捷方式:

for (int i = Model.StartPage; i <= Model.EndPage; i++)
{
    Response.Write(Html.Label(ViewData.Model.Controller + i.ToString()));
}

答案 1 :(得分:7)

这只是<%=的短标记<% Response.Write,请注意<%<%=

之间的区别

所以你可以这样写出来:

for (int i = Model.StartPage; i <= Model.EndPage; i++)
{
    Response.Write(Html.Label(ViewData.Model.Controller + i.ToString()));
}

有人可能会争辩哪个更好......

答案 2 :(得分:4)

这里的关键是理解&lt;%some code%&gt;之间的区别和&lt;%=某些代码%&gt;。 &lt;%some code%&gt;意味着只执行“一些代码”。 &lt;%=某些代码%&gt;表示执行一些代码并将返回值放在响应中。这就是为什么Darin的上述答案通过使用Response.Write来实现。

答案 3 :(得分:3)

已经给出了正确答案(至少两次)。然而,一些细节值得指出。 Fundementally,

<% stuff here %>

表示使用默认语言执行“stuff here”所代表的语句。鉴于: -

<%=stuff here %>

表示使用默认语言评估“stuff here”所代表的字符串表达式,并将结果发送给响应。

这是一个常见的问题。这是: -

<%="Hello, World!"%>

与此相同: -

<%Response.Write("Hello, World!")%>

答:没有。请注意,第一个是表达式,并且不以;结尾。而第二个是声明,将是语法错误。它有;丢失。

答案 4 :(得分:2)

同时考虑切换到Razor view engine。你可以摆脱那些讨厌的&lt; %%&gt;

for (int i = Model.StartPage; i <= Model.EndPage; i++)
{
    %>
    <% =Html.Label(ViewData.Model.Controller + i.ToString()) %>
    <%
} %>

变为

@for (int i = Model.StartPage; i <= Model.EndPage; i++)
{        
    Html.Label(ViewData.Model.Controller + i.ToString())        
}

答案 5 :(得分:0)

另一个建议是创建一个自定义HtmlHelper,它将Start和EndPage作为参数。在帮手你应该做这样的事情:

 public static string Pager<TModel>(this HtmlHelper<TModel> html, Func<TModel, string> Prefix, int StartPage, int EndPage) where TModel : class
    {
        var builder = new StringBuilder();

        for (var i = StartPage; i <= EndPage; i++)
            builder.Append(html.Label(Prefix.Invoke(html.ViewData.Model) + i));

        return builder.ToString();
    }

测试(请注意我使用的是MvcContrib TestControllerBuilder和RhinoMocks:

[Test]
        public void Pager_should_be_ok()
        {
            var testBuilder = new TestControllerBuilder();
            var controller = new TestController();

            testBuilder.InitializeController(controller);

            var viewData = MockRepository.GenerateStub<IViewDataContainer>();
            viewData.ViewData = new ViewDataDictionary
            {
                Model = new TestObject { Key = "Test", Value = "Value" }
            };

            var viewContext = new ViewContext { RouteData = new RouteData(), RequestContext = controller.ControllerContext.RequestContext };
            var html = new HtmlHelper<TestObject>(viewContext, viewData);

            var output = html.Pager(x => x.Key, 1, 2);

            Assert.That(output, Is.EqualTo("Test1Test2"));
        }

然后在你的视图中你可以这样使用:

<%= Html.Pager(x => x.Controller, Model.StartPage, Model.EndPage) %>

所以这就是避免你不想看到的意大利面条代码,这是可以测试的。