2009-09-24 7 views
19

jQuery ile ASP.NET MVC kullanıyorum ve denetleyicilerime çok sayıda Ajax isteği alıyorum.Kısmi Görünümler vs Json (veya her ikisi)

Bir sayfa yüklendiğinde intial görünümü oluşturmak için Kısmi Görünümler'i (usercontrols) kullanın. Daha sonra Ajax isteğime göre veri eklemem gerekirse/değiştirmem gerekiyorsa, Json yanıtından HTML oluşturuyorum.

Bu yaklaşım bana tam kontrol sağlıyor, yani. Bir şeyler ters giderse kontrolörden ek bilgi alabilir ve buna bağlı olarak bir hata mesajı gösterebilirim.

Bununla birlikte, kısa bir süre önce hem kısmi görünümlerimde hem de Json'dan HTML üreten kısımda HTML yapısını korumaya devam eden tüm ekstra çalışmalarla gerçekten sinirlendim.

JQuery ajax istekte bulunmayı ve denetleyicinin PartialView ("mypartialview") döndürmesini ve sonra görünümünde HTML'ye geçmek için jQuery kullanmasını istiyorum. Bununla birlikte, bu yolla kontrolörden ekstra veri ekleyemiyorum - ya kısmi bakış açısı verirse vermez - ya da hiçbir şey yok. En azından şu anki benimki.

Denetleyicimin eyleminde bir noktada bazı doğrulama yanlış giderse, kısmi görünümün HTML'sini döndürmek istemiyorum.

Peki bu sorunu nasıl ele alırsınız?

Okumak için teşekkürler.

cevap

2

Oluşturulmuş html'yi bir dize olarak döndürdüğünüze inanıyorum - bu, dönüşümlü olarak görüntülenecek bir hata iletisi içeren bir html dizesi olabilir mi?

+1

Gerçekten de, bu bir PartialView yanıtıdır. Ve oldukça hecelemeseniz de, bu çözümdür: AJAX yöntemlerinizi, sayfanın o kısmını ilk başta oluşturmak için kullandığınız aynı kullanıcı denetimini kullanarak oluşturulmuş bir PartialView döndürmesini sağlayın. Bunu, Json (model) dönüşü yerine geri dönen PartialView (model) yazarak yaparsınız. –

+0

Teşekkürler. Bu gerçekten daha iyi bir açıklama :) – Paddy

+0

Craig, şu an yaptığım şey bu. Ben de diğer verilerle birlikte göndermek böylece, Json içinde sarın ardından dönüş PartialView döndü ve çıkan html istiyorum: veya başka koymak - Sorunum Html ve Json hem dönmek istiyorum olmasıdır.gibi bu adam Tür: http://stackoverflow.com/questions/1168791/returning-a-rentered-html-partial-in-a-json-property-in-asp-net-mvc sanırım Yukarıdaki işe yarayacak, ama başkalarının bunu nasıl ele aldığını bilmek isterim. – bgeek

18

this stackoverflow anwser tabanlı Ben de aynı şeyi yapmak için yola çıktım.

İlk önce denetleyici sınıfı için bir uzantı yöntemi oluşturun.

public static string RenderViewToString(this Controller controller, string viewName, object model) 
{ 
    using (var writer = new StringWriter()) 
    { 
     var viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName); 
     controller.ViewData.Model = model; 
     var viewCxt = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, writer); 
     viewCxt.View.Render(viewCxt, writer); 
     return writer.ToString(); 
    } 
} 

Daha sonra jsonu denetleyiciler eylem yöntemine döndürün.

return Json(new 
          { 
           Html = this.RenderViewToString("MyView", model), 
           SomeExtraData = data 
          }); 

Artık ajax istekleriniz json'ı içerdiği html ile alacak. Hala düz Html fragmanlarını döndürme konusunda bu yaklaşımı deneyebilirsiniz.

Bu yardımcı olur umarım. ustura İşte

4

çalışmak Güncelleme

DÜZENLEME ilgili her sonucu tarafından döndürülen Content-Type yararlanmak için bir yoldur. Geri hata bilgileri göndermek için bunu kullanıyoruz ve iletileri görüntülemek için zaten JS var, bu yüzden ya istediğimiz kısmi görünümü alıyoruz ya da hata raporlaması için bilgileri kontrol ediyoruz.

Referans için kısmi görünüm text/html ve bir JSON yanıtı application/json döndürmelidir.

Her zamanki gibi, eğlenceli bölüm javascript tarafında ve JQuery ajax() burada hayal kırıklığı yok!Kumandanızda olarak

, sadece geri dönmek ya PartialView() veya Json(model,) uygun; try/catch biçiminde kullanıyoruz.

JS tarafında, aşağıdaki işlevi kullanıyoruz. Eğer ilk sayfa düzeyinde GET $(document).ready() ortayı güzel herhangi JQuery olayları yeniden kurmak gerektiğini unutmayın, bu yüzden bir geri arama parametresi var.

function getPartialView(action, controller, model, divId, callback) { 
    var url = "/" + controller + "/" + action + "/"; 
    $.ajax({ 
     type: "GET", 
     url: url, 
     data: model, 
     success: function (data, textStatus, jqXHR) { 
      var ct = jqXHR.getResponseHeader("Content-Type"); 
      var mx = ct.match("text\/html"); 
      if (mx != null) { 
       $(divId).html(data); 
       if (callback) { 
        callback($(divId)); 
       } 
      } 
      else { 
       addMessage(data.type, data.title, data.text, data.sticky); 
      } 
     }, 
     error: function (jqXHR, textStatus, errorThrown) { 
      addMessage(3, "\"" + url + "\": Failed", textStatus + ": " + errorThrown, false); 
     } 
    }); 
} 

sadece zor biraz tepki olarak Content-Type başlık kontrol etmek ve buna bağlı olarak hareket etmektedir. HTML olmasaydı JSON'u kabul ederek "aldattığımızı" unutmayın. Önceden var olan addMessage() işlevimizi arıyoruz, ihtiyacınız olanı yapın!

Ve nihayet, burada onclick yukarıdaki getPartialView() hedeflemesi ile örnek bir Çapa unsurdur. formun dışında

<a href="#" onclick="getPartialView('Action', 'Controller', model, '#partialviewdivid', function(dvx) { connectJqueryEvents(dvx); })">Cancel</a> 

İşleri Büyük ...

JSON yükü nedeniyle Content-Type yeterli düzeyde doğrulanmaması HTML olarak yanlışlıkla işlenir Ajax.BeginForm() yoluyla gönderir. Sonuç, div'un temelde HTML olarak oluşturulmadığı bir JSON ekleyebilmenizdir. AjaxOptions.OnSuccess geri araması yürütülür, ancak bu noktada DOM için çok geç!

basit bir çözüm yoktur, ancak yazılı olarak asyncOnSuccess() fonksiyon basiretsiz olduğu için ne yazık ki jquery-unobtrusive-ajax.js için küçük onarım gerektirir. OTB versiyonda

function asyncOnSuccess(element, data, contentType) { 
    var mode; 

    if (contentType.indexOf("application/x-javascript") !== -1) { 
    return; 
    } 
    if (contentType.indexOf("application/json") !== -1) { 
    return; 
    } 
...snip... 
} 

, ikinci if deyimi eksik olduğunu; Eklemek, JSON yükünüzü DOM'a çarpmasını önlemek için gerekli olan düzeltmedir. yerine bu düzeltmeyi

JSON yükü sizin AjaxOptions.OnSuccess Javascript içine girer ve burada gerektiği gibi devam edebilirsiniz.

Evet Get You Can Hem Umarım sen Json gönderme verildiği için, modelin her türlü geri göndermek, ve sıralama onu Javascript çıkmasına izin verebilir biliyorum

; hasOwnProperty() orada işe yarar. Açıkçası, daha önce belirtilen RenderViewToString() aracılığıyla bazı görünüm HTML'lerini geri gönderebilirsiniz.

0

Sen de bu şekilde yapmak Kumandanızda İçinde koy edebilirsiniz.

protected string RenderPartialViewToString(string viewName, object model) 
{ 
    if (string.IsNullOrEmpty(viewName)) 
     viewName = ControllerContext.RouteData.GetRequiredString("action"); 

    ViewData.Model = model; 

    using (StringWriter sw = new StringWriter()) { 
     ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName); 
     ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw); 
     viewResult.View.Render(viewContext, sw); 

     return sw.GetStringBuilder().ToString(); 
    } 
}