g_b
g_b

Reputation: 12438

How value passed to this lambda

I am trying out a sample in ASP.NET MVC 4. He create an extension method for HtmlHelper. Below is the code:

public static class PagingHelpers
{
    public static MvcHtmlString PageLinks(this HtmlHelper html,
        PagingInfo pagingInfo,
        Func<int, string> pageUrl)
    {
        StringBuilder result = new StringBuilder();
        for (int i = 1; i <= pagingInfo.TotalPages; i++)
        {
            TagBuilder tag = new TagBuilder("a"); // Construct an <a> tag
            tag.MergeAttribute("href", pageUrl(i));
            tag.InnerHtml = i.ToString();
            if (i == pagingInfo.CurrentPage)
                tag.AddCssClass("selected");
            result.Append(tag.ToString());
        }
        return MvcHtmlString.Create(result.ToString());
    }
}

This is used by a view as below:

@Html.PageLinks(Model.PagingInfo, x => Url.Action("List", new { page = x, category = Model.CurrentCategory }))

This is the controller that defines the action method for the view:

public ViewResult List(string category, int page = 1)
{
    ProductsListViewModel model = new ProductsListViewModel {
        Products = repository.Products
            .Where(p => category == null || p.Category == category)
            .OrderBy(p => p.ProductID)
            .Skip((page - 1) * PageSize)
            .Take(PageSize),
        PagingInfo = new PagingInfo
        {
            CurrentPage = page,
            ItemsPerPage = PageSize,
            TotalItems = repository.Products.Count()
        },
        CurrentCategory = category
    };
    return View(model);
}

Based on the results of the extension method (and using breakpoints), the value of x is the 'page' parameter on the List action method in the controller. How did x get a hold of that? Or how did the value get passed to x? I've mostly used delegates on LINQ when I am working with collections; the value passed as parameter is from the collection (iterated). But I can't seem to grasp this.

Upvotes: 0

Views: 76

Answers (2)

Dominic Zukiewicz
Dominic Zukiewicz

Reputation: 8474

The PagingHelpers.PageLinks extension method is using the Func<int, string> to generate URLs.

Since the actual generation of the URL is provided by the View, not the extension method, the extension method is just using the mechanism defined in the view as the URL generator.

The extension method works like this:

  • I loop between 1 and the number of pages
  • I generate a link defined by the Func<int, string> passed into me
    • (Note I don't care how it works, as long as I give it an int and get back a string)
  • I use that in the href.

So look at the view:

@Html.PageLinks(Model.PagingInfo, x => Url.Action("List", new { page = x, category = Model.CurrentCategory }))

The Func<int, string> is saying "When I'm given an int x, call this code with it". This way the URL generation is controlled by the view. The extension method is inly interested in the resulting HTML generated by the Url.Action.

Upvotes: 1

Dmitry Zaets
Dmitry Zaets

Reputation: 3277

Basically Func<int, string> pageUrl means a function with one int param and which returns string.

You are calling this function in for loop by:

tag.MergeAttribute("href", pageUrl(i));

When you are calling pageUrl it basically calls something like:

public String SomeFunction(int x)
{
  return Url.Action("List", new { page = x, category = Model.CurrentCategory });
}

So x => Url.Action("List", new { page = x, category = Model.CurrentCategory }) here means anonymous function which just wraps Url.Action function

Upvotes: 1

Related Questions