Site Meter
 
 

Partial Requests in ASP.NET MVC

In your ASP.NET MVC application, it can be tricky to combine multiple independent “widgets” on the same page. That’s because a WebForms-style hierarchy of independent controls clashes awkwardly against a purist’s one-way MVC pipeline. Widgets? I’m taking about that drill-down navigation widget you want in your sidebar, or the “most recent forum posts” widget you’d put in the page footer. Things that need to fetch their own data independently of the page that hosts them.

So, you’ve got basically two options:

  1. Make sure each action prepares an absolutely complete set of ViewData for not just the main page you’re rendering but also for every widget it hosts. Then in your view you can render widgets by calling <% Html.RenderPartial(…) %>, passing to the partial view template the subset of ViewData needed to render that widget.
  2. Allow actions or views to invoke other actions, spinning off multiple internal mini-MVC pipelines that prepare and render each widget.

Incidentally, this is exactly the same choice on offer to Ruby on Rails developers, who face the exact same issue. However, in Rails-world, option 2 is frowned upon because of the framework’s performance issues. But we don’t need to have that problem in ASP.NET MVC.

These two options are both perfectly usable in ASP.NET MVC, and each has its strengths and is suited to different circumstances.

Option 1 keeps your MVC pipeline simple and elegant, but it struggles to scale up in complexity if you have many widgets or hierarchies of widgets that appear or disappear at different times. It’s nice to use filter attributes to inject the ViewData elements needed for each widget, but not nice if there are many.

Option 2 is conceptually much simpler and enables simpler code, though at runtime there are more moving parts. It’s more like having a collection of genuinely independent widgets.  This is what you get with <%= Html.RenderAction(…) %> (which is sadly relegated to the MVC Futures assembly and has been left with some technical problems), and also with MvcContrib’s new idea of subcontrollers.

You’re free to choose the option that works best for you in any individual case. If someone tells you that internal subrequests (option 2) are bad because it “isn’t MVC”, then just bite them on the face immediately. Also ask them why they’re still willing to use Ajax, and even <IMG> tags for that matter, given that both are a form of subrequest.

About subcontrollers

Firstly, thankyou to the MVC Contrib guys, because the subcontrollers idea is neat and genuinely improves on what we had before with Html.RenderAction().

The core idea of subcontrollers is putting into ViewData a delegate for each widget. The view can render the widget by invoking the delegate. This allows the view to be totally ignorant of the widget it’s rendering, leaving the controller in full control. That eliminates the main problem people had with Html.RenderAction(). Brilliant!

What I don’t like so much about MVC Contrib’s subcontrollers is that it’s quite a heavyweight and complex solution. Firstly you have to be using MVC Contrib, and then you have to learn a non-obvious set of new conventions, and an alternative controller base class, and do something funny with your default model binder. I think it’s possible to get virtually all the same benefits (and some extra ones) with a utility class that’s just 17 lines long.

Partial Requests are easy

You’ve heard of partial views, so how about partial requests? Within any MVC request, you can set up a collection of internal partial requests, each of which can set up its own internal partial requests and so on. Each partial request renders a plain old action method in any of your plain regular controllers, and each can produce an independent widget. I’m calling them partial “requests” rather than “controllers” because they run a proper MVC request-handling pipeline that’s compatible with your routing system and your controller factory. Still, as with subcontrollers, all the control remains in controllers, and the view can be ignorant.

Drop this class somewhere in your MVC project:

public class PartialRequest
{
    public RouteValueDictionary RouteValues { get; private set; }
 
    public PartialRequest(object routeValues) {
        RouteValues = new RouteValueDictionary(routeValues);
    }
 
    public void Invoke(ControllerContext context)
    {
        RouteData rd = new RouteData(context.RouteData.Route, context.RouteData.RouteHandler);
        foreach (var pair in RouteValues)
            rd.Values.Add(pair.Key, pair.Value);
        IHttpHandler handler = new MvcHandler(new RequestContext(context.HttpContext, rd));
        handler.ProcessRequest(System.Web.HttpContext.Current);
    }
}

Now, when you want to attach a widget to your output, you can put a partial request into view data as so:

ViewData["latestPosts"] = new PartialRequest(new {
    controller = "Blog",
    action = "LatestPosts"
});

… then wherever you want to display that widget in your view, put:

<% ((PartialRequest)ViewData["partialAction"]).Invoke(ViewContext); %>

… or if you prefer, use this trivial Html.RenderPartialRequest() helper:

public static class PartialRequestsExtensions
{
    public static void RenderPartialRequest(this HtmlHelper html, string viewDataKey)
    {
        PartialRequest partial = html.ViewContext.ViewData.Eval(viewDataKey) as PartialRequest;
        if (partial != null)
            partial.Invoke(html.ViewContext);
    }
}

Now, having imported the relevant namespace, your view can simply contain:

<% Html.RenderPartialRequest("latestPosts"); %>

Assuming you have a regular BlogController with an action called LatestPosts, which might render its own view (have it render an MVC View User Control rather than an entire MVC View Page) or might simply return a ContentResult, you’ll find that its output is injected at the appropriate point in your view.

image

Of course, this works seamlessly with whatever arrangement of controller factories, model binders, and action invokers you might be using, and it executes any filters that surround the partial request’s target action method.

It’s testable, too: your unit tests can pick the PartialRequest object out of ViewData, and inspect its RouteValues collection, so check it’s invoking the expected target.

It naturally supports hierarchies of widgets, too: the action that a PartialRequest calls can fill its own independent ViewData collection with other PartialRequest objects, and invoke them from its own view, and so on.

It works well with Ajax, too: since your widget is the output of a plain old action method, you could use an Ajax request to re-fetch the widget’s contents and update it in the DOM without a full page refresh.

There’s one other major benefit, too, but I’m going to save that until tomorrow, because it’s cool enough to warrant a follow-up post in its own right…

kick it on DotNetKicks.com

93 Responses to Partial Requests in ASP.NET MVC

  1. Andreas

    Steve, thank you this was a good read and something I will include in my own project to replace the RenderAction extension method (and in favour of the subcontroller support on MVCContrib).

  2. Andreas

    Oh one thing that this doesn’t do it to play nice if placed on a master page. I imagine quite a lot of widgets would be placed on your master page and would need to be populated with different pieces of (typed) data.

    You can do this with Html.RenderAction and my first thought was to just add an overload for the RenderPartialRequest extensions method where the second parameter was a PartialRequest.

    However this won’t work since you will be invoking it in the wrong controller context, i.e imagine you paced the “recent post” widget on your master page then you’d need to be on view which was created by the Blog controller or controllerContext would be wrong and the action wouldn’t be able to be found¨.

  3. Steve

    Hi Andreas, thanks for your comments. I’m not completely certain that I understand what you’re getting at, but PartialRequest objects are able to target actions on any controller, independently of the main controller that’s handling the request. So I’m not sure there is an issue as you describe.

    The tricky bit with widgets on master pages – and this applies equally to PartialRequest, MVC Contrib’s subcontrollers, and plain partial views as widgets – is deciding where to put the code that populates ViewData. That’s because ASP.NET MVC doesn’t have a specific concept of “master controller”, but instead wisely lets you pick your own. Your options are:

    [1] Have a common base class for all your controllers, and override OnResultExecuting, putting a PartialRequest into ViewData there
    [2] Have a filter attribute you can sprinkle over your controllers that puts a PartialRequest in ViewData
    [3] Establish some other convention of master controller code in your app

    Essentially, you’re forced to choose *somewhere* to prepare ViewData for master page widgets. The only obvious way of bypassing this is to use Html.RenderAction(), which allows the view to make its own decisions about rendering widgets. In many ways this is the cleanest solution of all. You might think this gives too much responsibility to the view, but we’re usually talking only about a few widgets on a single master page that applies to your entire application, so it certainly doesn’t reduce maintainability or testability unless you use and abuse it to excess.

  4. Andreas

    Oh nevermind me. I just noticed I had swapped two variables around in my code and after solving that I was able to use the PartialRequest just fine from my master page.

    The only modifications I made was to the extension methods

    public static void RenderPartialRequest(this HtmlHelper html, string viewDataKey)
    {
    PartialRequest partial =
    html.ViewContext.ViewData.Eval(viewDataKey) as PartialRequest;

    PartialRequestsExtensions.RenderPartialRequest(html, partial);
    }

    public static void RenderPartialRequest(this HtmlHelper html, PartialRequest partial)
    {
    if (partial != null)
    {
    partial.Invoke(html.ViewContext);
    }
    }

    and then you can call it by explicitly passing it a PartialRequest object like so

    Html.RenderPartialRequest(new PartialRequest(new
    {
    controller = “YourController”,
    action = “YourAction”
    }));

    Voliá :-)

  5. Steve

    Hi there. Glad you got that sorted out. Obviously the way you’re using PartialRequest is exactly equivalent to using Html.RenderAction() (so you might was well use Html.RenderAction()), but if that’s what you want then fine.

  6. Andreas

    @Steve well with the help of the two extension method overloads I will be able to use PartialRequests both ways using only one technique (also with potentially one less dependency in the future).

  7. Mike

    Hey, great! Can you also address possible downsides, because each time partials or components for ASP.NET MVC are discussed it seems that there is never a solution without downsides. Which is probably why the current Microsoft implementation is in ‘futures’…

    Looking forward to the next post, and to using your simple implementation!

  8. Pingback: Steve Sanderson’s blog » Blog Archive » Partial output caching in ASP.NET MVC

  9. Steve

    @Mike: Thanks!

    One caveat that I forgot to bring up is that, because of a quirk of how TempData is implemented, you can’t use TempData during an action that’s invoked via a PartialRequest. This isn’t really a concern for me in my particular use case right now, but I’m sure it could be resolved if anyone needed.

    Other than that, I wouldn’t really say there are any particular downsides; after all, this is just one more technique to have in your toolbox. It’s not always the best approach. For example, if your widget is logically related to its host page, then it makes sense to prepare the widget’s viewdata inline in the host action and render the widget as a simple partial view. However, if the widget isn’t logically related to the host page, you might prefer not to mix those concerns and to use PartialRequest or subcontroller or Html.RenderAction() instead.

  10. mike

    Thanks for the reply!

  11. Pingback: Want to do cool things with ASP.NET MVC? - Aaron Jensen

  12. Very cool, and thanks for the link.

    What’s the testing story for this technique?

  13. Nevermind, I hadn’t read that paragraph. I will try this out now! Thanks.

  14. Great post. There seems to be a lot of work in the framework to prevent people from doing stuff like this for patterns sake. Partial rendering has been locked out from the beginning, it seems. I like taking the shackles off, and this code lets me do that.

    Thanks for taking the time to post,

    Jesse Foster | jf26028

  15. Steve, again – well done. Wish I had thought of this. How about a filter attribute that inserts the PartialRequest into ViewData? Might help clean up the actions and ease testing. We have “portal” views which use 10 or more partials.

    Also – have you considered contributing this to MvcContrib? It’s a very elegant solution.

  16. lauri

    This is great. I added little helper function to make this little bit more convient to use like

    Html.RenderPartialRequest(new {controller=”Model”, action=”Panel_AddProfile” });

    public static void RenderPartialRequest(this HtmlHelper html, object routeValues)
    {
    PartialRequest partial = new PartialRequest(routeValues);
    if (partial != null)
    partial.Invoke(html.ViewContext);
    }

    thanx

  17. Steve

    @Matt – thank you. I agree that if you are reusing widgets on whole sets of action methods, then it’s neat to use a filter attribute to put a PartialRequest object into ViewData. If you’d like to add partial requests and related code to MvcContrib then I’m entirely happy with that – please feel free to go ahead!

    @Lauri – very nice. You should bear in mind that, as with Andreas’s comment earlier, what you’re doing with your overload is exactly equivalent to what the built-in Html.RenderAction() helper (or Html.RenderRoute()) does. So, you might consider using one of those built-in methods to achieve the same thing.

  18. Hi Steve,

    This is great!

    I’ve implemented this solution in my small framework I am building, only I took a lambdier approach :)

    You see, I am prohibiting the use of ViewData as Dictionary and setting the convention that Model must always be used (actually this convention is Jeremy Miller’s idea, but I found it very neat).

    Now, in my controllers I do:

    var viewModel = new ListUsersViewModel {
    Sidebar = PartialFor<SidebarController>(c => c.List())
    }

    and in my view (because of the mentioned convention above), I can:

    < %= RenderPartialOf(model => model.Sidebar) %>

    much cleaner in my opinion!

    Also as my delegate definition for above RenderPartial is:
    public delegate PartialRequest PartialRequestOperation(T declaringType);

    in my intellisense only the PartialRequest types in my model will show or can be used (no typos or wrong property selections).

    What do you think?

  19. Steve

    Hi Vladan,

    That looks nice – certainly there are some benefits to strongly-typed viewdata.

    However, if you prohibit the use of viewdata as a dictionary, how will you mix in widgets that are unrelated to the current action? Are you going to force every action method to be aware of the notion of “sidebar”, as in the code you posted? And if so, why bother with PartialRequest at all? You could just put some SidebarData into your ViewData and then render the sidebar using a normal partial view (i.e., Html.RenderPartial()).

    Update: Vladan has explained to me that he has a base class for all his ViewData model objects, and he uses a filter or controller base class to populate the “Sidebar” property on the ViewData model base class. That means he doesn’t need to mix the concerns of each widget in with each action. The main benefit of using PartialRequest here, then, is partial caching and the ability to change which widget gets rendered at runtime according to other data.

  20. Alice

    Isn’t it the same code RenderAction implemented? Would you point me the differences?

  21. Steve

    @Alice, yes, it’s very similar to Html.RenderAction(). The only difference is that with PartialRequest, the view template can be completely ignorant of the widget it’s being asked to render. This gives your controllers more control over the page output.

    In some cases, this might not really make any difference. However, if you need to select and display a collection of widgets according to some logic, then it’s preferable to keep this logic in controller code rather than in a view template.

  22. Peter

    Can you show me what a test for Invoke method would look like using Rhino Mocks. I can’t get System.Web.HttpContext.Current to mock out.

    Thanks

  23. Steve

    @Peter – you don’t need to write tests for PartialRequest.Invoke(); you only need to write tests for your own action methods. If an action method is supposed to prepare a PartialRequest object, then your unit test can inspect ViewData and see that the expected PartialRequest object was put there. You don’t need to use any mocking tool to do this.

    This is the strength of the whole ActionResult concept. It eliminates the need for mocking most of the time.

  24. Steve,
    Congrats for this great work.
    Great solution for Partial Requests in ASP.NET MVC. It is a better solution than sub controller of MVCContrib.

  25. Peter

    Steve- I understand that you can use ActionResult to test the output from PartialRequest.Invoke. In my scenario, I am putting PartialRequest.Invoke in a class library that I will use with a lot of MVC projects, and I need to include unit tests with this library, would a proper way to test Invoke method is still through examining ViewData object?

  26. Peter – aha, I see. I’m not convinced that retrofitting a test for this is going to improve your code quality, but if you do want to break the dependency on System.Web.HttpContext.Current, try replacing the whole PartialRequest class with this:

    public class PartialRequest
    {
    public RouteValueDictionary RouteValues { get; private set; }

    public PartialRequest(object routeValues)
    {
    RouteValues = new RouteValueDictionary(routeValues);
    }

    public void Invoke(ControllerContext context)
    {
    RouteData rd = new RouteData(context.RouteData.Route, context.RouteData.RouteHandler);
    foreach (var pair in RouteValues)
    rd.Values.Add(pair.Key, pair.Value);
    var handler = new AccessibleMvcHandler(new RequestContext(context.HttpContext, rd));
    handler.ProcessRequest(context.HttpContext);
    }

    private class AccessibleMvcHandler : MvcHandler
    {
    public AccessibleMvcHandler(RequestContext requestContext) : base(requestContext) {}
    public new void ProcessRequest(HttpContextBase httpContext) { base.ProcessRequest(httpContext); }
    }
    }

    Note that to write a working unit test for Invoke(), you’ll also need to assign a mock IControllerFactory to ControllerBuilder (you’ll see when you try it).

  27. Chris

    Perfect! This looks exactly like what I need. Any chance you already have a simple VS solution you can zip up and send me?

  28. Steve

    @Chris – thanks. The PartialRequests code will be more useful to you if you add it to one of your own projects. All you need to do is follow the instructions above, starting from the heading “Partial Requests are Easy”.

  29. Pingback: Subcontrollers and caching on ASP.NET MVC - LA.NET [EN]

  30. @Steve,
    I really like that idea. It has the exact same guts as the Subcontroller base class, but it’s pulled out into a separate class so that the partial’s controller can be any implementation of IController. Love it. I’ll have to refactor MvcContrib’s implementation to support this. Would you be interested in contributing to MvcContrib more broadly?

  31. Oren Ben-Kiki

    I am a newbie to the MVC framework, so perhaps I am missing something obvious here. It was my understanding that the controller’s responsibility was to (1) fetch the necessary model and (2) decide on which view to render. The view then “simply” formats the data given to it in the model.

    If that is the case, I fail to understand the problem with RenderAction. Sure, it specifies a specific controller name. That seems reasonable; if I want to have some logic deciding what needs to be done at this point of the view, a controller seems like the right place to put it in.

    How is that different from using a specific controller name as a target of a route? Also, supposing this is a problem, wouldn’t using one of the numerous IoC frameworks solve the problem anyway?

    One possible benefit I can imagine is that it makes it harder to unit-test the view. But wouldn’t that be solved with a simple mock ControlFactory that returns “canned” responses to any RenderAction requests? Surely that would be simpler than sub-controllers or even PartialRender?

    My team is now seriously entering into using MVC and we need to decide whether we should use (MVC) user controls vs. RenderPartial, and RenderAction vs. PartialRequest vs. SubControllers. I am tending towards using RenderPartial for simple HTML refactoring and RenderAction wherever there is actual logic involved, as the simplest solution (albeit in the “futures” namespace). But I am nervous that I am missing some deep problem with RenderAction that will bite us once we have large amounts of code.

    I googled around and while I found plenty of references to the “debate” and “disagreement” and how RenderAction “breaks separation of concerns”. I couldn’t find any place that explains the actual problem in clear terms. I looked at SubControllers and PartialRequest and I still don’t get what exactly they are trying to solve.

    Perhaps I am being dense, but “He who is not willing to appear stupid in public, shall never reach enlightenment”. What am I missing?

  32. Steve

    @Oren, your question is well expressed, and you clearly have a good sense of the design goals that MVC strives for.

    > The view then “simply” formats the data given to it in the model

    Exactly, and this is the essence of the problem that some people have with RenderAction, because RenderAction falls outside this pattern. When you use RenderAction, you’re allowing a view template to have the authority to select a new controller and action to invoke, so the view is no longer just a dumb HTML formatter. Normally, this kind of application logic is not within the view’s single concern/responsibility of formatting data as HTML.

    PartialRequest and subcontrollers try to retain all application logic in controllers by giving the controller the ability to nominate the secondary controller/action to be rendered. This means that view templates don’t need to be concerned with the details.

    I don’t personally see any major problem with using RenderAction (or PartialRequest or subcontrollers) as long as you restrict the use to places where the widget (or whatever you’re rendering) is logically independent from the page in which it’s hosted. If it is logically independent (such as a global nav control) then it doesn’t make sense for your controller to be concerned about it. But if it is logically dependent (such as a repeating UI block used to render a list), then it makes more sense to use RenderPartial (having supplied all the data at once from the controller).

    > whether we should use (MVC) user controls vs. RenderPartial

    I don’t understand this question, because RenderPartial is what you use to render MVC View User Controls. There aren’t two options to choose from – they’re both the same thing.

  33. Oren Ben-Kiki

    Hmmm… In our application, we have stuff like a game page that also contains an embedded user box (avatar, name etc.). The two are, as you said, mostly independent and there really is no reason not to use RenderAction for such usage – IMVHO anyway, but I think you’d agree.

    What I don’t get is the claim that calling RenderAction does not “retain all the business logic in the controllers”. It seems to me to be quite the opposite. The view reaches a point where it *can’t* simply render the data it was given; basically, it lacks the data (as in my example – the game page has no concept of what a user is, but the avatar partial view does). At this point it “gives up” and calls a *controller* to do the work for it – fetch the necessary data, and even choose the nested view to use to display it.

    All the business logic is still encapsulated inside controllers. True, the name of the nested control is hard-wired into the view, but then *something* has to be hard-wired there (in your example, the name was “latestPosts” – lets call it the “widget name”).

    It seems to me that the *real* question is not whether the logic is in the view or the controller, but *which* controller it resides in. Using RenderAction, the logic is distributed – it resides in the ControlFactory, of course, and also inside the actions of the concrete controls. Using PartialRequest or sub-controllers, (some) logic is concentrated in the top-level controller.

    So first, I would have liked to see the issue presented in this way. It makes a hell of a lot more sense phrased in these terms than saying RenderAction “mixes business logic in the view”, which clearly (IMO) it does not. Unless I am missing something really basic that is ;-)

    Having re-phrased the issue… I would like to see some compelling example of why the complexity of *another* mapping layer is justified.

    It seems to me that if you want to concentrate your logic in the top-level controller, go ahead, and as a result pass a “larger” model to the view to render as it sees fit (using RenderPartial for modularity).

    If, on the other hand, you want to distribute your logic, well… that’s what RenderAction already does for you, placing it in each of the invoked controllers. And you can mess with the ControllFactory to flexibly map names to concrete implementation if you need to.

    Perhaps there is a large class of applications for which there is a middle ground that justifies PartialRequest or even (shudder) sub-controllers, but I can’t think of any example off the top of my head. Is this one of the cases where you need to have a large application to justify the architecture? I tend to be suspicious of these ;-)

    P.S. You are right of course about RenderPartial and user controls… I am still a bit unclear about the difference between an ascx and an aspx-without-master-page in the context of the MVC framework. Like I said, I’m a new comer to this framework.

  34. Steve

    @Oren

    A realistic example of when you’d benefit from using PartialRequest: If you’re rendering a series of widgets that are chosen dynamically (similar to “web parts” that can be selected and arranged by the end user) then you’d want to keep the logic of selecting those widgets in the controller, and not hard-code a particular set or order in a view template.

    But for more normal cases where you’re just rendering one or two specific widgets, I’d say you might as well go with RenderAction. The only reason I provided PartialRequest was to give a simpler alternative to subcontrollers. I don’t personally have a problem with RenderAction when the widget’s concern is independent of the host page.

  35. Oren Ben-Kiki

    You mean something like the customized Google home page? This would be pretty rare… also, in such a case I would simply create a “model” that contained the names of the widgets (== controllers) to invoke, and create a view that called RenderAction with the controller name coming from the view. It seems like a more natural and direct expression of what is being done, and requires no special extensions.

    Of course, I suppose at this point some MVC purists would have a collective fit (a model that contains the names of controllers?!?!) but I would be willing to defend the premise this is exactly the “right” way to model the Google customized home page.

    At any rate, thanks for helping me think through this. I now have a much better grasp of the trade-offs involved. I may even discover cases where PartialRequests make sense to me :-) I definitely prefer them to sub-controllers, which I see as a serious overkill.

    Speaking of which, any chance that PartialRequest will make it into MvcContrib? I’d hate the “default” option to be sub-controllers, just because “they are already there”…

  36. how can i use to my areas/groups
    The controller name ‘Home’ is ambiguous between the following types:
    YFF.Areas.Blogs.Controllers.HomeController
    YFF.Controllers.HomeController
    YFF.Areas.Forums.Controllers.HomeController
    YFF.Areas.Articles.Controllers.HomeController

  37. I’ve been using the Areas(http://haacked.com/archive/2008/11/04/areas-in-aspnetmvc.aspx), I would now like to add Partial Requests

  38. Steve

    @Death – aha, I see. It’s tricky for PartialRequest to work neatly with the Areas demo, because the whole DataTokens["Namespaces"] design relies on each request starting with a URL to be parsed, whereas a PartialRequest enters the pipeline later than that.

    One solution is to add an optional “PreferredNamespace” parameter to PartialRequest:

    public class PartialRequest
    {
        public RouteValueDictionary RouteValues { get; private set; }
        public string PreferredNamespace { get; set; }

        public PartialRequest(object routeValues)
        {
            RouteValues = new RouteValueDictionary(routeValues);
        }

        public void Invoke(ControllerContext context)
        {
            RouteData rd = new RouteData(context.RouteData.Route, context.RouteData.RouteHandler);
            foreach (var pair in RouteValues)
                rd.Values.Add(pair.Key, pair.Value);
            if(!string.IsNullOrEmpty(PreferredNamespace))
                rd.DataTokens.Add(“Namespaces”, new[] { PreferredNamespace });
            IHttpHandler handler = new MvcHandler(new RequestContext(context.HttpContext, rd));
            handler.ProcessRequest(System.Web.HttpContext.Current);
        }
    }

    Then you can tell it what namespace to find the controller in when you construct the PartialRequest object:

    ViewData["myPartial"] = new PartialRequest(new { controller = ”Home”, action = ”SomeWidget” }) 
                            { PreferredNamespace = ”AreasDemo.Controllers” };

    Of course, for your own application, you might want to create special helper methods for creating PartialRequest objects for specific widgets, thereby avoiding the need to hard-code namespaces all around your app.

  39. Hi steve I had followed your steps to make this PartialRequest work, but all run well except that it did not execute the action. need more configures? may I missing something? Yes, I had gotten the request object and fire the invoke method but the action not fire.

  40. Steve

    @Baldwin – I’m sorry but I don’t know how to help you, because I can’t see your application and therefore can’t guess what the problem might be. Have you tried using the Visual Studio debugger to figure out what’s happening?

  41. Rich Urwin

    Hi Steve, This is great; it’s exactly what I need to be able to render different UserControl contents inside a template UserControl. My only question is – how does one render a UserControl instead of a Page from a Controller Action?

    Thanks,
    Rich

  42. Steve

    @Rich – if you just want a view template to render an MVC View User Control directly (a.k.a. a partial view) then just use Html.RenderPartial().

    If you want to pass control to a different action method that can then render its choice of partial view, use PartialRequest and invoke an action that renders a partial view, i.e.

    return View(“NameOfPartialView”);

  43. Rich Urwin

    @Steve,

    I have a TemplateUserContriol (which basically renders a table with nice rounded corners) and I want to display various different UserControl contents inside this. I don’t want to create one TemplateUserControl for each with the name of the control whose contents is to render inside (not very DRY!) So I think I need RenderPartial.

    I could let the Action choose what to display, or I could pass the name of ther partial to render as a parameter when calling RenderPartial on the TemplateUserControl in order that the TemplateUserControl can render the correct Partial pased in via the ViewData. Is this a bit hacky?

    Rich

  44. Steve

    @Rich – as you hint, there are many possible ways to approach this. It’s up to you to choose what you think works best in your app. Here are a couple more options:

    (1) Just use RenderPartial(), passing the name of the child partial for it to render:

    < % Html.RenderPartial("MyRoundedCornersContainer", (object)"NameOfChildPartial"); %>

    Now, “NameOfChildPartial” will be available to the rounded corners partial as ViewData.Model. This avoids complicating the MVC pipeline with partial requests.

    (2) Keep the rounded corners thing independent of the child partial that it hosts. Split it into “top” and “bottom” segments and render thus:

    < % Html.RenderPartial("RoundedCornersTop", "Title"); %>
    < % Html.RenderPartial("ChildPartial"); %>
    < % Html.RenderPartial("RoundedCornersBottom"); %>

    Low-tech but very straightforward!

  45. Rich Urwin

    @Steve: Excellent – thanks. I’ll have a think about what works best.

  46. Pingback: Sub-Controllers, PartialRequests and Separating Views From Controllers « Giraffe: Developer

  47. Have u checked it is working with RC1 as i think i am getting platformNotSupported Exception which means it is having issue with RC1

  48. Herne

    I can’t seem to get this working post rc0 – I get: “Server cannot append header after HTTP headers have been sent.” on the handler.ProcessRequest(HttpContext.Current) line.

    I think it’s perhaps because I’m calling it from a view.

  49. Steve

    @Usman, @Herne – I’ll check this out as soon as I get time.

  50. Herne

    Thanks Steve, it’s appreciated. :o )

  51. Herne

    I’ve changed the last line of PartialRequest.Invoke to

    SimpleWorkerRequest request = new SimpleWorkerRequest(“dummy.html”, null, new StringWriter(CultureInfo.CurrentCulture));
    handler.ProcessRequest(new HttpContext(request));

    and everything seems to be working again.

  52. Maurits

    I am using the refresh of RC1 and did not have to change anything to get this to work.

    What I did do was add a generic version of PartialRequest so that I can do:
    var partial = new PartialRequest(c => c.Index());

    public class PartialRequest : PartialRequest where TController : Controller
    {
    public PartialRequest(Expression<Action> action)
    : base(ExpressionHelper.GetRouteValuesFromExpression(action))
    {
    }
    }

    I also needed to add an extra constructor to the non-generic PartialRequest:

    public PartialRequest(RouteValueDictionary routeValueDictionary)
    {
    RouteValues = routeValueDictionary;
    }

    The generic constructor depends on ExpressionHelper, which is part of the MVC Futures dll.

  53. Steve

    @Herne, @Maurits – thanks for checking that out!

  54. mantra

    I may be missing something obvious but is their anyway I can use this partial request to get the output as a string ?

  55. Steve

    @mantra – No, that’s not one of the things that this does. However, if you inspect the source code for my output caching filter, you’ll see a way of doing that. http://blog.codeville.net/2008/10/15/partial-output-caching-in-aspnet-mvc/

  56. Rajeshu

    Excellent post!!!!

  57. Great read Steve. Thanks for taking the time to help out those that can’t figure it out for ourselves ;)

  58. Mr Anonymous

    does not works in widget.

    Maybe something else is wrong.

  59. Mr Anonymous

    Worpress ate my braces in previous post.

    Anyway – i mean Html.ActionLink(…

  60. Mr Anonymous

    nevermind… just still uncomfortable with routing.

  61. Bryan

    @Steve – you say in your post that with the partial view, you can populate its own ViewData. How would you go about doing this? Where is this done at? Also, you say when you attach a widget to your output, you put a partial request in the ViewData; where would this be performed at? Love it, thanks.

  62. Gadi

    Steve & other contributors – Great read!

    I still seam missing how to, say, nest this approach.

    I have a task at hands: My view’s getting some object which contains collection of items. I need to render these items based on their type – text field, text area, dropdown etc.

    I’d like not to analyze item’s type in a view. Well, of course I can use something like that (Html.Display being HtmlHelper extension calling correspondent RenderAction):

    But I’d like to get read of the loop completely, and have something like

    How can I distribute logic and combine partial requests?
    Thanks.

  63. Gadi

    it looks like I need to repeat this part:

    I have a task at hands: My view’s getting some object which contains collection of items. I need to render these items based on their type – text field, text area, dropdown etc.

    I’d like not to analyze item’s type in a view. Well, of course I can use something like that (Html.Display being HtmlHelper extension calling correspondent RenderAction):

    foreach (var field in Model.Fields)
    {
    Html.Display(field);
    }

    But I’d like to get read of the loop completely, and have something like

    =Html.Encode(Model.Display())

    How can I distribute logic and combine partial requests?
    Thanks.

  64. Gadi

    Sorry for overposting, didn’t find how to edit post. :)

    Of course, code in my previous post must be in brackets.

  65. Jon

    I have an AJAX post that returns a JSON object with various properties. I would also like to return the HTML from a PartialResult within this JSON object. How would this work using the approach above?

  66. blu

    This is a great solution, thanks a bunch.

    I have one question though, on the line

    PartialRequest partial = html
    .ViewContext
    .ViewData
    .Eval(viewDataKey) as PartialRequest;

    I noticed when I called this on a view that was not strongly typed it worked great.

    When it got called on a View that was strongly typed the html.ViewContext.ViewData was empty. The value was actually in html.ViewData.

    I removed ViewContext from the line and all seems to work well. What was the reason for using this?

    I just want to make sure I am not setting my site up for some unforeseen error later on.

    Thanks again.

  67. @blu – you can use Html.ViewData now. The only reason I used Html.ViewContext.ViewData was that this blog post was originally written for an older preview release of ASP.NET MVC which required that.

  68. Hi Steve.

    Really great article. I am just getting in to MVC and the first real problem I came across is how to deal with the ‘rich’ screen my clients often ask for so was looking for a way to do composition with control type elements. Your site was the first one I came across and I looked at several others but after doing a but after a bit of reading elsewhere I came back and am going to be trying out your code because of the lightweight nature.

    Many thanks!

  69. Ta Duc

    Hello, nice to see your post, consider the time of this post was last year, i want to ask for some trouble when i go through this tutorial.

    i’ve created the 2 helper above, but however when i try to access Html helper class, i can’t reach the PartialRequest method.

    It’s the best if you can show us some example thorugh a tiny example project. im using MVC 2.0 Preview 1. ASP.net 3.5

    Thanks

  70. Ta Duc

    Additional details: the function work fine in the fist method, but not with Html helper.

  71. thang dao

    very good.
    Howto Ajax in Partial Request in asp.net MVC. Thanks

  72. BillB

    (How does he DO that?!?) Nice stuff here.
    Steve;
    I’m wondering why this wasn’t in your excellent book, maybe as a 6th way to “add dynamic content to a view template” in Chapter 10. Maybe you just didn’t want to get into it.

    Thanks,
    Bill

  73. Andrej Kaurin

    What I need to do is the following

    1. Set some form (or any partial view)
    2. Clic submit button and do some action
    3. Get back to the SAME place (controller/action) user was before clicking LOGIN button

    Any of Partial Request/Subcontroller,RenderAction solutions offer this without any extra code to handle parent page url?

  74. Andrej Kaurin

    Typo
    3. Get back to the SAME place (controller/action) user was before clicking FORM button

  75. Is there any way you could post the sample you created. I am missing something and always get an object reference not set.

    Thank you

  76. Roberto

    Wonderful solution.

    But, if I need that “partial rendered area” accepts user interaction (actionlinks, submits and so on)

    what could be the best way to implement it?

    currently, an actionlink in the partial rendered area redirect the user on a page that only contains herself or the actionlink’s result view.

  77. @Steve / @Roberto,

    I ran into the same problem. Seems the ViewContext changes. Is there a way of passing through the original context?

    My specific problem is that BuildUrlFromExpression no longer works correctly.

    Rich

  78. bobthecoder

    Thanks Steve. Enjoying your book a lot. This solution worked great for me and resolved the headache I was having due to the paradigm shift from ASP.NET to MVC.

  79. Pingback: MVC Partial Rendering | Alper Konuralp'in Blog Sitesi

  80. vishal patwardhan

    Hi Steve, I implement the second option for partials but not able to implement the first one, I did the following

    1)I put the given class somewhere in project.
    2)Create a action which will render a widget in associated controller.
    3)and associated view contains that
    but still this not working can u send me the sample project for this.
    Thanks

  81. Hi Steve,
    I’m a novice in terms of MVC, can you please advise the syntax required to pass parameters into the PartialRequest?
    I’ve tried various things like
    ViewData["GetTheMasksForFV"] = new PartialRequest(new
    {
    controller = “Home”,
    action = “GetTheMasksForFV”,
    id = “featureValueID = 1″
    });
    but always get the same error “The parameters dictionary contains a null entry for parameter ‘featureValueID’”

    Thanks.

  82. Music began playing as soon as I opened up this web-site, so irritating!

  83. Prasanna

    Has anyone made this work with razorviewengine?

  84. wheel hub

    Excellent Post.. I enjoy some of content in the post.. please keep it up..
    i want same like this from you… thanks

  85. Hello and thank you for your post. I have tested it with asp.net mv3 and razor and it really does another request to render the partial view.

    The problem is the partialrequest is executed before the main request, so I end up with an html like like:

    of course i could use a bit of css and js to organize everything, but i believe doing that we would miss the whole point, since I could just use ajax for the same behaviour and get my main view rendered faster.

    Is there a way to perform the partial request and embed its content within the main request?

  86. I wanted to post you that little bit of remark just to thank you once again for the splendid solutions you’ve discussed on this site. It is so open-handed of you to present unreservedly all that a few people could have made available for an e book in making some bucks on their own, specifically now that you might have done it in case you desired. Those ideas in addition served to provide a good way to fully grasp that other people have similar eagerness the same as mine to grasp significantly more with reference to this problem. Certainly there are many more enjoyable occasions in the future for many who discover your blog post.

  87. Ian

    I get the following compliation error when trying this is MVC 3.0…. any ideas

    Compiler Error Message: CS1502: The best overloaded method match for ‘System.Web.WebPages.WebPageExecutingBase.Write(System.Web.WebPages.HelperResult)’ has some invalid arguments

    Source Error:

    Line 5:
    Line 6: @Model.PageTitle
    Line 7: @Html.RenderPartialRequest(“Slider”);

  88. dani

    Excellent post, that solve a lot of time for me and is clear and working solution. Just add the two points: _originalWriter should be returned in null if cache had been invalidated, becouse we check it in onResultExecuted

    if (cachedOutput != null)
    {
    filterContext.Result = new ContentResult { Content = cachedOutput };
    _originalWriter = null;
    }

    and update to cachekey forming function:

    if (pair.Value.GetType() != typeof(DictionaryValueProvider))
    keyBuilder.AppendFormat(“rd{0}_{1}_”, pair.Key.GetHashCode(), pair.Value == null ? 0 : pair.Value.GetHashCode());

    it handle nullable params and RenderAction with RouteValueDictionary instead of anonymous type

  89. dani

    sorry, i miss with topic=)))

  90. kami

    Is one possible drawback of this that it doesn’t work with the ChildActionOnlyAttribute? I have a number of actions decorated with it that can’t be called via partial requests. I get “Error executing child request for handler.” I want to insulate those actions from web. Thanks.

  91. You will find already been following on from the blog site for a thirty days approximately and have picked up a lot of data and adored the process you’ve organised your internet site. I am looking to work my own extremely private blog site however. I do believe its also basic and that i should give attention to a great deal of smaller subjects. Being as much as possible to everyone folks isn’t everything that it’s chipped approximately be.