2012-11-09 5 views
5

प्रस्तुत नहीं कर रहा है मैं एमवीसी के लिए बहुत नया हूं और एमवीसी 4 में मौजूदा साइट को पोर्ट करने का प्रयास करते समय इस समस्या में भाग गया हूं।एमवीसी 4 व्यू कंट्रोलर से कॉम्प्लेक्स ऑब्जेक्ट पास कर रहा है, नया दृश्य

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

public class DistributionModel 
{ 
    public string typeOfDistribution { get; set; } 
    public Document document { get; set; } 
    public string thumbnailUrl { get; set; } 
    public MergeFieldModel mergeFields { get; set; } 
} 

public class MergeFieldModel 
{ 
    public MergeFields documentMergeFields { get; set; } 
} 

यहाँ नियंत्रक कार्रवाई मैं उपयोग कर रहा हूँ है:

 public ActionResult Index(DistributionModel distributionModel) 
    { 
     distributionModel.mergeFields = new MergeFieldModel() { documentMergeFields = MergeFieldsHelper.GetDocumentMergeFields(distributionModel.document.Id) }; 
     return View("Index", distributionModel); 
    } 

मैं एक [email protected] ("सूचकांक", मॉडल) उपयोग करने की कोशिश के बजाय

यहाँ मेरी मॉडल है नियंत्रक को कॉल करने के लिए नीचे दिए गए ब्लॉक में बटन का और रीडायरेक्ट करने के लिए (रीडायरेक्ट ने स्वयं काम किया था, लेकिन मुझे उसी दस्तावेज़ को पुनर्प्राप्त करने के लिए नियंत्रक के भीतर एक और सेवा कॉल करना पड़ा क्योंकि मैं कॉलिंग व्यू से काम कर रहा था) क्योंकि मॉडल के भीतर दस्तावेज़ ऑब्जेक्ट सी के रूप में वापस करने के रूप में वापस रखा रखा ontroller।

यहां दृश्य का हिस्सा है जो नियंत्रक को बुला रहा है और वास्तव में पूरा मॉडल देता है: मुझे लगता है कि मैं जो खोज रहा हूं वह AJAX के बिना इसे पूरा करने का एक तरीका है ताकि मैं वितरण/अनुक्रमणिका पर रीडायरेक्ट प्राप्त कर सकूं पेज (इस वितरण/DocumentDetails पेज से निकाल दिया जाता है)

 <button id="EmailDistribution" data-corners="false" data-theme="a">EMAIL</button> 

     $('#EmailDistribution').click(function() { 
       var model = @Html.Raw(Json.Encode(Model)); 
       $.ajax({ 
       url: '@Url.Action("Index", "Distribution")', 
       type: 'POST', 
       contentType: 'application/json; charset=utf-8', 
       data: JSON.stringify(model),  
       processData: false,     
       });     
     }); 

धन्यवाद, किसी भी मदद की बहुत सराहना की जाएगी।

+0

आप 'वितरण/दस्तावेज़ विवरण 'की अंतिम पंक्ति के रूप में' रीडायरेक्ट टॉएक्शन (" इंडेक्स ", वितरण मॉडल) क्यों वापस कर सकते हैं? – Suhas

+0

दस्तावेज़ विवरण कार्रवाई दस्तावेज़ विवरण दृश्य देता है। इसके अतिरिक्त, मैंने नियंत्रक विधियों में से एक से RedirectToAction करने का प्रयास किया, और पाया कि यह दस्तावेज़ ऑब्जेक्ट को अन्य क्रियाओं को NULL के रूप में पास कर दिया। – gutsmania

उत्तर

7

मुझे यकीन है कि अगर मैं आपकी समस्या को बिल्कुल समझ में आ नहीं कर रहा हूँ, लेकिन मैं आपको बता सकता है कि आप एक रूप एक नियंत्रक कार्रवाई करने के लिए पोस्ट किया है कि आप नहीं चाहते अशक्त होने के लिए अपने मॉडल के हर एक मूल्य डाल करने के लिए की आवश्यकता होगी।

यह है आप अपने AJAX कॉल में क्या करते हैं: आप वर्तमान में पूरे मॉडल को जेसन में बदलते हैं और डेटा पोस्ट करने के लिए इसे फिर से बदलने की jQuery क्षमता का उपयोग करते हैं। मान लें कि आप उदाहरण के लिए निम्नलिखित मॉडल है कि:

public class TestModel { 
    public string A { get; set; } 
    public string B { get; set; } 
} 

आपका जावास्क्रिप्ट कोड jQuery का उपयोग कर एक स्ट्रिंग { A: 'Value for a', B: 'Value for B' } जो एक HTTP POST अनुरोध करने के लिए परिवर्तित हो जाएगा के लिए इसी तरह का निर्माण करेगा: एक परिणाम के रूप

POST /Controller/Index HTTP/1.1 
Host: demo.loc 
User-Agent: Mozilla/5.0 whatever 
Content-Type: application/x-www-form-urlencoded; charset=utf-8 

A=Value+for+a&B=Value+for+B 

अपने Index कार्रवाई को बुलाया जाएगा और DefaultModelBinder आपके मॉडल गुणों के मानों को बांधता है। यह आदिम प्रकारों के साथ काम करता है जैसे पूर्णांक के साथ-साथ जटिल प्रकारों जैसे कि संग्रह के लिए संग्रह। DefaultModelBinder इन प्रकारों के परिवर्तन को संभालता है।

public class ComplexSubModel { 
    public ICollection<string> StringList { get; set; } 
} 

public class ComplexModel { 
    public ComplexSubModel SubModel { get; set; } 
} 

DefaultModelBinder भी उन जैसे मॉडल आबद्ध कर सकता है:

के एक अधिक जटिल मॉडल पर एक नजर है

POST /Controller/Index HTTP/1.1 
Host: demo.loc 
User-Agent: Mozilla/5.0 whatever 
Content-Type: application/x-www-form-urlencoded; charset=utf-8 

ComplexModel.SubModel.StringList[0]=First+entry&ComplexModel.SubModel.StringList[1]=Second+entry&ComplexModel.SubModel.StringList[2]=Third+entry 

इस के साथ ComplexModel का एक नया उदाहरण में परिणाम होगा इसकी SubModel संपत्ति ComplexSubModel के नए उदाहरण के लिए सेट की गई है, इसकी संपत्ति StringListSystem.Collection.Generic.List<string> के नए उदाहरण पर सेट है जिसमें तीन तार First entry, Second entry और Third entry

अब आप क्या करना है, उदाहरण के लिए छिपा क्षेत्रों के लिए अपने मॉडल गुण प्रस्तुत करना है ताकि वे एक पोस्टबैक में शामिल हैं:

@using (Html.BeginForm()) { 
    @Html.HiddenFor(m => m.SubModel.StringList[0]) 
    @Html.HiddenFor(m => m.SubModel.StringList[1]) 
    @Html.HiddenFor(m => m.SubModel.StringList[2]) 
} 

हर संपत्ति पोस्टबैक में शामिल तो नहीं अशक्त हो जाएगा लेकिन उपयोगकर्ता द्वारा जाली हो सकती थी क्योंकि वे सर्वर पर मानते हैं कि उन्हें छिपे हुए फ़ील्ड में प्रस्तुत किया गया था। असल में आप यह सुनिश्चित नहीं कर सकते कि पुन: प्रेषित मान वे हैं जिन्हें आपने पहले सेवा कॉल द्वारा लाया था।

एक और संभावना TempData -dictionary में सेवा कॉल के परिणामों को सहेजने के लिए होगी जो वास्तव में उपयोगकर्ता-सत्र में मानों को संग्रहीत करती है और जैसे ही उन्हें पोस्टबैक कार्रवाई में फिर से पढ़ा जाता है या अन्यथा उन्हें नष्ट कर देता है एक सत्र में मान संग्रहीत:,

public ActionResult Index() { 
    // Do service calls 

    #region Variant a 
    TempData["ServiceResultA"] = foo; 
    TempData["ServiceResultB"] = bar; 
    #endregion 

    #region Variant b 
    Session["ServiceResultA"] = foo; 
    Session["ServiceResultB"] = bar; 
    #endregion 

    var model = new DistributionModel(); 
    // Set properties and stuff 

    return View("Index", model); 
} 

[HttpPost] 
public ActionResult Index(DistributionModel model) { 
    // Read "cached" service calls 

    #region Variant a 
    var foo = (TResultA)TempData["ServiceResultA"]; 
    var bar = (TResultB)TempData["ServiceResultB"]; 
    #endregion 

    #region Variant b 
    var foo = (TResultA)Session["ServiceResultA"]; 
    var bar = (TResultB)Session["ServiceResultB"]; 
    #endregion 

    // Do stuff 

    return RedirectToAction(...); 
} 

वेरिएंट के दोनों है पेशेवरों और contras जैसे वे समस्याग्रस्त जब उदाहरण के लिए एक ब्राउज़र सत्र या वर्गों के लिए की जरूरत के भीतर दो टैब में ब्राउज़ serializable होना करने के लिए हो सकता है जब आप एक सत्र राज्य सर्वर का उपयोग कर रहे हैं। फिर भी प्रक्रिया हमेशा एक ही है: या तो आप

  • करने के लिए
  • उन्हें बचाने होगा डेटा हर आप सेवाओं से इसकी जरूरत लाने (क्या महंगा है) या सर्वर (TempData, सत्र और सामान पर कहीं भी) या अन्य
  • उन्हें फॉर्म के साथ सबमिट करना (उपयोगकर्ता द्वारा जाली जा सकती है, हमेशा आसान नहीं होती है)।

अपना जहर चुनें। ;-)

+0

ग्रेट स्पष्टीकरण! – TTT

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