1. ホーム
  2. c#

[解決済み] MVC 3:ajax経由でロードされたときに、そのレイアウトページなしでビューをレンダリングするにはどうすればよいですか?

2022-04-27 20:16:17

質問

について学んでいます。 プログレッシブ・エンハンスメント で、ビューのAJAX化について質問があります。私のMVC 3プロジェクトでは、レイアウトページ、ビュースタートページ、および2つのプレーンなビューがあります。

viewstart ページは Views フォルダのルートにあり、したがってすべてのビューに適用されます。このページでは、すべてのビューで _Layout.cshtml をレイアウトページに使用します。レイアウトページには2つのナビゲーションリンクがあり、各ビューに1つずつあります。リンクは @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>

これには2つの方法が考えられますが、私はどちらも特に好きではありません。

1) ビュー全体のコンテンツを部分ビューに配置し、メインビューがレンダリングされるときに部分ビューを呼び出すようにすることができます。この方法では Request.IsAjaxRequest() をコントローラの中で返すことができます。 View() または PartialView() は、リクエストがAjaxリクエストであるかどうかに基づいています。Ajaxリクエストに通常のビューを返すことはできません。そうすると、レイアウトページを使うことになり、レイアウトページの2番目のコピーが注入されるからです。しかし、これでは、単に @{Html.RenderPartial();} を、標準的なGETリクエストのために使用します。

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

そして、Index.cshtmlでは次のようにしてください。

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

2) Ajaxでない場合は、_viewstartからレイアウト指定を外し、手動で指定することができますね。

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

どなたか、もっと良いご提案はありませんか?レイアウトページのないビューを返す方法はないでしょうか?それがajaxリクエストである場合、それがajaxでない場合、レイアウトを明示的に含めることよりも、"don't include your layout"と明示的に言う方がずっと簡単でしょう。

解決方法は?

~/Views/ViewStart.cshtml :

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

とコントローラの中にあります。

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