How to convert a http-request into the right object?

我只是一个虾纸丫 提交于 2019-12-01 19:40:41

Check the ModelBindingContext documentation.

Edited based on comments

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();
    }
}

Finaly i solved it with the workaround of carrying the name of the model in my model and dynamically create the right model in the modelbinder. If you know a better solution plz show me :-)

HomeController:

// CREATE
public ActionResult About(MBTest testItem)
{
    if (testItem == null)
    {
        testItem = new MBAbl();
        testItem.Model = "MBAbl";
    }

    return View(testItem);
}

Models:

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;
}

Try this:

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);;
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!