在我的ASP.Net MVC3项目中,我创建了一个绑定基本模型的ModelBinder。在我的View中,我从Model继承自我的basemodel创建了一个对象。现在我不知道当我按下提交按钮时,我的ModelBinder中通过反射创建了哪个模型,但是如何?
ModelBinder的:
public class MBTestBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
//need to know which Model was created -> convert into the right object
//reflection?
}
}
型号:
[ModelBinder(typeof(MBTestBinder))]
public class MBTest
{
public string Name { get; set; }
public MBTest() {}
}
public class MBAbl : MBTest
{
public MBAbl() {}
public string House { get; set; }
}
查看:
@model ModelBinderProject.Models.MBTest
@using (Html.BeginForm("Index", "Home")) {
<fieldset>
<div class="editor-field">
@Html.EditorForModel(Model)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
控制器:
public ActionResult Create(MBTest testItem)
{
//on init get a view from a class that hast inherit the class MBTest
if (testItem.Name == null ) testItem = new MBAbl();
return View(testItem);
}
编辑:
使用bindingContext.ValueProvider.GetValue("House")
我可以获取表单的值,但bindingContext.ModelType
认为我的模型是MBTest
答案 0 :(得分:0)
查看ModelBindingContext文档。
根据评论编辑
public class MBTestBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var result = bindingContext.ValueProvider.GetValue("Name");
if (result == null || string.IsNullOrEmpty(result.AttemptedValue))
return new MBAbl();
else
return new MBTest();
}
}
答案 1 :(得分:0)
最后,我解决了它在我的模型中携带模型名称的变通方法,并在模型绑定器中动态创建了正确的模型。 如果你知道一个更好的解决方案,请告诉我: - )
HomeController中:
// CREATE
public ActionResult About(MBTest testItem)
{
if (testItem == null)
{
testItem = new MBAbl();
testItem.Model = "MBAbl";
}
return View(testItem);
}
型号:
public class MBTest
{
public MBTest() {}
[HiddenInput]
public string Model { get; set; }
public string Name { get; set; }
}
public class MBAbl : MBTest
{
public MBAbl() {}
public string House { get; set; }
}
public class MBAb2 : MBTest
{
...
}
ModelBinder的:
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
if (controllerContext == null) throw new ArgumentNullException("controllerContext");
if (bindingContext == null) throw new ArgumentNullException("bindingContext");
//string 'Model' is needed in the base class
var modelType = bindingContext.ValueProvider.GetValue("Model");
if (modelType != null && !string.IsNullOrEmpty(modelType.AttemptedValue))
{
string projectName = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
Type classtype = Type.GetType(string.Format("{0}.Models.{1}", projectName, modelType.AttemptedValue));
PropertyInfo[] properties = classtype.GetProperties();
var classObject = classtype.GetConstructor(new Type[] { }).Invoke(null);
foreach (PropertyInfo propertie in properties)
{
var value = bindingContext.ValueProvider.GetValue(propertie.Name).AttemptedValue;
classtype.GetProperty(propertie.Name).SetValue(classObject, value, null);
}
return classObject;
}
return null;
}
答案 2 :(得分:0)
试试这个:
public class ModelBinder : DefaultModelBinder, IModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var typeValue = bindingContext.ValueProvider.GetValue("ModelType");
var type = Type.GetType("Namespace.a.b." + typeValue.AttemptedValue.ToString());
var model = Activator.CreateInstance(type);
//Change the model
bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, type);
bindingContext.ModelMetadata.Model = model;
//Here, we used the default model binder of the mvc
return base.BindModel(controllerContext, bindingContext);;
}
}