Model Binding on Multiple Model Form Submission from Strongly-Typed View

前端 未结 5 1465
情歌与酒
情歌与酒 2021-01-31 23:05

I\'m having problems binding on a form with multiple models being submitted. I have a complaint form which includes complaint info as well as one-to-many complainants. I\'m tr

5条回答
  •  迷失自我
    2021-01-31 23:33

    To get this to work without case-by-case workarounds you need to create your own model binder and override method SetProperty:

    public class MyDefaultModelBinder : DefaultModelBinder
    {
        protected override void SetProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, object value)
        { 
            ModelMetadata propertyMetadata = bindingContext.PropertyMetadata[propertyDescriptor.Name]; 
            propertyMetadata.Model = value;
            string modelStateKey = CreateSubPropertyName(bindingContext.ModelName, propertyMetadata.PropertyName);
    
            // Try to set a value into the property unless we know it will fail (read-only 
            // properties and null values with non-nullable types)
            if (!propertyDescriptor.IsReadOnly) { 
            try {
                if (value == null)
                {
                propertyDescriptor.SetValue(bindingContext.Model, value);
                }
                else
                {
                Type valueType = value.GetType();
    
                if (valueType.IsGenericType && valueType.GetGenericTypeDefinition() == typeof(EntityCollection<>))
                {
                    IListSource ls = (IListSource)propertyDescriptor.GetValue(bindingContext.Model);
                    IList list = ls.GetList();
    
                    foreach (var item in (IEnumerable)value)
                    {
                    list.Add(item);
                    }
                }
                else
                {
                    propertyDescriptor.SetValue(bindingContext.Model, value);
                }
                }
    
            }
            catch (Exception ex) {
                // Only add if we're not already invalid
                if (bindingContext.ModelState.IsValidField(modelStateKey)) { 
                bindingContext.ModelState.AddModelError(modelStateKey, ex); 
                }
            } 
            }
        }
    }
    

    Don't forget to register your binder in Global.asax:

    ModelBinders.Binders.DefaultBinder = new MyDefaultModelBinder();
    

提交回复
热议问题