2012-05-25 16 views
46

एक काफी अनुभवी ASP.Net डेवलपर के रूप में अभी हाल ही में MVC का उपयोग कर शुरू करने के बीच राज्य रखने के लिए, मैं अपने आप को एक पारंपरिक "सर्वर नियंत्रण और ईवेंट हैंडलर" से मेरी मानसिकता को बदलने के लिए थोड़ा संघर्ष कर पाते हैं चीजों को करने के तरीके, चीजों के अधिक गतिशील एमवीसी तरीके में। मुझे लगता है कि मैं धीरे-धीरे वहां जा रहा हूं, लेकिन कभी-कभी एमवीसी "जादू" मुझे फेंकता है।ASP.Net MVC और राज्य - कैसे अनुरोध

मेरे वर्तमान परिदृश्य एक वेब पेज है कि उपयोगकर्ता, एक स्थानीय फ़ाइल ब्राउज़ सर्वर पर अपलोड करें और इस दोहराने जब तक वह साथ काम करने के लिए फ़ाइलों की एक सूची है की अनुमति देता है बनाने के लिए है। जब वह फ़ाइल सूची (जो पृष्ठ पर एक ग्रिड में प्रदर्शित किया जाएगा) के साथ खुश है, वह फ़ाइलों को प्रोसेस और कहा कि एक डेटाबेस में संग्रहीत किया जाएगा कुछ डेटा निकालने के लिए एक बटन पर क्लिक करेंगे।

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

मैं मैं बेहतर पोस्ट मेरी इस कोडिंग समस्या की व्याख्या करने की नहीं बल्कि अधूरा प्रयास लगता है।

आदेश मेरी फाइल सूची डेटा रखने के लिए, मैं एक viewmodel मूल रूप से फ़ाइलों की एक टाइप सूची है कि, कुछ अतिरिक्त मेटाडाटा के साथ बनाया है:

public class ImportDataViewModel 
{ 
    public ImportDataViewModel() 
    { 
     Files = new List<ImportDataFile>(); 
    } 

    public List<ImportDataFile> Files { get; set; } 
... 

ध्यान में रखते हुए मैं ब्राउज़िंग के लिए एक रूप है और फ़ाइल को अपलोड:

<form action="AddImportFile" method="post" enctype="multipart/form-data"> 
    <label for="file"> 
    Filename:</label> 
    <input type="file" name="file" id="file" /> 
    <input type="submit" /> 
    </form> 

दृश्य अपने मॉडल के रूप में उपयोग कर रहा है viewmodel:

@model MHP.ViewModels.ImportDataViewModel 

यह मेरा कार्रवाई करने के लिए फ़ाइल भेज देंगे:

public ActionResult AddImportFile(HttpPostedFileBase file, ImportDataViewModel importData) 
    { 

     if (file.ContentLength > 0) 
     { 
      ImportDataFile idFile = new ImportDataFile { File = file }; 
      importData.Files.Add(idFile); 
     } 

     return View("DataImport", importData); 
    } 

यह क्रिया फ़ाइलों की सूची से युक्त viewmodel उदाहरण के साथ DataImport पेज के लिए दृश्य देता है।

यह एक निश्चित बिंदु तक अच्छी तरह से काम करता है, मैं एक फ़ाइल ब्राउज़ कर सकता हूं और इसे अपलोड कर सकता हूं, और मैं कार्रवाई के अंदर व्यूमोडेल डेटा देख सकता हूं, और फिर भी अगर मैं दृश्य के अंदर ब्रेकपॉइंट डालता हूं और इसे "डीबेल" ", सब कुछ ठीक है।

लेकिन फिर, अगर मैं एक और फ़ाइल अपलोड करने का प्रयास करता हूं, तो AddImportFile कार्रवाई के अंदर ब्रेकपॉइंट डालने पर, आयात डेटा पैरामीटर खाली होता है। तो दृश्य स्पष्ट रूप से कार्रवाई के लिए अपने मॉडल के वर्तमान उदाहरण को पारित नहीं कर रहा है।

एमवीसी नमूने में मैंने किया है, मॉडल उदाहरण "जादुई रूप से" पैरामीटर के रूप में क्रिया विधि को पारित किया गया है, तो अब यह खाली क्यों है?

मुझे लगता है कि असली समस्या एमवीसी की मेरी सीमित समझ है, और शायद यह एक बहुत ही सरल समाधान है। वैसे भी, अगर कोई मुझे सही दिशा में इंगित कर सकता है तो मैं बहुत आभारी हूं।

+0

आप सर्वर पर कहीं भी अपलोड की गई फ़ाइलों को संग्रहीत नहीं कर रहे हैं। आप कैसे उम्मीद करते हैं कि वे पोस्टबैक के बीच बने रहेंगे? आपके पास आपके '

' के अंदर जो कुछ भी है, वह एक फ़ाइल इनपुट फ़ील्ड है। तो नियंत्रक कार्रवाई में आने के लिए आप जो भी उम्मीद कर सकते हैं वह यह फ़ाइल है। और कुछ नहीं। कोई जादू नहीं है एएसपी.नेट एमवीसी में कोई व्यूस्टेट नहीं है। –

+0

डारिन, आपकी टिप्पणी के लिए धन्यवाद। यह सही है कि मैं सर्वर पर फ़ाइल संग्रहीत नहीं कर रहा हूं। मैं इसे डेटाबेस में संग्रहीत कर सकता हूं, लेकिन यह डाटाबेस स्पेस और उपयोगकर्ता धैर्य का अपशिष्ट होगा, क्योंकि इसमें काफी समय लगेगा और इसके लिए कोई वास्तविक आवश्यकता नहीं है। मैं क्या करना चाहता हूं बस इसे सर्वर मेमोरी में किसी चर के रूप में रखने के लिए है जब तक उपयोगकर्ता इसे संसाधित करने का निर्णय नहीं लेता। फिर मैं उस प्रसंस्करण के आउटपुट को डेटाबेस में संग्रहीत करूंगा। मुझे लगता है कि या तो मैं एमवीसी को गलत तरीके से इस्तेमाल करने की कोशिश कर रहा हूं, या मुझे नहीं पता कि यह कैसे करना है। मुझे नहीं पता कि यह अभी तक कौन सा है ... – TMan

+2

सर्वर मेमोरी में फ़ाइलों को रखना सबसे बुरी चीजों में से एक है। इस कीमत से सभी कीमतों से बचें। इतना ही नहीं कि यह आपके सर्वर पर बहुत सारी मेमोरी का उपभोग करेगा, लेकिन यह न भूलें कि आईआईएस किसी भी समय एप्लिकेशन डोमेन रीसायकल कर सकता है, स्मृति में संग्रहीत सभी डेटा खो देता है। अगर आप सर्वर फार्म में भागते हैं तो क्या होगा?यदि आप सर्वर की याद में संग्रहीत करते हैं तो इसका मतलब है कि खेत के केवल 1 सर्वर में यह जानकारी है और यदि लोड बैलेंसर खेत के किसी अन्य सर्वर पर बाद के अनुरोध भेजता है तो आप जानकारी खो देंगे। –

उत्तर

46

कुछ समय हो गया है क्योंकि मैंने सवाल पोस्ट किया था, जो मेरे छोटे अनुभव और एमवीसी के ज्ञान से काफी रंगीन था। फिर भी मुझे कुछ काफी उपयोगी इनपुट मिला, जिसने मुझे अंततः समाधान ढूंढने और एमवीसी की कुछ अंतर्दृष्टि प्राप्त करने का नेतृत्व किया।

क्या मुझे पहली जगह में बंद फेंक दिया, था आप एक पैरामीटर के रूप एक जोरदार टाइप किया वस्तु के साथ एक नियंत्रक, इस तरह हो सकता है:

public ActionResult DoSomething(MyClass myObject)... 

इस वस्तु एक ही नियंत्रक से उत्पन्न:

... 
return View(myObject); 
... 

यह मुझे विश्वास दिलाता है कि वस्तु इन दो चरणों में रहती है, और मैं किसी भी तरह से उम्मीद कर सकता हूं कि आप इसे देखने के लिए भेज सकते हैं, कुछ करें और फिर "जादुई" इसे फिर से नियंत्रक के पास ले जाएं।

मॉडल बाध्यकारी के बारे में पढ़ने के बाद, मुझे समझ में आया कि यह निश्चित रूप से मामला नहीं है। दृश्य पूरी तरह से मृत और स्थैतिक है, और जब तक आप कहीं भी जानकारी संग्रहीत नहीं करते हैं, यह चला गया है।

समस्या पर वापस जाना, जो क्लाइंट से फ़ाइलों का चयन और अपलोड कर रहा था, और इन फ़ाइलों की एक सूची प्रदर्शित करने के लिए, मुझे एहसास हुआ कि सामान्य रूप से एमवीसी में अनुरोधों के बीच जानकारी संग्रहीत करने के तीन तरीके हैं:

  1. आप ध्यान में रखते हुए प्रपत्र फ़ील्ड्स में जानकारी स्टोर, और इसे वापस नियंत्रक को पोस्ट कर सकते हैं बाद में
  2. आप इसे भंडारण, जैसे किसी तरह का में बच सकते हैं एक फ़ाइल या डेटाबेस
  3. आप इसे पूरे ऑर्डर देने वाले ऑब्जेक्ट्स का आकलन करके सर्वर मेमोरी में संग्रहीत कर सकते हैं, उदा। सत्र चर

मेरे मामले में, मैं मूल रूप से लागू करने के लिए दो प्रकार की जानकारी थी: फ़ाइल मेटाडाटा (फ़ाइल नाम, फ़ाइल आकार आदि) 1. 2. फ़ाइल सामग्री

"द्वारा -थ-बुक "दृष्टिकोण शायद फॉर्म फ़ील्ड में मेटाडेटा को स्टोर करना होगा, और फाइल में सामग्री या डीबी में फाइल सामग्री को स्टोर करना होगा। लेकिन एक और तरीका भी है। चूंकि मुझे पता है कि मेरी फाइलें काफी छोटी हैं और उनमें से केवल कुछ ही होंगे, और यह समाधान सर्वर फार्म या इसी तरह से कभी भी तैनात नहीं किया जाएगा, मैं सत्र चर के # 3 विकल्प का पता लगाना चाहता था। फाइल सत्र से परे बने रहने के लिए भी दिलचस्प नहीं हैं - उन्हें संसाधित और त्याग दिया जाता है, इसलिए मैं उन्हें अपने डीबी में स्टोर नहीं करना चाहता था।

इस उत्कृष्ट लेख को पढ़ने के बाद: Accessing ASP.NET Session Data Using Dynamics

मुझे विश्वास था। मैं बस एक sessionbag वर्ग आलेख में वर्णित के रूप में बनाया है, और फिर मैं अपने नियंत्रक में निम्न कर सकता है:

[HttpPost] 
    public ActionResult AddImportFile(HttpPostedFileBase file) 
    { 

     ImportDataViewModel importData = SessionBag.Current.ImportData; 
     if (importData == null) importData = new ImportDataViewModel(); 

     if (file == null) 
      return RedirectToAction("DataImport"); 

     if (file.ContentLength > 0) 
     { 
      ImportDataFile idFile = new ImportDataFile { File = file }; 
      importData.Files.Add(idFile); 
     } 

     SessionBag.Current.ImportData = importData; 

     return RedirectToAction("DataImport"); 
    } 

मैं पूरी तरह से पता है कि ज्यादातर मामलों में, यह एक बुरा समाधान होगा हूँ। लेकिन सर्वर मेमोरी के कुछ केबी के लिए फाइलें कब्जा कर लेती हैं और इसकी सादगी के साथ, मुझे लगता है कि यह मेरे लिए बहुत अच्छी तरह से काम करता है।

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

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

+0

अच्छा सारांश और स्पष्टीकरण। – Lester

+1

सत्र की समाप्ति के बारे में क्या? – garik

+0

@garik रीसाइक्लिंग के सत्रों से निपटने का एक समाधान है, आउट-ऑफ-प्रोसेस सत्र स्टेट सर्वर या एसक्यूएल सर्वर का उपयोग कर रहा है: https://technet.microsoft.com/en-us/library/cc754032(v=ws। 10) .aspx –

10

अपलोड कर रहा है

1 के संबंध में) हो सकता है कि HTML के साथ एक AJAX अपलोड करने वाले पर विचार अपने उपयोगकर्ता एकाधिक फ़ाइलों का चयन करने के लिए उन्हें सर्वर पर भेजा जाता है से पहले अनुमति देने के लिए। यह BlueImp jQuery AJAX फ़ाइल अपलोड करने वाले एक बहुत महान एपीआई के साथ बहुत अद्भुत है: Blueimp Jquery File Upload।यह उपयोगकर्ताओं को कई फ़ाइलों को खींचने और छोड़ने या बहु फ़ाइल का चयन करने और फ़ाइल ऑर्डर को संपादित करने, आदि शामिल करने/बहिष्कृत करने की अनुमति देगा .. फिर जब वे खुश हों तो वे आपके नियंत्रक को भेजे जाने के लिए अपलोड दबा सकते हैं या सर्वर पक्ष पर प्रोसेसिंग के लिए हैंडलर अपलोड कर सकते हैं।

2) आप प्रत्येक अपलोड को डेटाबेस में बना सकते हैं, हालांकि आप पूरे पृष्ठ को पुनः लोड कर रहे हैं और लिस्टिंग प्रभाव प्राप्त करने के लिए कुछ अतिरिक्त दृश्य मॉडल और रेज़र कोड लिख रहे हैं। यह शायद नहीं उत्तरदायी होने की ...

राज्य WebForms रखते हुए के बारे में जा रहा है/MVC

अनुरोधों के बीच राज्य में रखते हुए कुछ हद तक काला जादू और वूडू है। एएसपी.नेट एमवीसी में जाने पर, यह समझें कि वेब अनुप्रयोग अनुरोध और प्रतिक्रियाओं का उपयोग करके संवाद करते हैं। तो वेब को स्टेटलेस के रूप में गले लगाने और वहां से विकसित होने में जाओ! जब आपका मॉडल आपके नियंत्रक के माध्यम से पोस्ट किया जाता है, तो यह नियंत्रक में किसी भी चर के साथ चला गया है! हालांकि इससे पहले कि यह दूर हो जाए, आप बाद में पुनर्प्राप्ति के लिए डेटाबेस में अपनी सामग्री स्टोर कर सकते हैं।

वेब अनुप्रयोग डेस्कटॉप अनुप्रयोगों जैसे वास्तविक स्थिति को नहीं रख सकते हैं। AJAX ढांचे के कई तरीके हैं, और कुछ वूडू उपकरण जो लोग HTTP वातावरण में राज्य अनुकरण करने के लिए नियोजित करते हैं। और राज्य का अनुकरण वास्तव में केवल राज्य की झूठी नकल है। एएसपी.नेट वेब फॉर्म डेवलपर से HTTP की स्टेटलेस प्रकृति को छिपाने के तरीके से राज्य को अनुकरण करने की कोशिश करता है। वेब फॉर्म मार्कअप कोड और अपने स्वयं के अजाक्स ढांचे के साथ अपने स्वयं के AJAX कोड को नियोजित करने का प्रयास करते समय आप बहुत सी सिरदर्द में भाग सकते हैं।

मैं वास्तव में खुशी है कि तुम MVC

सभी चुटकुले सीख रहे हैं एक तरफ, अगर आप MVC/HTTP/statelessness मानसिकता मिलता है, यह अन्य सुपर लोकप्रिय चौखटे के पैटर्न लागू करने के लिए बहुत आसान हो जाएगा हूँ रेल पर रूबी, स्प्रिंगएमवीसी (जावा), डीजेगो (पायथन), केकेपीएचपी इत्यादि ... ज्ञान का यह आसान हस्तांतरण आपको एक बेहतर डेवलपर बनने में मदद करेगा और अजाक्स में वास्तव में अच्छा होगा।

मुझे सचमुच खुशी है कि आप एमवीसी 3 सीख रहे हैं, मैं कुछ बहुत बड़ी कंपनियों में कुछ इंटर्नशिप के साथ रहा हूं, जिनमें इन पागल बड़े एएसपी.नेट वेब फॉर्म प्रोजेक्ट्स थे, जो कोड के साथ हर जगह कुछ संख्याओं को बदलने के लिए थे डेटाबेस में मान (-_- ') महसूस किया जैसे मैं एक बच्चे के साक बुनाई के लिए कैंची का उपयोग कर रहा था। एक आसान गलत कदम, और सब कुछ टूट गया। यह PHP में विकास की तरह महसूस किया, आप पसीना आते हैं और वास्तव में यह सुनिश्चित नहीं करते कि क्या हुआ और किस लाइन पर। डीबग और अपडेट करना लगभग असंभव था।

+0

हालांकि थोड़ा स्पष्ट है, मैं 2) ए) जोड़ता हूं ताकि अनुरोध के बीच फ़ाइलों की सूची बनाए रखने के लिए छिपे हुए फ़ील्ड का उपयोग किया जा सके। आखिरकार वेब फॉर्म में व्यूस्टेट एब्स्ट्रक्शन छिपे हुए क्षेत्र का उपयोग करता है, इसलिए यह सब के बाद इतना बुरा विचार नहीं है और डेटाबेस विकल्प से लागू करना आसान होगा। – Kiran

+0

मैक्स, एक पूर्ण जवाब के लिए धन्यवाद। 1 के लिए) - हां, मैं शायद इसे अधिक उपयोगकर्ता अनुकूल बनाने के लिए बाद में एक से अधिक फ़ाइल अपलोड कार्यक्षमता को लागू करने का प्रयास करूंगा, लेकिन यह वास्तव में मुख्य मुद्दा नहीं है। मुझे लगता है कि यहाँ मूल मुद्दा स्टेटस बनाम स्टेटलेस के बारे में अधिक है। मैं पहले इस चर्चा में आया हूं, लेकिन मुझे पूरी तरह से यह पूरा नहीं मिलता है 'एमवीसी की स्टेटलेस प्रकृति को गले लगाओ'। क्या आप कह रहे हैं कि हमें अपने वेब ऐप्स में राज्य लागू नहीं करना चाहिए? सब कुछ डीबी में संग्रहीत नहीं किया जाना चाहिए। उदाहरण के लिए शॉपिंग कार्ट लें। मनुष्य स्वभाव से हैं, तो वेब ऐप्स क्यों नहीं होना चाहिए? – TMan

+0

किरण, मुझे लगता है कि आप सही हैं। अब मैं मॉडल बाइंडिंग के बारे में पढ़ रहा हूं, जो मेरे मामले में कथित "जादू" का एक बड़ा हिस्सा प्रस्तुत करता है - दृश्य में फ़ील्ड फ़ील्ड अचानक नियंत्रक में दृढ़ता से टाइप किए गए क्लास उदाहरणों में परिवर्तित हो जाते हैं। अंतर्निहित सिद्धांतों को समझे बिना किसी भिन्न परिदृश्य में "जादू" को लागू करने का प्रयास करते समय, यह निश्चित रूप से गलत हो जाएगा। सोचो कि मैं अभी सही रास्ते पर हूं। – TMan