2009-05-27 16 views
22

मुझे यह तय करने में समस्या हो रही है कि नियंत्रक कार्रवाई, जिसे AJAX द्वारा बुलाया जाता है, को आंशिक दृश्य, या "कच्चा" JSON वापस करना चाहिए।एएसपी.नेट एमवीसी: एजेक्स रिटर्न जेएसओएन या एचटीएमएल प्रस्तुत करने वाले नियंत्रक को चाहिए?

प्रस्तुत किए गए HTML के साथ आंशिक दृश्य लौटने से जावास्क्रिप्ट को लौटाए गए HTML के साथ वर्तमान डोम को अपडेट करना आसान हो जाता है। हालांकि, यह प्रतिबंधित करता है कि जावास्क्रिप्ट क्लाइंट वेबसाइकिल उपभोग करने वाले क्लाइंट को लौटाए गए HTML के साथ क्या कर सकता है।

दूसरी तरफ, नियंत्रक कार्रवाई वापसी होने पर JSON को जावास्क्रिप्ट को "मैन्युअल रूप से" जेएसओएन पर आधारित मार्कअप बनाने के लिए कॉल करने की आवश्यकता होगी।

तो सामान्य रूप से, प्रत्येक दृष्टिकोण के लाभ और कमजोरी होती है। क्या प्रत्येक दृष्टिकोण के लिए कोई अन्य पेशेवर/विपक्ष है?

+0

टिप्पणियों पर टिप्पणियों पर जा रहे चर्चा पर: - बिलकुल, आपके लिए कई तरीके उपलब्ध हैं। जो कुछ भी आपको पसंद है उसका प्रयोग करें। एमवीसी चट्टानों !!!! – IsmailS

उत्तर

16

आप MVC प्रतिमान का उपयोग कर रहे हैं, तो नियंत्रक डेटा (JSON) लौट सकते हैं और दृश्य तरह यह अपने आप के लिए बाहर जाने चाहिए, बस अपना काम की तरह मॉडल में डेटा को ढूंढना/अनुकूलित करना और सर्वर की तरफ देखने के लिए इसे पास करना है।

आप तर्क और यूआई के बीच चिंताओं

  • अपने ajax कार्यों परीक्षण योग्य बनाने के अलग होने के संरक्षण के लिए

    • browny अंक मिलता है (सौभाग्य एचटीएमएल परीक्षण है कि कार्रवाई से लौटे ...)

    यह थोड़ा और जटिल हो सकता है, लेकिन यह फिट बैठता है।

    आप क्लाइंट-टेम्पलेटिंग सिस्टम का उपयोग कर सकते हैं जैसे एमएस अजाक्स टूलकिट में अब कुछ लोड लेने में मदद करने के लिए और ग्राहक पक्ष पर तर्क/प्रतिपादन पृथक्करण को संरक्षित रखने में मदद करें।

    तो मैं निश्चित रूप से JSON कहूंगा। लेकिन हे, सामान्य रूप से वाईएमएमवी ...

  • +0

    उसने क्या कहा। यहां तक ​​कि यदि आपको एमवीसी पैटर्न की परवाह नहीं है, तो JSON क्लाइंट पक्ष में हेरफेर और सत्यापित करना आसान होगा। – Gromer

    +0

    लगभग सभी मेरे नियंत्रक क्रियाएं जेसन/एक्सएमएल लौटती हैं। हालांकि, प्रति पृष्ठ एक क्रिया है जो एक HTML पृष्ठ देता है। आप एक पूरी तरह से स्थिर ग्राहक के पास जा सकते हैं और आपके सभी कार्य जेसन लौट सकते हैं, लेकिन मैं एचटीएमएल में एम्बेडेड प्रारंभिक डेटा को जेसन के रूप में एक राउंड ट्रिप बचाने के लिए भेजना पसंद करता हूं, क्योंकि क्लाइंट को यह देखने के लिए सर्वर से कनेक्शन करना पड़ता है कि क्या फाइल को वैसे भी संशोधित किया गया है। –

    0

    यदि आप JQuery का उपयोग करते हैं तो आपको JSON या XML का उपयोग करना चाहिए क्योंकि इसे संशोधित करना आसान है, लेकिन यदि आपका AJAX कॉल केवल एक सूची बॉक्स के लिए आइटम देता है उदाहरण के लिए आप HTML का उपयोग भी कर सकते हैं।

    मेरे निजी पसंद JSON या XML है, क्योंकि उपयोग JQuery बहुत बार

    2

    चिंताओं के पृथक्करण को बनाए रखने के लिए आपको JSON वापस करना चाहिए।

    जब आप एचटीएमएल वापस करते हैं तो आप लौटाए गए डेटा के साथ क्या कर सकते हैं सीमित कर सकते हैं। यदि आपको डेटा की एक सूची की आवश्यकता है और इसे विभिन्न तरीकों से प्रस्तुत करना चाहते हैं तो JSON का उपयोग करें, अन्यथा आपको उसी डेटा के अलग-अलग प्रस्तुतिकरण प्राप्त करने के लिए सर्वर पर अलग-अलग विधियां करनी होंगी।

    18

    मेरी राय में, JSON लौटने और फिर दे क्लाइंट साइड दृश्य यह तरह बाहर क्योंकि निम्नलिखित सीमाओं का गंदा हो सकता है:

    1. जावास्क्रिप्ट के लिए कोई मानक templating भाषा। सबसे खराब स्थिति परिदृश्य में, आपको आवश्यक HTML का निर्माण करने के लिए तारों को संयोजित करने का लुत्फ उठाया जाएगा।
    2. आपके कॉन्सटेनेशन कोड द्वारा उत्पन्न एचटीएमएल परीक्षण इकाई का कोई आसान तरीका नहीं है।
    3. आपकी जावास्क्रिप्ट के लिए IntelliSense की कमी का मतलब है कि आप और अधिक गलतियों को करने के लिए भी प्रवण हैं।

    जिस तरह से मैंने इसे संभाला है, वह एचटीएमएल प्रस्तुत करना है, लेकिन इसके बजाय आंशिक दृश्य का उपयोग करके इस प्रस्तुत एचटीएमएल को वापस कर दें। यह आपको दोनों दुनिया के सर्वश्रेष्ठ प्रदान करता है। आपके पास सर्वर-साइड टेम्पलेट्स के साथ-साथ IntelliSense समर्थन भी है।

    यहाँ मेरी अजाक्स कॉल है, जैसा कि आप देख सकते हैं सभी यह है मेरी बिना क्रम वाली सूची के लिए एचटीएमएल की जगह है:

    :

    FilterRequests: function() { 
        $.post("/Request.aspx/GetFilteredRequests", { }, function(data) { 
         $('ul.requests').html(data); 
        }); 
    }, 
    

    यहाँ मेरी नियंत्रक पर मेरी कार्रवाई की

    यहाँ एक उदाहरण है

    public ActionResult GetFilteredRequests(string filterJson) 
    { 
        var requests = _requestDao.LoadAll(); 
    
        return PartialView("FilteredRequests", requests); 
    } 
    
    अंत में यहाँ

    मेरी आंशिक (देखें यह समझने के लिए कोई आवश्यकता नहीं है है, मैं बस आप कैसे जटिल कुछ प्रतिपादन एक वास्तविक दुनिया आवेदन में प्राप्त कर सकते हैं दिखा रहा हूँ। मैं में यह कर भय था जावास्क्रिप्ट। आप यह भी देखेंगे कि मेरा आंशिक दृश्य बदले में अन्य आंशिक विचारों को भी कॉल करता है।):

    <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IEnumerable<Request>>" %> 
    <%@ Import Namespace="Diangy.HelpDesk.Models.Lookups"%> 
    <%@ Import Namespace="Diangy.HelpDesk.Models.Requests"%> 
    <%@ Import Namespace="System.Web.Mvc.Html"%> 
    
    <% foreach (var request in ViewData.Model) %> 
    <%{%> 
        <li class="request"> 
         <h2>#<%= request.Id %>: <%= request.InitialInteraction().Description %></h2> 
         <p>from <%= request.Customer.FullName %> (<%= request.Customer.EmailAddress %>), <%= request.InitialInteraction().UsableTimeStamp %></p> 
    
         <h3>Custom Fields & Lookups</h3> 
         <div class="tabs"> 
          <ul> 
          <li><a href="#customfields<%= request.Id %>">Custom Fields</a></li> 
          <% foreach (var lookupDefinition in (List<LookupDefinition>)ViewData["LookupDefinitions"]) %> 
          <%{%> 
          <li><a href="#<%= lookupDefinition.Name.ToLowerInvariant().Replace(" ", "") + request.Id %>"><%= lookupDefinition.Name %></a></li> 
          <%}%> 
         </ul> 
         <% Html.RenderPartial("CustomFields", request); %> 
        </div> 
    
        <% Html.RenderPartial("Discussion", request); %> 
        <% Html.RenderPartial("Attachment", request); %> 
        </li> 
    <%}%> 
    
    +0

    पूरी तरह से सहमत नहीं है। जेसन के साथ आपके पास थोड़ा और काम है, लेकिन नेटवर्क यातायात बहुत छोटा है, और प्रतिपादन/प्रस्तुतिकरण तर्क "स्मार्ट" क्लाइंट (jquery, extjs, ...) में रहता है। नए एमएस AJAX में टेम्पलेटिंग इंजन होगा –

    +7

    @hrvoje उस तर्क से हमें सभी नियंत्रक क्रियाएं केवल दृश्य के डेटा को वापस करनी चाहिए। देखें इंजन उस दुनिया में बेकार हैं। मुझे लगता है कि प्रवीण कह रहे हैं कि जब आप 1 से अधिक डीओएम तत्व अपडेट करते हैं तो व्यू इंजन द्वारा प्रस्तुत एचटीएमएल वापस करना आदर्श होता है। यह दृष्टिकोण आपकी क्रिया में "व्यू (...)" को कॉल करने जैसा ही है - एक HTML स्निपेट और "व्यू()" को एचटीएमएल दस्तावेज़ प्रस्तुत करने के लिए "ParitialView()" को कॉल करना। जब तक आप एक दृश्य इंजन की अवधारणा को त्यागना नहीं चाहते हैं, मुझे यकीन नहीं है कि आप इतनी दृढ़ता से असहमत कैसे हो सकते हैं। –

    +0

    पूरी तरह से असहमत। Http://code.google.com/closure/templates/docs/helloworld_js.html देखें। यह एक बहुत परिपक्व और तेज़ टेम्पलेटिंग सिस्टम है, बदसूरत स्ट्रिंग concatenation की कोई ज़रूरत नहीं है। इस तर्क को अलग रखने से आप सर्वर साइड कोड को दोबारा लिखने के बिना एक और क्लाइंट (आईफोन, स्विंग, फ्लैश) लिखने की अनुमति देते हैं क्योंकि आप सर्वर पर पहुंचे जो यह सबसे अच्छा करता है - डेटा प्रदान करता है - और दृश्य भाग को क्लाइंट में ले जाता है। Google की टेम्पलेटिंग सिस्टम आपको क्लाइंट की सेवा करने की आवश्यकता होने पर आपके टेम्पलेट्स सर्वर पक्ष को चलाने की अनुमति देती है जो जावास्क्रिप्ट का समर्थन नहीं करती है। –

    2

    क्यों जेसन और एचटीएमएल दोनों नहीं? वर्तमान प्रोजेक्ट में हम मार्ग बना रहे हैं ताकि आप फ्रंट एंड से चुन सकें, जो प्रारूप कुछ मामलों में सबसे उपयुक्त है ... तो दो नियंत्रक क्यों नहीं बनाते हैं, पहले जेसन में अपेक्षित डेटा वापस कर देंगे और दूसरा नियंत्रक वापस आ जाएगा एक ही डेटा लेकिन एचटीएमएल के साथ ... इस तरह से आप चुन सकते हैं कि jQuery क्या कहां और कब चाहते हैं और किस प्रारूप में आप इसे चाहते हैं ... और सबसे अच्छी बात यह है कि विभिन्न प्रारूपों के लिए आपको अलग-अलग एड्रेस को कॉल करने की आवश्यकता है .. ।

    दूसरे शब्दों में, यह आरामदायक बनाने के लिए, बच्चे! :)

    चीयर्स

    +0

    अनुरोध के स्वीकार्य सामग्री प्रकार का उपयोग करने की भी देखभाल की जा सकती है, क्योंकि आप वास्तव में एक ही संसाधन (यूरी) को देख रहे हैं, लेकिन एक अलग प्रतिनिधित्व। मुझे नहीं पता कि एएसपीनेट एमवीसी को उस पर आधारित एक अलग कार्रवाई के लिए बनाया जा सकता है, जो कि कार्रवाई हैंडलर में सामग्री-प्रकार पर एक विशाल स्विच केस से मुझे बेहतर लगता है ... –

    +0

    मुझे लगता है इसे और अधिक क्लीनर है करने के लिए किया था कुछ इस तरह: {नियंत्रक}/{कार्रवाई}/{...} और jQuery से आप json प्रारूप की जरूरत है: json/सूची/.... और अगर आपको एचटीएमएल की आवश्यकता है: एचटीएमएल/सूची/... चीयर्स – Marko

    2

    मेरे लिए, मैं डेटा संचालित दृष्टिकोण चुनता हूं। यहाँ दोनों के लिए सुविधाओं का एक छोटा सेट है:

    डेटा पर ही आधारित: सर्वर से

    1. JSON (नियंत्रक प्रतिक्रिया के लिए सीधे मॉडल भेजता है)
    2. जे एस टेम्पलेट बाध्यकारी (क्लाइंट साइड पर अधिक समय लग सकता है)
    3. कम बैंडविड्थ लोड
    4. यह सिर्फ इतना ही सेक्सी है!

    एचटीएमएल संचालित: सर्वर से

    1. एचटीएमएल (नियंत्रक, कुछ आंशिक देखें मॉडल भेजता है यह परिणाम renders और यह देता है - सर्वर साइड पर अधिक समय लग सकता है)
    2. जे एस में कोई अधिभार बाध्यकारी
    3. उच्च बैंडविड्थ लोड
    4. सेक्सी नहीं, कोई नहीं :)

    तो आप एचटीएमएल संचालित दृष्टिकोण के साथ भी एमवीसी को बनाए रख सकते हैं हालांकि यह थोड़ा कठिन होगा।

    4

    मैं कॉलिंग ऐप को निर्णय लेने की अनुमति देना चाहता हूं। मैंने एक मल्टीव्यू कंट्रोलर को एक साथ चिपकाया है (मुझे जो कोड मिला है, मैं क्रेडिट के साथ अपडेट करने का प्रयास करूंगा, जब मैं इसे पाता हूं) कि, एक्शन एक्सटेंशन के आधार पर, उपयुक्त प्रारूप वापस कर देगा।उदाहरण के लिए:

    myapp.com/api/Users/1 - defaults to html based on route 
    myapp.com/api/Users.html/1 - html 
    myapp.com/api/Users.json/1 - json 
    myapp.com/api/Users.xml/1 - xml 
    myapp.com/api/Users.partial/1 - returns a partial view of action name (see code) 
    myapp.com/api/Users.clean/1 - partial html without styling, etc... 
    

    मेरे नियंत्रकों MultiViewController से और के बजाय वारिस "वापसी दृश्य (मॉडल)," मैं बस "रिटर्न फॉर्मेट व्यू (मॉडल) या प्रारूप दृश्य (" व्यूनाम ", मॉडल) कहता हूं;"। दूसरा अगर मुझे परिणाम के लिए एक विशिष्ट दृश्य लागू करने की आवश्यकता है - निहित दृश्य नहीं।

    मल्टीव्यू कंट्रोलर इस तरह दिखता है। FormatView पर विशेष ध्यान दें, whitch एक कार्रवाई परिणाम देता है:

    public abstract class MultiViewController : Controller 
    { 
        private const string FORMAT_KEY = "format"; 
        public enum FileFormat {Html, Json, Xml, Partial, Clean} 
    
        protected MultiViewController() 
        { 
         RequestedFormat = FileFormat.Html; 
        } 
        protected FileFormat RequestedFormat { get; private set; } 
    
        protected override void OnActionExecuting(ActionExecutingContext filterContext) 
        { 
         base.OnActionExecuting(filterContext); 
         var routeValues = filterContext.RouteData.Values; 
         if (routeValues.ContainsKey(FORMAT_KEY)) 
         { 
          var requestedFormat = routeValues[FORMAT_KEY].ToString(); 
          if (isValidFormat(requestedFormat)) 
          { 
           RequestedFormat = (FileFormat)Enum.Parse(typeof(FileFormat), requestedFormat, true); 
          } 
         } 
        } 
    
        private bool isValidFormat(string requestedFormat) 
        { 
         return Enum.GetNames(typeof (FileFormat)).Any(format => format.ToLower() == requestedFormat.ToLower()); 
        } 
    
        protected ActionResult FormatView(string viewName, object viewModel) 
        { 
         switch (RequestedFormat) 
         { 
          case FileFormat.Html: 
           if (viewName != string.Empty) 
           { 
            return View(viewName,viewModel); 
           } 
           return View(viewModel); 
          case FileFormat.Json: 
           return Json(viewModel); 
          case FileFormat.Xml: 
           return new XmlResult(viewModel); 
          case FileFormat.Partial: 
          //return View(this.ControllerContext.RouteData.Values["action"] + "Partial"); 
          return PartialView(this.ControllerContext.RouteData.Values["action"] + "Partial"); 
          case FileFormat.Clean: 
           if (viewName != string.Empty) 
           { 
            return View(viewName, "~/Views/Shared/Clean.master", viewModel); 
           } 
           var v = View(viewModel); 
           v.MasterName = "~/Views/Shared/Clean.Master"; 
           return v; 
          default: 
           throw new FormatException(string.Concat("Cannot server the content in the request format: ", RequestedFormat)); 
         } 
        } 
        protected ActionResult FormatView(object viewModel) 
        { 
         return FormatView("", viewModel); 
        } 
    
    
    
    
    } 
    

    Clean.master बस एक मास्टर पृष्ठ है कि किसी भी अतिरिक्त एचटीएमएल शामिल नहीं करता है - यह दृष्टिकोण लेता है (ताकि मैं किसी भी आंशिक वर्गों को मजबूत कर सकते हैं) और इसे स्वच्छ एचटीएमएल के साथ प्रस्तुत करता है जिसे सीधे रखा जा सकता है।

    यदि मैं जेसन चाहता हूं - नियंत्रक मेरा व्यूमोडेल बनाता है और उसके बाद उस दृश्य मॉडल को जेसन के रूप में देता है, डिफ़ॉल्ट दृश्य को भेजने के बजाय - .xml के साथ।

    आंशिक विचार उसमें थोड़ा दिलचस्प हैं, सम्मेलन के अनुसार, मेरे सभी मुख्य विचार आंशिक रूप से विभाजित हो जाते हैं, ताकि विशेष आंशिक रूप से अनुरोध किया जा सके - यह jquery का उपयोग करके एक अपडेट पैनेल की कार्यक्षमता की नकल करने के लिए आसान है अपडेट पैनेल से जुड़े सभी जंक के बिना।

    +0

    बहुत दिलचस्प है। रेल की तरह आपको बहुत कुछ करने की इजाजत मिलती है। कई स्थितियों के लिए समझ में आता है। –

    संबंधित मुद्दे