2012-07-25 14 views
33

मैं एक HTML स्ट्रिंग में पार्टिकल व्यू प्रस्तुत करना चाहता हूं ताकि मैं इसे सिग्नलआर AJAX अनुरोध पर वापस कर सकूं।सिग्नलआर प्रतिक्रिया में एमवीसी आंशिक दृश्य प्रस्तुत करें

कुछ की तरह:

SignalR हब (mySignalHub.cs)

public class mySignalRHub: Hub 
{ 
    public string getTableHTML() 
    { 
     return PartialView("_MyTablePartialView", GetDataItems()) // *How is it possible to do this* 
    } 
} 

उस्तरा PartialView (_MyTablePartialView.cshtml)

@model IEnumerable<DataItem> 

<table> 
    <tbody> 
     @foreach (var dataItem in Model) 
     { 
     <tr> 
      <td>@dataItem.Value1</td> 
      <td>@dataItem.Value2</td> 
     </tr> 
     } 
    </tbody> 
</table> 

एचटीएमएल (MySignalRWebPage.html)

<Script> 
    ...  
    //Get HTML from SignalR function call 
    var tableHtml = $.connection.mySignalRHub.getTableHTML(); 

    //Inject into div 
    $('#tableContainer).html(tableHtml); 
</Script> 

<div id="tableContainer"></div> 

मेरी समस्या यह है कि मैं नियंत्रक के बाहर पार्टिकल व्यू प्रस्तुत नहीं कर सकता। क्या नियंत्रक के बाहर आंशिक दृश्य प्रस्तुत करना भी संभव है? रेजर के साथ आने वाली भयानक HTML जनरेटिंग क्षमताओं का लाभ उठाने में सक्षम होना अभी भी बहुत अच्छा होगा।

क्या मैं यह सब गलत कर रहा हूं? क्या कोई और तरीका है?

+1

भी रुचि ... विचार:

public static string RenderPartialView(string controllerName, string partialView, object model) { var context = new HttpContextWrapper(System.Web.HttpContext.Current) as HttpContextBase; var routes = new System.Web.Routing.RouteData(); routes.Values.Add("controller", controllerName); var requestContext = new RequestContext(context, routes); string requiredString = requestContext.RouteData.GetRequiredString("controller"); var controllerFactory = ControllerBuilder.Current.GetControllerFactory(); var controller = controllerFactory.CreateController(requestContext, requiredString) as ControllerBase; controller.ControllerContext = new ControllerContext(context, routes, controller); var ViewData = new ViewDataDictionary(); var TempData = new TempDataDictionary(); ViewData.Model = model; using (var sw = new StringWriter()) { var viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, partialView); var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, ViewData, TempData, sw); viewResult.View.Render(viewContext, sw); return sw.GetStringBuilder().ToString(); } } 

आप के लिए कुछ इसी तरह से कॉल करने की होगी? क्या आप नियंत्रकों के बाहर आंशिक प्रस्तुत कर सकते हैं? –

+0

यह आगे बढ़ने का एक सुविधाजनक तरीका नहीं है। केवल केसन डेटा को वापस करना बेहतर है और फिर क्लाइंट साइड टेम्पेट को निष्क्रिय करने के लिए बेहतर है, जो पहले से ही पेज में है। बदले में, टेम्पलेट को आंशिक दृश्य –

उत्तर

12

यहां, मैं एजेक्स के लिए नियंत्रकों में उपयोग करता हूं, मैंने इसे थोड़ा संशोधित किया है ताकि इसे नियंत्रक के बजाय विधि से बुलाया जा सके, विधि returnView आपके दृश्य को प्रस्तुत करता है और HTML स्ट्रिंग देता है ताकि आप इसे जेएस/jQuery के साथ सम्मिलित कर सकें अपने पृष्ठ में जब आप इसे क्लाइंट साइड पर पुन: प्राप्त करते हैं:

public static string RenderPartialToString(string view, object model, ControllerContext Context) 
     { 
      if (string.IsNullOrEmpty(view)) 
      { 
       view = Context.RouteData.GetRequiredString("action"); 
      } 

      ViewDataDictionary ViewData = new ViewDataDictionary(); 

      TempDataDictionary TempData = new TempDataDictionary(); 

      ViewData.Model = model; 

      using (StringWriter sw = new StringWriter()) 
      { 
       ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(Context, view); 

       ViewContext viewContext = new ViewContext(Context, viewResult.View, ViewData, TempData, sw); 

       viewResult.View.Render(viewContext, sw); 

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

     //"Error" should be name of the partial view, I was just testing with partial error view 
     //You can put whichever controller you want instead of HomeController it will be the same 
     //You can pass model instead of null 
     private string returnView() 
     { 
      var controller = new HomeController(); 
      controller.ControllerContext = new ControllerContext(HttpContext,new System.Web.Routing.RouteData(), controller); 
      return RenderPartialToString("Error", null, new ControllerContext(controller.Request.RequestContext, controller)); 
     } 

मैंने इसे एक हब पर परीक्षण नहीं किया लेकिन इसे काम करना चाहिए।

+0

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

+0

@ चालीस-दो मुझे लगता है कि यह अच्छा होना चाहिए क्योंकि मैं इस विधि को कॉल करने से पहले नियंत्रक के इंस्टेस को अक्षम करता हूं। आप स्क्रैच से बने कंट्रोलर कॉन्टेक्स्ट का उदाहरण देख सकते हैं। यह अच्छा होगा अगर किसी ने मुझे यह बताने के लिए परीक्षण किया, क्योंकि मैं छुट्टी पर हूं और इसका परीक्षण करने के लिए कहीं भी नहीं है। – formatc

+0

हम्म। यह शुरू में ऐसा लगता था कि यह चाल करेगा, लेकिन जब मैंने पूरी तरह से परीक्षण किया, तो मैं समस्याओं में भाग रहा हूं: कोई रूट डेटा उपलब्ध नहीं है (अनुरोध एमवीसी रूटिंग के माध्यम से नहीं किया जाता है)। इसे संबोधित करने के लिए नकली रूटिंग जोड़ा गया। आंशिक रूप से खोजने की कोशिश करते समय अब ​​निरर्थक अपवाद प्राप्त हो रहा है ... ऐसा लगता है कि इस दृष्टिकोण को अपस्ट्रीम तैरना है। मैं कुछ अन्य विकल्पों की जांच करने जा रहा हूं (जैसे रेजर टेम्पलेट इंजन) और देखें कि यह मुझे कहां प्राप्त करता है। मैं इस पोस्ट को अपडेट कर दूंगा क्योंकि मुझे और पता चल जाएगा। – James

-1

नीचे asimilar सवाल को आपूर्ति की जवाब के आधार पर, मैं उपयोग करने का सुझाव होगा

Html.Partial (partialViewName)

यह एक MvcHtmlString, जो आप सामग्री के रूप में उपयोग करने में सक्षम होना चाहिए देता है आपके सिग्नलआर प्रतिक्रिया का। हालांकि, मैंने इसका परीक्षण नहीं किया है।

स्टैक ओवरफ़्लो प्रश्न: Is it possible to render a view outside a controller?

+0

प्रदान किया जा सकता है "HTML" ऑब्जेक्ट का प्रकार "HTMLHelper" है। इसे तुरंत चालू करने के लिए, आपको ViewContext की आवश्यकता है। ViewContext को तुरंत चालू करने के लिए आपको एक ही समस्या पर वापस नियंत्रक कॉन्टेक्स्ट की आवश्यकता है। कोई नियंत्रक नहीं हालांकि देखने के लिए धन्यवाद! – James

1

आप http://razorengine.codeplex.com/ की तरह एक रेजर टेम्पलेट इंजन का उपयोग कर के बारे में सोचा है? आप आंशिक विचारों को पार्स करने के लिए इसका उपयोग नहीं कर सकते हैं, लेकिन आप इसका उपयोग रेज़र टेम्पलेट्स को पार्स करने के लिए कर सकते हैं, जो लगभग आंशिक विचारों के समान हैं।

+0

दिलचस्प, धन्यवाद। नीचे पाओलो की पोस्ट पर टिप्पणी देखें। मैं आगे की जांच कर सकता हूं, लेकिन उस परियोजना के साथ कुछ संभावित मुद्दे प्रतीत होते हैं। – James

4

शायद RazorEngine का उपयोग करने के लिए सबसे अच्छा विकल्प है, Wim सुझाव दे रहा है।

public class mySignalRHub: Hub 
{ 
    public string getTableHTML() 
    { 
     var viewModel = new[] { new DataItem { Value1 = "v1", Value2 = "v2" } }; 

     var template = File.ReadAllText(Path.Combine(
      AppDomain.CurrentDomain.BaseDirectory, 
      @"Views\PathToTablePartialView\_MyTablePartialView.cshtml")); 

     return Engine.Razor.RunCompile(template, "templateKey", null, viewModel); 
    } 
} 
+1

दिलचस्प लग रहा है। हालांकि, इस पुस्तकालय में समवर्ती उपयोग के साथ समस्याएं हैं, जो वेब वातावरण में अच्छी तरह से काम नहीं करेगी। विवरण के लिए यह धागा देखें: http://stackoverflow.com/questions/6444277/using-razorengine-to-parse-razor-templates-concurrently। इस इंजन के लेखक इन समस्याओं का समाधान करने के लिए एक पुनर्लेखन कर रहे थे, लेकिन ऐसा लगता है कि इस परियोजना पर थोड़ी देर के लिए कोई आंदोलन नहीं हुआ है - अब एक मृत परियोजना हो सकती है: https://github.com/Antaris/RazorEngine – James

+1

@ जेम्स रेजरइंजिन v3 (वर्तमान [NuGet पैकेज] (http://nuget.org/packages/RazorEngine)) बहु-थ्रेडेड परिदृश्य में ठीक काम करना चाहिए। आपको स्थिर विधि 'Razor.Parse' का आह्वान करने के बजाय, केवल' टेम्पलेट सेवा 'को तुरंत चालू करने की आवश्यकता है। अधिक जानकारी के लिए [इस पोस्ट] (http://www.fidelitydesign.net/?p=473) देखें। –

0

कैसे RazorEngineHost और RazorTemplateEngine उपयोग के बारे में। मुझे यह nice article मिल गया जो कि आप जो खोज रहे हैं वह हो सकता है। यह एएसपी.नेट (एमवीसी) के बाहर रेजर की मेजबानी करने के बारे में है।

3

उपरोक्त @ user1010609 द्वारा प्रदान किए गए उत्तर के आगे, मैंने इसके माध्यम से भी संघर्ष किया और एक ऐसे फ़ंक्शन के साथ समाप्त हो गया जो प्रस्तुत नियंत्रक नाम को एक नियंत्रक नाम, दृश्य और मॉडल के पथ प्रदान करता है।

इस तथ्य का विवरण लेता है कि आपके पास नियंत्रक नहीं है और इसलिए सिग्नलर ईवेंट से आने वाली सामान्य स्थिति में से कोई भी नहीं।

RenderPartialView("MyController", "~/Views/MyController/_partialView.cshtml", model);