views:

370

answers:

5

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.

+21  A: 

<%=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()));
}
Darin Dimitrov
The correct solution but some explanatory text would help.
AnthonyWJones
@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.
Darin Dimitrov
+1 but don't you mean %><%=x%><% is a shortcut for Response.Write(x); OR <%=x%> is a shortcut for <$Response.Write(x);%> ? ;)
AnthonyWJones
@Anthony, you are totally correct, I've updated my post. Thank you.
Darin Dimitrov
+6  A: 

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

Filip Ekberg
+3  A: 

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.

Rohith
+2  A: 

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.

AnthonyWJones
A: 

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.

couellet
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; }
couellet