MVC 3: Ajax ile yüklendiğinde bir görünüm, yerleşim sayfası olmadan nasıl oluşturulur?


153

Ben yaklaşık öğreniyorum Aşamalı Enhancement ve ben AJAXifying görünümler hakkında bir sorum var. MVC 3 projemde bir düzen sayfası, bir görünüm başlatma sayfası ve iki düz görünüm var.

Viewstart sayfası Views klasörünün kökündedir ve bu nedenle tüm görünümler için geçerlidir. Tüm görünümlerin _Layout.cshtmlmizanpaj sayfaları için kullanılması gerektiğini belirtir . Düzen sayfası, her görünüm için bir tane olmak üzere iki gezinme bağlantısı içerir. Bağlantılar @Html.ActionLink()kendilerini sayfaya dönüştürmek için kullanır .

Şimdi jQuery ekledim ve bu bağlantıları kaçırmak ve dinamik olarak sayfadaki içeriğini yüklemek için Ajax kullanmak istiyorum.

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

Bunu yapmanın iki yolu var, ama ikisini de sevmiyorum:

1) Tüm Görünüm'ün içeriğini alıp kısmi bir görünüme yerleştirebilirim, daha sonra ana görünüm oluşturulduğunda kısmi görünümü çağırabilirim. Bu şekilde, Request.IsAjaxRequest()denetleyicide kullanarak , isteğin bir Ajax isteği olup olmamasına bağlı olarak View()geri dönebilir veya geri dönebilirim PartialView(). Ajax isteğine normal görünümü geri veremem çünkü düzen sayfasını kullanır ve düzen sayfasının ikinci bir kopyasını alırım. Ancak, bunu sevmiyorum çünkü beni @{Html.RenderPartial();}standart GET istekleri için bunlarla bir boş görünüm oluşturmaya zorluyor .

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

Sonra Index.cshtml dosyasında şunları yapın:

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

2) Düzen atamasını _viewstart öğesinden kaldırabilir ve istek Ajax DEĞİL olduğunda manuel olarak belirtebilirim:

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

Daha iyi bir öneri olan var mı? Düzen sayfası olmadan bir görünüm döndürmenin bir yolu var mı? Eğer bir ajax isteği ise açıkça "mizanpajınızı dahil etmeyin" demek çok daha kolay olurdu, mesela ajax değilse mizanpajı dahil etmek daha kolay olacaktır.

Yanıtlar:


259

İçinde ~/Views/ViewStart.cshtml:

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

ve denetleyicide:

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

3
Bu görünüm başlangıcında belirtilebilir mi?
Chev

10
@Matt Greer, sen buna kötü diyorsun, ben buna KURU, sübjektif şeyler derim :-)
Darin Dimitrov

2
İtiraf etmeliyim, ilk başta beğenmedim, ancak kaydettiği kodun miktarı çok zayıf gibi görünüyor. Çok fazla IMO dayatmıyorsa basit bir boole. Aksiyon yöntemlerimi her seferinde ikiye ayırmaktan daha çok hoşlanıyorum. Ayrıca, Matt dediğini yapmama ve potansiyel olarak eylem yönteminde iki dev mantık yoluna inmeme engel oluyor. Her iki durumda da aynı şekilde çalışmak için eylemi yazıyorum veya yeni bir eylem yazıyorum.
Chev

1
bunu bir temel denetleyicide yapamadınız, ViewData'da bir özellik ayarlayıp kullanamaz mısınız? Sonra hat olurdu Layout = ViewBag.LayoutFile.
RPM1984

2
Sanırım yapabildim, ama gerçekten neden küçük bir çizgi için bir baseController oluşturun?
Chev

92

Aşağıdaki kodu sayfanın üstüne koymanız yeterlidir

@{
    Layout = "";
}

4
AJAX aracılığıyla talep edilip edilmediğine bağlı olarak düzeni açıp kapatabilmek istediğim için bu çalışmıyor. Bu yalnızca düzeni kapatmanıza izin verir, değiştirmez.
Chev

4
Neden bu oy var? pls açıklamak böylece ben de oy.
Usman Younas

1
@UsmanY. Oy vermenize gerek yok. Ama ben yaparım. Benim tartışmam google.com.pk/#q=mvc3%20view%20without%20layout adresine gidin . Ve bu sorguya mükemmel bir cevap.
Sami

3
Konu, iki farklı senaryoda düzeni değiştirmekle ilgilidir. Bu cevap, senaryo ne olursa olsun, yerleşimi boşaltacak şekilde ayarlar.
Rajshekar Reddy

Dostum, bu işe yarıyor ve gerçekten çok güzel. Kullandığım senaryo: Yetkisiz kullanıcı giriş yapmaya çalışıyor, hata sayfasının yetkisiz bir kullanıcıya bağlantı göstermesini istemiyor! Tabii ki, her şey için de çalışır!
JosephDoggie

13

# 1 seçeneğinizi tercih ediyorum ve kullanıyorum. # 2'yi sevmiyorum çünkü bana göre View()sayfanın tamamını iade ediyorsun. Görüntüleme motoru onunla yapıldığında tamamen etli ve geçerli bir HTML sayfası olmalıdır. PartialView()HTML'nin rastgele parçalarını döndürmek için oluşturuldu.

Kısmi diyen bir görüşe sahip olmanın çok önemli olduğunu sanmıyorum. Hala KURU ve kısmi mantığını iki senaryoda kullanmanızı sağlar.

Birçok insan eylemlerinin çağrı yollarını parçalamaktan hoşlanmaz Request.IsAjaxRequest()ve bunu takdir edebilirim. Ancak IMO, yaptığınız tek şey aramaya karar vermek View()veya PartialView()daha sonra şubenin büyük bir anlaşma olmadığı ve bakımı (ve test edilmesi) kolay olmasıdır. Kendinizi IsAjaxRequest()eyleminizin nasıl oynandığının büyük bölümlerini belirlemek için kullanırsanız , ayrı bir AJAX eylemi yapmak muhtemelen daha iyidir.


13

İki düzen oluşturun: 1. boş düzen, 2. ana düzeni seçin ve _viewStart dosyasına şu kodu yazın:

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

Tabii ki, belki de en iyi çözüm değildir


8

Bunun için boş bir görünüm oluşturmanız gerekmez.

Denetleyicide:

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

bir PartialViewResult döndürmek, yanıtı oluştururken mizanpaj tanımını geçersiz kılar.


2

ASP.NET 5 ile artık bir İstek değişkeni mevcut değildir. Artık Context.Request ile erişebilirsiniz.

Ayrıca artık IsAjaxRequest () yöntemi yoktur, kendiniz yazmak zorundasınız, örneğin 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");
        }
    }
}

Şimdi bu konuda bir süre aradım ve umarım bazı diğerlerine de yardımcı olur;)

Kaynak: https://github.com/aspnet/AspNetCore/issues/2729


-5

Ruby on Rails uygulaması için, render layout: falseajax html ile yanıt vermek istediğim denetleyici eyleminde belirterek bir mizanpajın yüklenmesini engelleyebildim .


6
Etiketler: c # asp.net, yakut değil
MrKekson
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.