MVC 3 : Ajax를 통해로드 될 때 레이아웃 페이지없이 뷰를 렌더링하는 방법?


153

점진적 향상 에 대해 배우고 있으며 AJAXifying보기에 대한 질문이 있습니다. 내 MVC 3 프로젝트에는 레이아웃 페이지, 뷰 시작 페이지 및 두 개의 일반 뷰가 있습니다.

viewstart 페이지는 Views 폴더의 루트에 있으므로 모든보기에 적용됩니다. 모든 뷰가 _Layout.cshtml해당 레이아웃 페이지에 사용되도록 지정합니다 . 레이아웃 페이지에는 각보기마다 하나씩 두 개의 탐색 링크가 있습니다. 링크 @Html.ActionLink()는 페이지에 자신을 렌더링하는 데 사용 됩니다.

이제 jQuery를 추가하고 이러한 링크를 가로 채고 Ajax를 사용하여 해당 컨텐츠를 페이지에 동적으로로드하려고합니다.

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

이 작업을 수행 할 수있는 두 가지 방법이 있지만 특히 두 가지 중 하나를 좋아하지 않습니다.

1) 전체보기의 내용을 가져 와서 부분보기에 배치 한 다음 기본보기가 렌더링 될 때 부분보기를 호출하도록 할 수 있습니다. 그렇게 Request.IsAjaxRequest()하면 컨트롤러에서 사용 하여 요청이 Ajax 요청인지 여부에 따라 반환 View()하거나 반환 할 수 있습니다 PartialView(). 레이아웃 페이지를 사용하기 때문에 Ajax 요청에 일반보기를 반환 할 수 없으며 레이아웃 페이지의 두 번째 사본이 주입됩니다. 그러나 @{Html.RenderPartial();}표준 GET 요청에 대해 빈 뷰를 작성해야하기 때문에 이것을 좋아하지 않습니다 .

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

그런 다음 Index.cshtml에서 다음을 수행하십시오.

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

2) _viewstart에서 레이아웃 지정을 제거하고 요청이 Ajax가 아닌 경우 수동으로 지정할 수 있습니다.

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

더 나은 제안이 있습니까? 레이아웃 페이지없이 뷰를 반환하는 방법이 있습니까? 아약스가 아닌 경우 레이아웃을 명시 적으로 포함하는 것보다 아약스 요청 인 경우 "레이아웃을 포함하지 마십시오"라고 명시 적으로 말하는 것이 훨씬 쉽습니다.

답변:


259

에서 ~/Views/ViewStart.cshtml:

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

컨트롤러에서 :

public ActionResult Index()
{
    return View();
}

3
이것을 viewstart에서 지정할 수 있습니까?
Chev

10
@ 매트 Greer, 당신은 그것을 불쾌한이라고 부릅니다. 어쨌든 주관적인 물건이라고 부릅니다 :-)
Darin Dimitrov

2
인정해야합니다. 처음에는 마음에 들지 않았지만 저장하는 코드의 양은 단점보다 훨씬 비쌉니다. IMO를 많이 부과하지 않으면 간단한 부울입니다. 나는 매번 반마다 내 행동 방법을 자르는 것보다 낫습니다. 또한 Matt가 말한 것을 수행하고 잠재적으로 액션 방법에서 두 가지 거대한 논리 경로를 따라갈 수 없습니다. 두 경우 모두 동일하게 작동하도록 조치를 작성하거나 새 조치를 작성합니다.
Chev

1
기본 컨트롤러 에서이 작업을 수행 할 수 없으며 ViewData에서 속성을 설정하고 사용합니까? 그런 다음 줄은입니다 Layout = ViewBag.LayoutFile.
RPM1984

2
나는 할 수 있다고 생각하지만 실제로 작은 줄에 대해 baseController를 만드는 이유는 무엇입니까?
Chev

92

페이지 상단에 다음 코드를 입력하십시오.

@{
    Layout = "";
}

4
AJAX를 통한 요청 여부에 따라 레이아웃을 켜거나 끌 수 있기 때문에 작동하지 않습니다. 이렇게하면 레이아웃을 끄지 않고 끌 수 있습니다.
Chev

4
왜 이것이 투표를 했습니까 ?? pls는 내가 그것을 투표 너무 설명합니다.
Usman Younas

1
@UsmanY. 투표하지 않아도됩니다. 그러나 나는한다. 내 주장은 google.com.pk/#q=mvc3%20view%20without%20layout으로 이동합니다 . 그리고 그것은 그 질문에 대한 완벽한 대답입니다.
Sami

3
이 주제는 두 가지 시나리오에서 레이아웃을 전환하는 것입니다. 이 답변은 시나리오가 무엇이든간에 레이아웃을 비우도록 설정했습니다.
Rajshekar Reddy

야,이 작동하고 정말 좋은 것입니다. 내가 사용하는 시나리오 : 권한이없는 사용자가 로그인하려고하면 오류 페이지에 권한이없는 사용자에게 링크 등이 표시되는 것을 원하지 않습니다! 물론 다른 모든 것에서도 작동합니다!
JosephDoggie

13

나는 당신의 # 1 옵션을 선호하고 사용합니다. 나에게 View()당신이 전체 페이지를 반환한다는 것을 암시 하기 때문에 # 2를 좋아하지 않습니다 . 일단 뷰 엔진이 완성되면 완전히 완성되고 유효한 HTML 페이지 여야합니다. PartialView()임의의 HTML 청크를 반환하기 위해 만들어졌습니다.

나는 단지 부분적이라고 부르는 견해를 갖는 것이 큰 문제라고 생각하지 않습니다. 여전히 건조하며 두 가지 시나리오에서 부분의 논리를 사용할 수 있습니다.

많은 사람들이 자신의 행동 경로를 조각화하는 것을 좋아하지 않습니다 Request.IsAjaxRequest(). 그러나 IMO, 전화 여부를 결정 당신이하고있는 모든 경우 View()또는 PartialView()다음 분기는 큰 문제가되지 않습니다 및 유지 관리가 용이 (테스트)입니다. 자신 IsAjaxRequest()의 액션이 어떻게 전개되는지 결정하는 데 많이 사용한다면 별도의 AJAX 액션을 만드는 것이 좋습니다.


13

두 개의 레이아웃을 만듭니다. 1. 빈 레이아웃, 2. 메인 레이아웃 다음 _viewStart 파일에 다음 코드를 작성하십시오.

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

물론, 아마도 최선의 해결책이 아닐 수도 있습니다.


8

이를 위해 빈 뷰를 만들 필요는 없습니다.

컨트롤러에서 :

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

PartialViewResult를 반환하면 응답을 렌더링 할 때 레이아웃 정의가 재정의됩니다.


2

ASP.NET 5에서는 더 이상 사용할 수있는 요청 변수가 없습니다. Context.Request로 액세스 할 수 있습니다.

또한 더 이상 IsAjaxRequest () 메서드가 없으므로 Extensions \ HttpRequestExtensions.cs와 같이 직접 작성해야합니다.

using System;
using Microsoft.AspNetCore.Http;

namespace Microsoft.AspNetCore.Mvc
{
    public static class HttpRequestExtensions
    {
        public static bool IsAjaxRequest(this HttpRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            return (request.Headers != null) && (request.Headers["X-Requested-With"] == "XMLHttpRequest");
        }
    }
}

나는 이것에 대해 잠시 동안 검색했고 그것이 다른 사람들에게도 도움이되기를 바랍니다.)

리소스 : https://github.com/aspnet/AspNetCore/issues/2729


-5

Ruby on Rails 애플리케이션의 경우, render layout: falseajax html로 응답하려는 컨트롤러 조치를 지정하여 레이아웃이로드되지 않도록 할 수있었습니다 .


6
태그 : C # asp.net, 루비 아님
MrKekson
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.