web-dev-qa-db-ja.com

MVC 3:ajax経由でロードされたときに、レイアウトページなしでビューをレンダリングする方法

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

ビュースタートページはビューフォルダのルートにあるため、すべてのビューに適用されます。すべてのビューがレイアウトページに_Layout.cshtmlを使用する必要があることを指定します。レイアウトページには、各ビューに1つずつ、合計2つのナビゲーションリンクが含まれています。リンクは@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()を使用して、リクエストがAjaxリクエストであるかどうかに基づいてView()を返すか、PartialView()を返すことができます。 Ajaxリクエストに通常のビューを返すことはできません。Ajaxリクエストではレイアウトページが使用され、レイアウトページの2番目のコピーが挿入されるためです。ただし、標準のGETリクエストに対して@{Html.RenderPartial();}のみを使用して空のビューを作成する必要があるため、これは好きではありません。

    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.
    }

誰かより良い提案がありますか?レイアウトページなしでビューを返す方法はありますか? ajaxリクエストである場合、「レイアウトを含めない」と明示的に言う方が、ajaxでない場合、レイアウトを明示的に含めるよりもはるかに簡単です。

152
Chev

~/Views/ViewStart.cshtmlで:

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

そしてコントローラーで:

public ActionResult Index()
{
    return View();
}
252
Darin Dimitrov

次のコードをページの上部に配置するだけです

@{
    Layout = "";
}
89
roncansan

私はあなたの#1オプションを好み、使用します。私にとってView()はページ全体を返すことを意味するため、私は#2が好きではありません。ビューエンジンで処理が完了すると、完全に肉付けされた有効なHTMLページになります。 PartialView()は、HTMLの任意のチャンクを返すために作成されました。

パーシャルを単に呼び出すビューを持つことは大したことではないと思います。まだDRYであり、2つのシナリオでパーシャルのロジックを使用できます。

多くの人は、アクションの呼び出しパスをRequest.IsAjaxRequest()で断片化することを嫌います。しかし、IMOでは、View()またはPartialView()を呼び出すかどうかを決定するだけであれば、ブランチは大したことではなく、保守(およびテスト)が簡単です。 IsAjaxRequest()を使用してアクションの大部分を判断している場合は、別のAJAXアクションを作成することをお勧めします。

13
Matt Greer

2つのレイアウトを作成します。1。空のレイアウト、2。メインレイアウトを作成し、_viewStartファイルに次のコードを記述します。

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

もちろん、おそらくそれは最善の解決策ではありません

13
Arash Karami

このために空のビューを作成する必要はありません。

コントローラー内:

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

partialViewResultを返すと、応答をレンダリングするときにレイアウト定義がオーバーライドされます。

7
Souhaieb Besbes

ASP.NET 5では、Request変数は使用できなくなりました。 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

1
Drotak