MVC 3:Ajax経由で読み込まれたときに、レイアウトページなしでビューをレンダリングする方法


153

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

viewstartページはViewsフォルダーのルートにあるため、すべてのビューに適用されます。すべてのビューが_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リクエストに通常のビューを返すことはできません。それは、レイアウトページを使用し、レイアウトページの2番目のコピーが挿入されるためです。ただし、@{Html.RenderPartial();}標準のGETリクエストでは、aのみを含む空のビューを作成する必要があるため、これは好きではありません。

    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でない場合、明示的にレイアウトを含めるよりもはるかに簡単です。

回答:


259

~/Views/ViewStart.cshtml

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

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

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

3
これはビュースタートで指定できますか?
Chev

10
@マットグリーア、あなたはそれを厄介だと呼んでいます、私はとにかくそれをDRY、主観的なものと呼んでいます:-)
Darin Dimitrov

2
認めざるを得ませんでしたが、最初は気に入らなかったのですが、節約できるコードの量はマイナス面をはるかに上回っているように思えます。IMOをあまり課さない場合は、単純なブール値です。私は自分の行動方法を毎回半分に切るよりも好きです。それに加えて、マットが言ったことを実行できず、アクションメソッドで2つの巨大なロジックパスをたどることができなくなります。どちらの場合でも同じように動作するようにアクションを記述するか、新しいアクションを記述します。
Chev

1
これをベースコントローラで実行し、ViewDataでプロパティを設定してそれを使用することはできませんか?次に、行になりますLayout = ViewBag.LayoutFile
RPM1984

2
できると思いますが、実際にはなぜ1つの小さな行のbaseControllerを作成するのでしょうか。
Chev

92

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

@{
    Layout = "";
}

4
AJAX経由でリクエストされたかどうかに基づいてレイアウトのオンとオフを切り替えられるようにしたいので、これは機能しません。これは、レイアウトをオフにすることのみが可能で、切り替えはできません。
Chev、

4
なぜこれは賛成投票ですか?plsが説明するので、私も投票します。
Usman Younas 2013年

1
@UsmanY。投票する必要はありません。でもやるよ。私の議論はgoogle.com.pk/#q=mvc3%20view%20without%20layoutに移動します。そして、それはその質問に対する完全な答えです。
2013年

3
トピックは、2つの異なるシナリオでレイアウトを切り替えることです。この答えは、シナリオが何であっても、レイアウトを空に設定するだけです。
Rajshekar Reddy 2013

おい、これは動作し、それは本当に素晴らしいです。私が使用するシナリオ:許可されていないユーザーがログインを試みます。エラーページにリンクなどが表示されて、許可されていないユーザーに表示されるのは望ましくありません。もちろん、それは他のすべてにも有効です!
JosephDoggie、2014年

13

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

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

多くの人々は、アクションの呼び出しパスをRequest.IsAjaxRequest()で断片化することを嫌っています。しかし、IMO、コールするかどうかを決定するあなたがやっているすべてがされている場合View()PartialView()、その後分岐はたいしたものではありませんし、維持しやすい(とテスト)です。IsAjaxRequest()アクションの再生方法の大部分を決定するのに使用している場合は、個別のAJAXアクションを作成することをお勧めします。


13

2つのレイアウトを作成します。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では、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


-5

Ruby on Railsアプリケーションの場合、render layout: falseajax htmlで応答したいコントローラーアクションを指定することで、レイアウトが読み込まれないようにすることができました 。


6
タグ:ルビーではなく、c#asp.net
MrKekson
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.