MVC 3: How to render a view without its layout pag

2019-01-08 03:29发布

I am learning about Progressive Enhancement and I have a question about AJAXifying views. In my MVC 3 project I have a layout page, a viewstart page, and two plain views.

The viewstart page is in the root of the Views folder and thus applies to all views. It specifies that all views should use _Layout.cshtml for their layout page. The layout page contains two navigation links, one for each view. The links use @Html.ActionLink() to render themselves to the page.

Now I have added jQuery and want to hijack these links and use Ajax to load their content on the page dynamically.

<script type="text/javascript">
    $(function () {
        $('#theLink').click(function () {
            $.ajax({
                url: $(this).attr('href'),
                type: "GET",
                success: function (response) {
                    $('#mainContent').html(response);
                }
            });
            return false;
        });
    });
</script>

There are two ways I can think of to do this, but I don't particularly like either one:

1) I can take the entire View's contents and place them in a partial view, then have the main view call the partial view when it is rendered. That way, using Request.IsAjaxRequest() in the controller, I can return View() or return PartialView() based on whether or not the request is an Ajax request. I can't return the regular view to the Ajax request because then it would use the layout page and I'd get a second copy of the layout page injected. However, I don't like this because it forces me to create empty views with just a @{Html.RenderPartial();} in them for the standard GET requests.

    public ActionResult Index()
    {
        if (Request.IsAjaxRequest())
            return PartialView("partialView");
        else
            return View();
    }

Then in Index.cshtml do this:

@{Html.RenderPartial("partialView");}

2) I can remove the layout designation from _viewstart and specify it manually when the request is NOT Ajax:

    public ActionResult Index()
    {
        if (Request.IsAjaxRequest())
            return View(); // Return view with no master.
        else
            return View("Index", "_Layout"); // Return view with master.
    }

Does anyone have a better suggestion? Is there a way to return a view without its layout page? It would be much easier to explicitly say "don't include your layout" if it is an ajax request, than it would be to explicitly include the layout if it's not an ajax.

6条回答
兄弟一词,经得起流年.
2楼-- · 2019-01-08 03:52

In ~/Views/ViewStart.cshtml:

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

and in the controller:

public ActionResult Index()
{
    return View();
}
查看更多
淡お忘
3楼-- · 2019-01-08 03:57

Just put the following code on the top of the page

@{
    Layout = "";
}
查看更多
姐就是有狂的资本
4楼-- · 2019-01-08 04:11

For a Ruby on Rails application, I was able to prevent a layout from loading by specifying render layout: false in the controller action that I wanted to respond with ajax html.

查看更多
贪生不怕死
5楼-- · 2019-01-08 04:14

Create two layout: 1. empty layout, 2 . main layout and then write in _viewStart file this code:

@{
if (Request.IsAjaxRequest())
{
    Layout = "~/Areas/Dashboard/Views/Shared/_emptyLayout.cshtml";
}
else
{
    Layout = "~/Areas/Dashboard/Views/Shared/_Layout.cshtml";
}}

of course, maybe it is not best solution

查看更多
一纸荒年 Trace。
6楼-- · 2019-01-08 04:15

I prefer, and use, your #1 option. I don't like #2 because to me View() implies you are returning an entire page. It should be a fully fleshed out and valid HTML page once the view engine is done with it. PartialView() was created to return arbitrary chunks of HTML.

I don't think it's a big deal to have a view that just calls a partial. It's still DRY, and allows you to use the logic of the partial in two scenarios.

Many people dislike fragmenting their action's call paths with Request.IsAjaxRequest(), and I can appreciate that. But IMO, if all you are doing is deciding whether to call View() or PartialView() then the branch is not a big deal and is easy to maintain (and test). If you find yourself using IsAjaxRequest() to determine large portions of how your action plays out, then making a separate AJAX action is probably better.

查看更多
Root(大扎)
7楼-- · 2019-01-08 04:16

You don't have to create an empty view for this.

In the controller:

if (Request.IsAjaxRequest())
  return PartialView();
else
  return View();

returning a PartialViewResult will override the layout definition when rendering the respons.

查看更多
登录 后发表回答