9

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

   <%@ 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()) %>
    <%
} %> 

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.

1
  • 10
    And the award in Topic-Naming goes to.. Drumroll..... someone else. Commented Nov 6, 2009 at 12:57

6 Answers 6

26

<%=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()));
}
Sign up to request clarification or add additional context in comments.

3 Comments

@AnthonyWJones, I thought that the code is pretty self explanatory. A single line of code is worth thousand words, but I agree with you that some explanatory text could be helpful in this case.
+1 but don't you mean %><%=x%><% is a shortcut for Response.Write(x); OR <%=x%> is a shortcut for <$Response.Write(x);%> ? ;)
@Anthony, you are totally correct, I've updated my post. Thank you.
6

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..

Comments

4

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.

Comments

3

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.

Comments

2

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

1 Comment

Or you could just do <% for (int i = Model.StartPage; i <= Model.EndPage; i++) { Response.Write(Html.Label(ViewData.Model.Controller + i.ToString())); } %>
0

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.

1 Comment

Forgot to mention that I had no Html.Label extension method, so mine is very simple: public static string Label(this HtmlHelper html, string input) { return input; }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.