开发者

Avoiding spaghetti code in ASP.NET MVC

Probably a stupid question, but here goes. In my view, I have the following code....

   <%@ Control Lan开发者_运维百科guage="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()) %>
    <%
} %> 

Do I have to close and reopen around the call to Html.Label "%><%" etc.?

I'd much rather do something like...

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

...but the labels aren't being displayed.

Can you guess that I'm new to this??

Many thanks,

ETFairfax.


<%=x %> is just a shortcut for Response.Write(x):

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


This is just a short-tag <%= for <% Response.Write note the difference between <% and <%=

So you could very well write it like this:

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

One could argue which is nicer..


The key here is to understand the difference between <% some code %> and <%= some code %>. <% some code %> means just execute "some code". <%= some code %> means execute some code and put the return value in the response. This is why Darin's answer above works by using Response.Write.


The correct answer has already been given (at least twice). However some subtlies are worth pointing out. Fundementally,

<% stuff here %>

means execute the contained statements represented by "stuff here" using the default language. Whereas:-

<%=stuff here %>

means evaluate the contained string expression represented by "stuff here" using the default language and send the result to the response.

Here is a common gotcha. Is this:-

<%="Hello, World!"%>

the same as this:-

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

?

Ans: no. Note the first is an expression and is not terminated with a ;. Whereas the second is a statement and will be a syntax error. It has the ; missing.


Also consider a switch to Razor view engine. You can get rid of those pesky <% %>

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

becomes

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


Another suggestion is to create a custom HtmlHelper that would take the Start and EndPage as parameters. In the Helper you should do something like this:

 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();
    }

Test (note that I am using MvcContrib TestControllerBuilder and 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"));
        }

Then in your view you can use this like that:

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

So this is avoiding the spaghetti code that you don't want to see and this is testable.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜