2012-01-11 17 views
7

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

public class BaseLocation 
{ 
    [Display(Name="Your Name")] 
    public string Name {get;set;} 

    public virtual string Address {get;set;} 
} 

public class CustomerLocation : BaseLocation 
{ 
    [Display(Name="Customer Address")] 
    public override string Address {get;set;} 
} 

public class EmployeeLocation : BaseLocation 
{ 
    [Display(Name="Employee Address")] 
    public override string Address {get;set;} 
} 

तब मैं, आधार स्थान के लिए एक आंशिक बनाया था, इसलिए जैसे:

यहाँ मैं क्या हासिल करना कोशिश कर रहा हूँ की एक सरलीकृत संस्करण है,

@model BaseLocation 
***ASP.NET MVC Helpers here: labels, text, validation, etc. 

अंत में ग्राहक में और कर्मचारी पृष्ठ, मैं आंशिक कॉल करता हूं और इसे उप-वर्गीकृत प्रकार भेजता हूं।

Customer.cshtml 
@model CustomerLocation 
@Html.Render("_BaseLocation", Model) 


Employee.cshtml 
@model EmployeeLocation 
@Html.Render("_BaseLocation", Model) 

परिणाम यह है कि मुझे विशिष्ट प्रकार के लिए डेटा विशेषताओं को नहीं दिखाई देगा। तो उदाहरण के लिए, ग्राहक पृष्ठ में, मुझे "ग्राहक पता" के बजाय "पता" का एक लेबल मिलेगा।

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

+0

आधार सार बनाने का प्रयास करें, देखें कि यह कुछ भी बदलता है या नहीं। – gdoron

+0

@gdoron, यह कुछ भी नहीं बदलेगा। –

+0

@DarinDimitrov, तो एकमात्र तरीका जिसके बारे में मैं सोच सकता हूं वह अपना 'एचटीएमएलहेल्पर' लिख रहा है जो सही काम करता है। – gdoron

उत्तर

1

दृश्य विरासत कैसे काम करता है और मॉडल को परिभाषित किया गया है कि LabelFor और TextBoxFor जैसे किसी पैरामीटर में पारित पैरामीटर कक्षा में परिभाषित मॉडल प्रकार का उपयोग करता है। आपके मामले में यह हमेशा BaseLocation होगा, यही कारण है कि इसे ओवरराइड नहीं किया जा रहा है।

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

Customer.cshtml 
@model CustomerLocation 
@Html.Render("_CustomerBaseLocation", Model) 


Employee.cshtml 
@model EmployeeLocation 
@Html.Render("_EmployeeBaseLocation", Model) 

मैं निश्चित रूप से अपने मुद्दे को समझने के बाद से आप केवल एक ही दृश्य को बदलना चाहते हैं और आप पहले से ही BaseLocation साथ स्थितियों के इन समान प्रकार के कई हो सकता था।

आप कुछ इस तरह कर सकता है ...

public static IHtmlString LabelTextFor<TModel, TValue>(this HtmlHelper<TModel> html, object model, Expression<Func<TModel, TValue>> expression) 
{ 
    MemberExpression memberExpression = (MemberExpression)expression.Body; 
    var propertyName = memberExpression.Member is PropertyInfo ? memberExpression.Member.Name : null; 

    //no property name 
    if (string.IsNullOrWhiteSpace(propertyName)) return MvcHtmlString.Empty; 

    //get display text 
    string resolvedLabelText = null; 
    var displayattrib = model.GetType().GetProperty(propertyName) 
       .GetCustomAttributes(true) 
       .SingleOrDefault(f => f is DisplayAttribute) 
             as DisplayAttribute; 
    if (displayattrib != null) { 
     resolvedLabelText = displayattrib.Name; 
    } 

    if (String.IsNullOrEmpty(resolvedLabelText)) { 
     return MvcHtmlString.Empty; 
    } 

    TagBuilder tag = new TagBuilder("label"); 
    tag.Attributes.Add("for", TagBuilder.CreateSanitizedId(html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(""))); 
    tag.SetInnerText(resolvedLabelText); 
    return new HtmlString(tag.ToString()); 
} 

फिर अपनी _BaseLocation.cshtml आप एक कॉल की तरह होगा:

@Html.LabelTextFor(Model, m => m.Address) 

एक कस्टम विस्तार विधि लेखन ऐसा करने के लिए लगभग

+0

यह विशेष विधि 'DisplayAttribute' पर निर्भर करती है और वैकल्पिक विधियों की अनुमति नहीं देती है मॉडल मेटाडेटा जोड़ने के लिए जैसे 'IModelMetadata' का उपयोग करना। – Buildstarted

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