मुझे आज भी एक ही समस्या का सामना करना पड़ा। अपने आप की तरह मैं अपने मॉडल को सीधे अपने मॉडल से जोड़ता हूं लेकिन एक इंटरमीडिएट व्यूडाटा मॉडेल क्लास का उपयोग करता हूं जिसमें मॉडल का उदाहरण होता है और किसी भी पैरामीटर/कॉन्फ़िगरेशन जिन्हें मैं दृश्य में भेजना चाहता हूं।
मैंने को NullReferenceException
को बाधित करने के लिए डेटा एन्नोटेशन मॉडेलबिन्डर पर संशोधित करना समाप्त कर दिया, और मैं व्यक्तिगत रूप से गुणों को पसंद नहीं करता था अगर वे वैध थे (नीचे कारण देखें)।
protected override void BindProperty(ControllerContext controllerContext,
ModelBindingContext bindingContext,
PropertyDescriptor propertyDescriptor) {
string fullPropertyKey = CreateSubPropertyName(bindingContext.ModelName, propertyDescriptor.Name);
// Only bind properties that are part of the request
if (bindingContext.ValueProvider.DoesAnyKeyHavePrefix(fullPropertyKey)) {
var innerContext = new ModelBindingContext() {
Model = propertyDescriptor.GetValue(bindingContext.Model),
ModelName = fullPropertyKey,
ModelState = bindingContext.ModelState,
ModelType = propertyDescriptor.PropertyType,
ValueProvider = bindingContext.ValueProvider
};
IModelBinder binder = Binders.GetBinder(propertyDescriptor.PropertyType);
object newPropertyValue = ConvertValue(propertyDescriptor, binder.BindModel(controllerContext, innerContext));
ModelState modelState = bindingContext.ModelState[fullPropertyKey];
if (modelState == null)
{
var keys = bindingContext.ValueProvider.FindKeysWithPrefix(fullPropertyKey);
if (keys != null && keys.Count() > 0)
modelState = bindingContext.ModelState[keys.First().Key];
}
// Only validate and bind if the property itself has no errors
//if (modelState.Errors.Count == 0) {
SetProperty(controllerContext, bindingContext, propertyDescriptor, newPropertyValue);
if (OnPropertyValidating(controllerContext, bindingContext, propertyDescriptor, newPropertyValue)) {
OnPropertyValidated(controllerContext, bindingContext, propertyDescriptor, newPropertyValue);
}
//}
// There was an error getting the value from the binder, which was probably a format
// exception (meaning, the data wasn't appropriate for the field)
if (modelState.Errors.Count != 0) {
foreach (var error in modelState.Errors.Where(err => err.ErrorMessage == "" && err.Exception != null).ToList()) {
for (var exception = error.Exception; exception != null; exception = exception.InnerException) {
if (exception is FormatException) {
string displayName = GetDisplayName(propertyDescriptor);
string errorMessage = InvalidValueFormatter(propertyDescriptor, modelState.Value.AttemptedValue, displayName);
modelState.Errors.Remove(error);
modelState.Errors.Add(errorMessage);
break;
}
}
}
}
}
}
मैं भी इसे संशोधित इतना है कि यह हमेशा डेटा संपत्ति पर कोई फर्क नहीं पड़ता बांधता है अगर यह वैध है या नहीं। इस तरह से मैं सिर्फ मॉडल को वापस अमान्य अमान्य गुणों को रीसेट करने के लिए रीसेट कर सकता हूं।
नियंत्रक अंश
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(ProfileViewDataModel model)
{
FormCollection form = new FormCollection(this.Request.Form);
wsPerson service = new wsPerson();
Person newPerson = service.Select(1, -1);
if (ModelState.IsValid && TryUpdateModel<IPersonBindable>(newPerson, "Person", form.ToValueProvider()))
{
//call wsPerson.save(newPerson);
}
return View(model); //model.Person is always bound no null properties (unless they were null to begin with)
}
मेरे मॉडल वर्ग (व्यक्ति) एक वेब सेवा से आता है तो मैं नहीं विशेषताओं उन पर सीधे तरह से मैं इस प्रकार है हल डाल सकते हैं,:
नेस्टेड DataAnnotations
[Validation.MetadataType(typeof(PersonValidation))]
public partial class Person : IPersonBindable { } //force partial.
public class PersonValidation
{
[Validation.Immutable]
public int Id { get; set; }
[Validation.Required]
public string FirstName { get; set; }
[Validation.StringLength(35)]
[Validation.Required]
public string LastName { get; set; }
CategoryItemNullable NearestGeographicRegion { get; set; }
}
[Validation.MetadataType(typeof(CategoryItemNullableValidation))]
public partial class CategoryItemNullable { }
public class CategoryItemNullableValidation
{
[Validation.Required]
public string Text { get; set; }
[Validation.Range(1,10)]
public string Value { get; set; }
}
अब अगर मैं वायुसेना बाँध के साथ उदाहरण ओआरएम फ़ील्ड [ViewDataModel.]Person.NearestGeographicRegion.Text
& [ViewDataModel.]Person.NearestGeographicRegion.Value
मॉडलस्टेट सही ढंग से उन्हें सत्यापित करना शुरू कर देता है और डेटा एन्नोटेशन मॉडेलबिन्डर उन्हें सही तरीके से बांधता है।
यह उत्तर निश्चित नहीं है, यह आज दोपहर मेरे सिर को खरोंचने का उत्पाद है। यह ठीक तरह से परीक्षण नहीं किया गया है, हालांकि यह the project में यूनिट परीक्षण पास कर दिया गया है ब्रायन विल्सन ने शुरू किया और मेरा अधिकांश सीमित परीक्षण। इस मामले पर सच्चे बंद होने के लिए मुझे इस समाधान पर Brad Wilson विचार सुनना अच्छा लगेगा।
मेरे पास एक समान मॉडल है लेकिन आम तौर पर एक समय में अलग-अलग वस्तुओं को संपादित करता है। उदाहरण के लिए: मेरे पास एक घोषणा ऑब्जेक्ट है जिसमें संलग्नक (छवियों, पीडीएफ) की श्रृंखला हो सकती है या नहीं, लेकिन मैं घोषणा स्वयं को संपादित कर सकता हूं और इसलिए सत्यापनकर्ता को घोषणा की बाल वस्तुओं में उतरने के लिए मजबूर नहीं किया जाता है। मैं फिर बच्चे वस्तुओं को अलग से संपादित करूंगा - एक ही दृश्य, लेकिन अलग पोस्ट कार्रवाई। मुझे अब दिलचस्पी है - आपके कार्य कैसे काम करते हैं कि आप विशाल वस्तु पेड़ों को मान्य करते हैं? और यूआई इसके लिए कैसे काम करता है? –
दृश्यों के बारे में: मैंने वर्णन किया है कि यह कैसे करें http://devermind.com/linq/aspnet-mvc-using-custom-viewmodels-with-post-action-methods प्रमाणीकरण के संबंध में: अब तक मैं रहा हूं स्कॉट ग के ट्यूटोरियल में वर्णित तरीके से सर्वर-साइड सत्यापन का उपयोग करना: http://weblogs.asp.net/scottgu/archive/2009/03/10/free-asp-net-mvc-ebook-tutorial.aspx। मेरा नियंत्रक तब विभिन्न इकाइयों से सत्यापन त्रुटियों को इकट्ठा करता है: मॉडलस्टेट। AddRuleViolations (model.User.GetRuleViolations(), "उपयोगकर्ता"); ModelState.AddRuleViolations (model.Company.GetRuleViolations(), "कंपनी"); –
मुझे यकीन है कि यह मेरे मॉडल बाइंडर कोड में कहीं भी एक बग है, लेकिन मेरे पास इसे ट्रैक करने का समय नहीं है। अधिक दबाव देने वाले डिलिवरेबल्स रास्ते में हैं। :( –