'When using ASP.NET MVC, what is the best way to update multiple page sections with one HTML.Action() method?

I have a pretty big ASP.NET MVC site with 100 controllers and thousands of actions. Previously the header image that was defined on the Site.Master page was hardcoded and I want to make it dynamic.

To do so, I added this line to my Site.Master file:

<%= Html.Action("GetHeaderTitle", "Home")%>

which just returns some HTML for the header title such as:

<span style='font-size:15px;'>My Header Title</span>

The issue is that <title> also had this same hard coded value. I could obviously create another HTML.Action to have it show the dynamic valid in the title, but now I am going back to the server twice for essentially the same information (not the exact same HTML as I don't want the span information, but the same logic on the server to get the data).

Is there a way to have an Html.Action return multiple snippets of HTML that I can updates in different places on my master page?



Solution 1:[1]

I think you're looking at it wrong - if retrieving of the title is a long operation then just cache the results and write different actions anyway.

// Controller
public string GetTitle()
{
    var title = (string)ControllerContext.HttpContext.Items["CachedTitle"];
    if (string.IsNullOrEmpty(title))
    {
        title = "some lengthy retrieval";
        ControllerContext.HttpContext.Items["CachedTitle"] = title;
    }
    return title;
}

public ActionResult GetTitleForTitle()
{
    return Content(GetTitle());
}

public ActionResult GetHeaderTitle()
{
    return Content("<span>"+ GetTitle() + "<span>");
}

Alternatively, you can cache it directly on the view, which is kind of evil (the simpler view the better):

 <%
   ViewBag.CachedTitle = Html.Action("GetHeaderTitle", "Home");
 %>
 ...
 <%= ViewBag.CachedTitle %>
 ...
 <%= ViewBag.CachedTitle %>

Solution 2:[2]

Are you using <asp:ContentPlaceHolder ID="TitleContent" runat="server" /> ? in your site.master? Or have you considered using it? This would allow you to set the title from within a view based on your model.

Maybe you should also consider to introduce ViewModels, which allows you to combine view related data into a ViewModel and return it from a controller. This would allow you to batch queries and save round trips. And use a data repository which gets injected into your controller class (if you are not already doing). Sorry I'm guessing here because you do not show any controller code.

Or you should take advantage of client side code (JavaScript) and load parts of the UI via ajax? And have the UI update itself (could also be reactive).

Unfortunately I have the feeling that the thing your are facing today is not about the title but more about the hundreds of controllers with thousands of actions.

So researching how to organize controllers and building up an opinion based on your use cases would be my best bet based on what I can see and guess from your question.

Hope that helps...

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Peter Mortensen
Solution 2 silverfighter