2014-05-14 11 views
16

मैं व्यू मॉडेल का उपयोग करने के लिए काफी नया हूं और मुझे आश्चर्य है, क्या यह व्यूमोडेल के लिए डोमेन मॉडल के उदाहरणों को गुणों के रूप में शामिल करने के लिए स्वीकार्य है, या उन डोमेन मॉडल के गुणों को व्यूमोडेल के गुण होना चाहिए? उदाहरण के लिए, अगर मैं एक वर्ग Album.csएमवीसी/एमवीवीएम में दृश्य मॉडल/परतों का पृथक्करण - सर्वोत्तम प्रथाओं?

public class Album 
{ 
    public int AlbumId { get; set; } 
    public string Title { get; set; } 
    public string Price { get; set; } 
    public virtual Genre Genre { get; set; } 
    public virtual Artist Artist { get; set; } 
} 

है आप आमतौर पर ViewModel Album.cs वर्ग का एक उदाहरण पकड़ होता है, या आप ViewModel होता Album.cs वर्ग 'गुण से प्रत्येक के लिए गुण होते हैं।

public class AlbumViewModel 
{ 
    public Album Album { get; set; } 
    public IEnumerable<SelectListItem> Genres { get; set; } 
    public IEnumerable<SelectListItem> Artists { get; set; } 
    public int Rating { get; set; } 
    // other properties specific to the View 
} 


public class AlbumViewModel 
{ 
    public int AlbumId { get; set; } 
    public string Title { get; set; } 
    public string Price { get; set; } 
    public IEnumerable<SelectListItem> Genres { get; set; } 
    public IEnumerable<SelectListItem> Artists { get; set; } 
    public int Rating { get; set; } 
    // other properties specific to the View 
} 
+0

आपके पहले दृष्टिकोण में मॉडल ऑब्जेक्ट तक पूर्ण पहुंच देना खतरनाक हो सकता है। बेहतर विकल्प आपके मॉडल को निजी क्षेत्र में रखेगा और केवल उन गुणों का खुलासा करेगा जिन्हें देखने के लिए जरूरी है। जैसे सार्वजनिक स्ट्रिंग शीर्षक {प्राप्त करें {this.album.Title को वापस करें; } सेट करें {this.album.Title = value;}} –

उत्तर

23

मज़ा हिस्सा: इस MVC में viewmodels तक सीमित नहीं है, यह वास्तव में "अच्छे पुराने डेटा/व्यापार/ui परतों" चिंताओं में से अर्थात जुदाई की जुदाई की बात है। मैं इसे बाद में समझाऊंगा, लेकिन अभी के लिए; ध्यान रखें कि यह MVVM या किसी अन्य डिज़ाइन पैटर्न पर भी लागू होता है।

क्या यह डोमेन मॉडल के उदाहरणों को देखने के लिए व्यूमोडेल के लिए स्वीकार्य है?

असल में नहीं, हालांकि मुझे लगता है कि यह बहुत कुछ होता है। यह आपकी परियोजना के quick-win स्तर पर थोड़ा सा निर्भर करता है।

मुझे एक उदाहरण दें। निम्न दृश्य मॉडल की कल्पना कीजिए:

public class FooViewModel 
{ 
    public string Name {get; set;} 
    public DomainClass Genre {get;set;} 
} 

और निम्नलिखित DomainClass

//also applies to database data/POCO classes 
public class DomainClass 
{ 
    public int Id {get; set;}  
    public string Name {get;set;} 
} 

तो, अपने नियंत्रक में कहीं आप FooViewModel पॉप्युलेट करने और अपने दृश्य के लिए उस पर गुजरती हैं।

1) डोमेन मॉडल परिवर्तन:

अब, निम्न परिदृश्यों पर विचार करें।

इस मामले में आपको शायद दृश्य को समायोजित करने की आवश्यकता होगी, यह चिंताओं को अलग करने के संदर्भ में खराब अभ्यास है।

यदि आपने DomainModel से ViewModel को अलग किया है, तो मैपिंग में एक मामूली समायोजन (ViewModel => DomainModel (और back)) पर्याप्त होगा।

2) डोमेन क्लास ने गुणों को घोंसला दिया है और आपका दृश्य केवल GenreName प्रदर्शित करता है।

मैंने वास्तविक वास्तविक परिदृश्यों में यह गलत देखा है।

इस मामले में एक आम समस्या यह है कि @Html.EdittorFor का उपयोग नेस्टेड ऑब्जेक्ट के लिए इनपुट का कारण बन जाएगा। इसमें Id एस और अन्य संवेदनशील जानकारी शामिल हो सकती है। इस कोर्स के बाद, आप खुद को hidden इनपुट बनायेंगे। यदि आप इसे सर्वर साइड मॉडलबाइंडिंग या ऑटोमैपर के साथ जोड़ते हैं तो यह छिपी हुई Id के फायरबग जैसे उपकरणों के हेरफेर को अवरुद्ध करना वाकई मुश्किल है।

यद्यपि यह संभव है, संभवतः, उन क्षेत्रों में से कुछ को अवरुद्ध करने के लिए, अधिक घोंसला वाले डोमेन/डेटा ऑब्जेक्ट्स को अवरोधित करने के लिए, यह भाग सुरक्षित करने के लिए और अधिक कठिन हो जाएगा।और ध्यान रखें, कि आप अपने डोमेन मॉडल को उस कारण से बदलना चाहेंगे जो दृश्य को लक्षित नहीं कर रहा है। इसलिए आपके डोमेन मॉडल में प्रत्येक बदलाव के साथ आपको अवगत होना चाहिए कि नियंत्रक के दृश्य और सुरक्षा पहलुओं को प्रभावित कर सकता है।

3) एएसपीनेट-एमवीसी में सत्यापन गुणों का उपयोग करना आम है।

क्या आप वास्तव में अपने डोमेन को अपने विचारों के बारे में मेटाडेटा रखना चाहते हैं? या अपने डेटा-लेयर पर व्यू-लॉजिक लागू करें? क्या आपका व्यू-सत्यापन हमेशा डोमेन-सत्यापन के समान ही है? क्या यह वही सत्यापन तर्क है? क्या आप अपने डोमेन-मॉडल क्रॉस एप्लिकेशन का उपयोग कर रहे हैं? आदि

मुझे लगता है कि यह स्पष्ट है कि यह लेने का मार्ग नहीं है।

4) अधिक

मैं आप दे सकते हैं और अधिक परिदृश्य के, लेकिन यह क्या और अधिक आकर्षक है करने के लिए स्वाद का मामला है। मैं सिर्फ इस बिंदु पर आशा करता हूँ आप बिंदु मिल जाएगा :) फिर भी, मैं एक उदाहरण देने का वादा किया:

Scematic

अब, वास्तव में गंदा के लिए और quick-wins यह काम करेंगे, लेकिन मैं आपको लगता है नहीं है इसे चाहिए

यह दृश्य-मॉडल बनाने के लिए थोड़ा और प्रयास है, जो आम तौर पर डोमेन मॉडल के समान 80 +% के लिए होता है। यह अनावश्यक मैपिंग कर की तरह महसूस कर सकते हैं, लेकिन जब पहले वैचारिक अंतर पैदा होती है, तो आप पाएंगे कि यह प्रयास :)

एक विकल्प के रूप

तो लायक था, मैं एक सामान्य मामले के लिए निम्नलिखित सेटअप का प्रस्ताव:

  • एक viewmodel
  • एक domainmodel
  • एक डेटामॉडल
  • बनाने बनाने बनाने automapper की तरह एक पुस्तकालय का उपयोग दूसरे के (से मानचित्रण बनाने के लिए इसको Foo.FooProp मैप करने के लिए मदद मिलेगी)

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

वेब एपीआई/डेटा परत

फिर भी यह कैसे एक वेब एपीआई/एफई परिदृश्य में काम करेंगे की एक और ठोस उदाहरण:

Web Api Datalayer EF

टिप्पणी

जैसा कि @ mrjoltcola ने कहा: ध्यान में रखने के लिए एक अति-इंजीनियर घटक भी है। यदि उपरोक्त में से कोई भी लागू नहीं होता है, और उपयोगकर्ता/प्रोग्रामर पर भरोसा किया जा सकता है, तो आप जाने के लिए अच्छा लगा। लेकिन ध्यान रखें कि डोमेनमोडेल/व्यूमोडेल मिश्रण के कारण रखरखाव और पुनः उपयोगिता कम हो जाएगी।

13

राय तकनीकी सर्वोत्तम प्रथाओं और व्यक्तिगत वरीयताओं के मिश्रण से भिन्न होती है।

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

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

इंजेक्शन के खिलाफ सुरक्षा के लिए, अपने समग्र दृष्टिकोण से प्रासंगिक सुरक्षित प्रथाओं का उपयोग करें। यदि आप डोमेन ऑब्जेक्ट्स का उपयोग करने की योजना बना रहे हैं, तो नियंत्रक में या मॉडल बाइंडर एनोटेशन के माध्यम से सफेद सूचियों या काले सूचियों (समावेशन/बहिष्करण) का उपयोग करना सुनिश्चित करें। ब्लैक सूचियां अधिक सुविधाजनक हैं, लेकिन भविष्य में संशोधन लिखने वाले आलसी डेवलपर्स उनके बारे में भूल सकते हैं या उनसे अवगत नहीं हो सकते हैं। व्हाइट सूची ([बाइंड (शामिल = ...)] हैं अनिवार्य, ध्यान देने की आवश्यकता है जब नए क्षेत्रों, जोड़ रहे हैं तो वे एक इनलाइन दृश्य मॉडल के रूप में कार्य

उदाहरण:।

[Bind(Exclude="CompanyId,TenantId")] 
public class CustomerModel 
{ 
    public int Id { get; set; } 
    public int CompanyId { get; set; } // user cannot inject 
    public int TenantId { get; set; } // .. 
    public string Name { get; set; } 
    public string Phone { get; set; } 
    // ... 
} 

या

public ActionResult Edit([Bind(Include = "Id,Name,Phone")] CustomerModel customer) 
{ 
    // ... 
} 

पहला नमूना आवेदन भर में multitenant सुरक्षा लागू करने के लिए एक अच्छा तरीका है। दूसरा नमूना प्रत्येक कार्य को अनुकूलित कर सकते हैं।

अपने दृष्टिकोण में संगत और स्पष्ट रूप से दस्तावेज़ दृष्टिकोण अन्य डेवलपर्स के लिए आपके प्रोजेक्ट में उपयोग किया जाता है।

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

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