Rendering Helpers

Rendering helpers produce links to other resources inside an application, and can also enable you to build those reusable pieces of UI known as partial views.

Html.ActionLink and Html.RouteLink

The ActionLink method renders a hyperlink (anchor tag) to another controller action. Like the BeginForm helper you looked at earlier, the ActionLink helper uses the routing API under the hood to generate the URL. For example, when linking to an action in the same controller used to render the current view, you can simply specify the action name:

@Html.ActionLink("Link Text", "AnotherAction")

This produces the following markup, assuming the default routes:

<a href="/Home/AnotherAction">LinkText</a>

When you need a link pointing to an action of a different controller, you can specify the controller name as a third argument to ActionLink. For example, to link to the Index action of the ShoppingCartController, use the following code:

@Html.ActionLink("Link Text", "Index", "ShoppingCart")

Notice that you specify the controller name without the Controller suffix. You never specify the controller's type name. The ActionLink methods have specific knowledge about ASP.NET MVC controllers and actions, and you've just seen how these helpers provide overloads enabling you to specify just the action name, or both the controller name and action name.

In many cases you'll have more route parameters than the various overloads of ActionLink can handle. For example, you might need to pass an ID value in a route, or some other route parameter specific to your application. Obviously, the built-in ActionLink helper cannot provide overloads for these types of scenarios out of the box.

Fortunately, you can provide the helper with all the necessary route values using other overloads of ActionLink. One overload enables you to pass an object of type RouteValueDictionary. Another overload enables you to pass an object parameter (typically an anonymous type) for the routeValues parameter. The runtime reflects over the properties of the object and uses them to construct route values (the property names will be the name of the route parameter, and the property values will represent the value of the route parameter). For example, to build a link to edit an album with an ID of 10720 you can use the following code:

@Html.ActionLink("Edit link text", "Edit", "StoreManager", new {id=10720}, null)

The last parameter in the preceding overload is the htmlAttributes argument. You saw earlier in the chapter how you can use this parameter to set any attribute value on an HTML element. The preceding code is passing a null (effectively not setting any attributes in the HTML). Even though the code isn't setting attributes, you have to pass the parameter to invoke the correct overload of ActionLink.

The RouteLink helper follows the same pattern as the ActionLink helper, but also accepts a route name and does not have arguments for controller name and action name. For example, the first example ActionLink shown previously is equivalent to the following:

@Html.RouteLink("Link Text", new {action="AnotherAction"})

URL Helpers

The URL helpers are similar to the HTML ActionLink and RouteLink helpers, but instead of returning HTML they build URLs and return the URLs as strings. There are three helpers:

  • Action
  • Content
  • RouteUrl

The Action URL helper is exactly like ActionLink, but does not return an anchor tag. For example, the following code will display the URL (not a link) to browse all Jazz albums in the store.

        <span>
            @Url.Action("Browse", "Store", new { genre = "Jazz" }, null)
        </span>

The result will be the following HTML:

       <span>
            /Store/Browse?genre=Jazz
        </span>

When we reach the AJAX chapter (Chapter 8), we'll see another use for the Action helper.

The RouteUrl helper follows the same pattern as the Action helper, but like RouteLink it accepts a route name and does not have arguments for controller name and action name.

The Content helper is particularly helpful because it can convert a relative application path to an absolute application path. You'll see the Content helper at work in the music store's _Layout view.

<script src="@Url.Content("∼/Scripts/jquery-1.5.1.min.js")" 
        type="text/javascript"></script>

Using a tilde as the first character in the parameter you pass to the Content helper will let the helper generate the proper URL no matter where your application is deployed (think of the tilde as representing the application root directory). Without the tilde the URL could break if you moved the application up or down the virtual directory tree.

Html.Partial and Html.RenderPartial

The Partial helper renders a partial view into a string. Typically, a partial view contains reusable markup you want to render from inside multiple different views. Partial has four overloads:

public void Partial(string partialViewName);   
public void Partial(string partialViewName, object model);  
public void Partial(string partialViewName, ViewDataDictionary viewData);    
public void Partial(string partialViewName, object model, 
                    ViewDataDictionary viewData);

Notice you do not have to specify the path or file extension for a view because the logic the runtimes uses to locate a partial view is the same logic the runtime uses to locate a normal view. For example, the following code renders a partial view named AlbumDisplay. The runtime looks for the view using all the available view engines.

@Html.Partial("AlbumDisplay")

The RenderPartial helper is similar to Render, but RenderPartial writes directly to the response output stream instead of returning a string. For this reason, you must place RenderPartial inside a code block instead of a code expression. To illustrate, the following two lines of code render the same output to the output stream:

@{Html.RenderPartial("AlbumDisplay "); }
@Html.Partial("AlbumDisplay ")

So, which should you use, Partial or RenderPartial?

In general, you should prefer Partial to RenderPartial because Partial is more convenient (you don't have to wrap the call in a code block with curly braces). However, RenderPartial may result in better performance because it writes directly to the response stream, although it would require a lot of use (either high site traffic or repeated calls in a loop) before the difference would be noticeable.

Html.Action and Html.RenderAction

Action and RenderAction are similar to the Partial and RenderPartial helpers. The Partial helper typically helps a view render a portion of a view's model using view markup in a separate file. Action, on the other hand, executes a separate controller action and displays the results. Action offers more flexibility and re-use, because the controller action can build a different model and make use of a separate controller context.

Once again, the only difference between Action and RenderAction is that RenderAction writes directly to the response (which can bring a slight efficiency gain). Here's a quick look at how you might use this method. Imagine you are using the following controller:

public class MyController {
  public ActionResult Index() {
    return View();
  }
  
  [ChildActionOnly]
  public ActionResult Menu() {
    var menu = GetMenuFromSomewhere();
    return PartialView(menu);
  }
}

The Menu action builds a menu model and returns a partial view with just the menu:

@model Menu
<ul>
@foreach (var item in Model.MenuItem) {
  <li>@item</li>
}
</ul>

In your Index.cshtml view, you can now call into the Menu action to display the menu:

<html>
<head><title>Index with Menu</title></head>
<body>
    @Html.Action("Menu")
    <h1>Welcome to the Index View</h1>
</body>
</html>

Notice that the Menu action is marked with a ChildActionOnlyAttribute. The attribute prevents the runtime from invoking the action directly via a URL. Instead, only a call to Action or RenderAction can invoke a child action. The ChildActionOnlyAttribute isn't required, but is generally recommended for child actions.

In MVC 3 there is also a new property on the ControllerContext named IsChildAction. IsChildAction will be true when someone calls an action via Action or RenderAction (but false when invoked through a URL). Some of the action filters of the MVC runtime behave differently with child actions (such as the AuthorizeAttribute and OutputCacheAttribute).

Passing Values to RenderAction

Because these action helpers invoke action methods, it's possible to specify additional values to the target action as parameters.

For example, suppose you want to supply the menu with options.

1. You can define a new class, MenuOptions, like so:

public class MenuOptions {
    public int Width { get; set; }
    public int Height { get; set; }
}

2. Change the Menu action method to accept this as a parameter:

[ChildActionOnly]
public ActionResult Menu(MenuOptions options) {
    return PartialView(options);
}

3. You can pass in menu options from your action call in the view:

@Html.Action("Menu", new { 
    options = new MenuOptions { Width=400, Height=500} })

Cooperating with the ActionName Attribute

Another thing to note is that RenderAction honors the ActionName attribute when calling an action name. If you annotate the action like so:

[ChildActionOnly]
[ActionName("CoolMenu")]
public ActionResult Menu(MenuOptions options) {
    return PartialView(options);
}

you'll need to make sure to use CoolMenu as the action name and not Menu when calling RenderAction.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.225.57.126