jgauffin
jgauffin

Reputation: 101156

Automatically render a partial when the request is sent through ajax

I'm trying to figure out how I can automatically render a view as a partial (no master page) when the request is made through ajax.

What I want to avoid is to use the following code in every controller method that can return ajax (since that's not very DRY):

return Request.IsAjaxRequest() ? PartialView(model) : View(model)

My first thought was to add the check into my base controller in the View method. But the view method returns a View (which PartialView do not inherit). So that failed.

My next attempt was to try to make the check in my custom razor view engine and simple remove the master page if it's a ajax request. But that failed too.

What I can do is to create a new method ViewOrPartial which contains the check and return a result accordingly.

How would you have done it?

Upvotes: 2

Views: 1733

Answers (4)

iCollect.it Ltd
iCollect.it Ltd

Reputation: 93601

I found in practice that IsAjaxRequest is not 100% reliable.

With loads of requests from a mobile device it would occasionally return false on an Ajax call.

I wound up adding a query string parameter (e.g. partial=1) to my Ajax requests to ensure the controller was not fooled. This was around MVC 4 so may have been corrected since then, but I can't afford to take a chance.

In my base controller (inherited by all my controllers) I added this:

public bool IsPartialPageRequest
{
    get
    {
        return Request.IsAjaxRequest() || !string.IsNullOrEmpty(Request["partial"]);
    }
}

In the controllers I then have something like:

    if (!base.IsPartialPageRequest)
    {
        ViewBag.Layout = "~/Views/Shared/_Layout.cshtml";
    }

And finally in my views I have:

@{
    Layout = ViewBag.Layout;
}

I ensure I always add &partial=1 to my Ajax requests (just in case) and it has been 100% reliable since.

Upvotes: 0

Darin Dimitrov
Darin Dimitrov

Reputation: 1039130

How about putting the following:

@{
    Layout = !Request.IsAjaxRequest() ? "~/Views/Shared/_Layout.cshtml" : null;
}

in your ~/Views/_ViewStart.cshtml and in your controller action simply returning a view:

return View(model);

All razor views use _ViewStart.cshtml. This is where the master page is specified. So by making this change all views automatically will apply the master page only conditionally if the request was not an AJAX request. Pretty DRY.

Upvotes: 8

John Farrell
John Farrell

Reputation: 24754

I outline how to do this here: Simple ASP.NET MVC CRUD views opening/closing in JavaScript UI dialog

Upvotes: 0

Related Questions