मेरे पास एक मॉडल है जिसमें एक पता और व्यक्ति दो बार होता है, एक बार "मुख्य" संपर्क के लिए, और एक बार "चालान" संपर्क के लिए, और एक बूलियन मान InvoiceContactSameAsMain - एक अनाड़ी नाम, लेकिन वर्णनात्मक। संपत्ति का प्राप्तकर्ता यह देखने के लिए जांचता है कि क्या "मुख्य" और "चालान" के लिए पता और संपर्क ऑब्जेक्ट समान हैं, और यदि वे हैं तो सत्य लौटाते हैं। सेटर यह देखने के लिए जाँच करता है कि क्या मान सही है, और यदि ऐसा है, तो चालान व्यक्ति पर मुख्य व्यक्ति और चालान पते पर मुख्य पता की प्रतिलिपि बनाता है।

मेरे विचार में, बूलियन मान को चेक बॉक्स द्वारा दर्शाया जाता है (जैसा कि आप उम्मीद करेंगे)। इसके साथ एक छोटा JS फ़ंक्शन जुड़ा हुआ है, जो चेक बॉक्स को चेक करने पर, इनवॉइस फ़ील्ड को छुपाता है और डेटा-वैल HTML विशेषता को गलत पर सेट करके क्लाइंट-साइड सत्यापन को "स्विच ऑफ" करता है और विनीत के पुन: पार्स को मजबूर करता है। प्रपत्र में सत्यापन विशेषताएँ। बॉक्स को अनचेक करना स्वाभाविक रूप से फ़ील्ड दिखाता है और सत्यापन को वापस चालू करता है।

यह सब ठीक काम करता है, जब तक कि मैं अपने नियंत्रक तक नहीं पहुंच जाता।

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

क्या यहां कुछ स्पष्ट है जो मैंने यहां याद किया है जो मुझे मॉडलस्टेट को फिर से सत्यापित करने की अनुमति देगा? मैंने TryUpdateModel और TryValidateModel को आजमाया है, लेकिन वे दोनों कैश किए गए मॉडलस्टेट मानों का उपयोग करते प्रतीत होते हैं। मैंने "फिक्स्ड" मॉडल में गुजरते हुए, फिर से अपने एक्शन को दोबारा कॉल करने का भी प्रयास किया है। मैं लगभग आभारी हूं कि किसी ने काम नहीं किया।

कृपया मुझे बताएं कि क्या कोई और विवरण या उदाहरण मदद करेगा।

संपादित करें: जाहिर है, अगर समस्या से संपर्क करने का यह पूरी तरह गलत तरीका है, तो बस मुझे बताएं।

संपादित करें 2: रॉन सिजम के सुझाव के अनुसार जोड़े गए कोड नमूने।

मॉडल इस प्रकार है: सार्वजनिक वर्ग विवरण { public int? उपयोगकर्ता आईडी {प्राप्त करें; सेट; }

    public Company Company { get; set; }

    public Address CompanyAddress { get; set; }
    public Person MainPerson { get; set; }

    public Address InvoiceAddress { get; set; }
    public Person InvoiceContact { get; set; }

    [Display(Name = "Promotional code")]
    [StringLength(20, ErrorMessage = "Promotional code should not exceed 20 characters")]
    public string PromotionalCode { get; set; }

    [Display(Name = "Invoice contact same as main")]
    public bool InvoiceContactSameasMain
    {
        get { return InvoiceContact.Equals(MainPerson); }
        set
        {
            if (value)
            {
                InvoiceContact = MainPerson.Copy();
                InvoiceAddress = CompanyAddress.Copy();
            }
        }
    }

    [_Common.MustAccept]
    [Display(Name = "I agree with the Privacy Policy")]
    public bool PrivacyFlag { get; set; }

    [Display(Name = "Please subscribe to Sodexo News Letter")]
    public bool MarketingOption { get; set; }

    [Display(Name = "Contract number")]
    public int? ContractNumber { get; set; }

    public Details()
    {
        Company = new Company();
        CompanyAddress = new Address();
        MainPerson = new Person();
        InvoiceAddress = new Address();
        InvoiceContact = new Person();
    }
}

यह एक व्यूमोडेल में लपेटा गया है क्योंकि पृष्ठ में कई चयन सूचियां शामिल हैं:

public class DetailsViewModel
{
    public Details    Details              { get; set; }
    public SelectList MainContactTitles    { get; set; }
    public SelectList InvoiceContactTitles { get; set; }
    public SelectList SICCodes             { get; set; }
    public SelectList TypesOfBusiness      { get; set; }
    public SelectList NumbersOfEmployees    { get; set; }

    public DetailsViewModel()
    {
    }
}

नियंत्रक की दो प्रासंगिक क्रियाएं इस प्रकार हैं:

public class DetailsController : _ClientController
{
    [Authorize]
    public ActionResult Index()
    {
        DetailsViewModel viewModel = new DetailsViewModel();
        if (Client == null)
        {
            viewModel.Details = DetailsFunctions.GetClient((int)UserId, null);
        }
        else
        {
             viewModel.Details = DetailsFunctions.GetClient((int)UserId, Client.ContractNumber);
        }
        viewModel.MainContactTitles = DetailsFunctions.GetTitles((int)UserId, viewModel.Details.MainPerson.title);
        viewModel.InvoiceContactTitles = DetailsFunctions.GetTitles((int)UserId, viewModel.Details.InvoiceContact.title);
        viewModel.SICCodes = DetailsFunctions.GetSICCodes(viewModel.Details.Company.sic_code);
        viewModel.NumbersOfEmployees = DetailsFunctions.GetNumbersOfEmployees(viewModel.Details.Company.number_of_employees);
        viewModel.TypesOfBusiness = DetailsFunctions.GetTypesOfBusiness(viewModel.Details.Company.public_private);
        return View(viewModel);
    }

    [Authorize]
    [HttpPost]
    public ActionResult Index(DetailsViewModel ViewModel)
    {
        if (ModelState.IsValid)
        {
            //go to main page for now
            DetailsFunctions.SetClient((int)UserId, ViewModel.Details);
            return RedirectToAction("Index", "Home");
        }
        else
        {
            ViewModel.MainContactTitles = DetailsFunctions.GetTitles((int)UserId, ViewModel.Details.MainPerson.title);
            ViewModel.InvoiceContactTitles = DetailsFunctions.GetTitles((int)UserId, ViewModel.Details.InvoiceContact.title);
            ViewModel.SICCodes = DetailsFunctions.GetSICCodes(ViewModel.Details.Company.sic_code);
            ViewModel.NumbersOfEmployees = DetailsFunctions.GetNumbersOfEmployees(ViewModel.Details.Company.number_of_employees);
            ViewModel.TypesOfBusiness = DetailsFunctions.GetTypesOfBusiness(ViewModel.Details.Company.public_private);
            return View(ViewModel);
        }
    }
}

यदि आवश्यक हो तो मैं दृश्य और जेएस प्रदान कर सकता हूं, लेकिन चूंकि मॉडल बाध्यकारी सब ठीक काम कर रहा है, मुझे यकीन नहीं है कि यह कितनी मदद है।

2
Simon Rolfe 10 नवम्बर 2011, 19:52
1
मुझे लगता है कि आपके पास जो कुछ है उसका एक कोड नमूना मदद करेगा
 – 
Ron Sijm
10 नवम्बर 2011, 19:56
डिबगिंग करते समय आप देख सकते हैं कि ModelState.IsValid झूठा क्यों है। यदि आप कुछ नोड्स का विस्तार करते हैं तो आप देखेंगे कि कौन सा नियम विफल हुआ।
 – 
Darcy
10 नवम्बर 2011, 19:57
@ डार्सी: जो नियम विफल हो रहे हैं वे कॉपी-ओवर चालान पते और व्यक्ति में हैं। सत्यापनकर्ता अभी भी उन्हें रिक्त के रूप में देखता है, भले ही मैं उन्हें मॉडल में सही ढंग से भरते हुए देख सकता हूं।
 – 
Simon Rolfe
10 नवम्बर 2011, 20:04
मैंने अपने "चालान संपर्क को मुख्य के समान" तर्क को अपने सिर पर बदलने की कोशिश की है: यह अब एक साधारण बूलियन मान है, और चालान संपर्क और चालान पते के लिए गेटर्स इसे जांचें और बूलियन मान होने पर मुख्य संपर्क (या पता) वापस कर दें सच हैं। इसका समस्या पर कोई प्रभाव नहीं पड़ा, और मॉडलस्टेट अभी भी सोचता है कि वे फ़ील्ड खाली हैं, भले ही मॉडल उन्हें स्पष्ट रूप से भरा हुआ दिखाता है।
 – 
Simon Rolfe
10 नवम्बर 2011, 20:59

1 उत्तर

सबसे बढ़िया उत्तर

यह एक मामूली बकवास हैक है, लेकिन मैंने ModelState.IsValid की जांच करने से पहले नियंत्रक में प्रासंगिक फ़ील्ड के लिए मॉडलस्टेट त्रुटियों को साफ़ कर दिया है:

if(ViewModel.Details.InvoiceContactSameasMain)
        {
            //iterate all ModelState values, grabbing the keys we want to clear errors from
            foreach (string Key in ModelState.Keys)
            {
                if (Key.StartsWith("Details.InvoiceContact") || Key.Startwith("Details.InvoiceAddress"))
                {
                    ModelState[Key].Errors.Clear();
                }
            }
        }

केवल उल्टा है, यदि व्यक्ति या पता ऑब्जेक्ट बदलते हैं, तो इस कोड को बदलने की आवश्यकता नहीं होगी।

3
Simon Rolfe 11 नवम्बर 2011, 15:32
+1 यह एकमात्र ऐसी चीज है जो एक समान समस्या के लिए मुझे एक कामकाजी समाधान जैसा दिखता है। ऐसा लगता है कि एक बेहतर तरीका होना चाहिए लेकिन मुझे नहीं पता कि यह क्या है।
 – 
Corin
17 अप्रैल 2013, 19:25