Asp.net mvc 如何使控制器操作采用动态参数?

Asp.net mvc 如何使控制器操作采用动态参数?,asp.net-mvc,asp.net-mvc-3,dynamic,controller,Asp.net Mvc,Asp.net Mvc 3,Dynamic,Controller,我希望能够将任何序列化对象发布到操作方法,并实例化发布类型的新对象,以便使用TryUpdateModel。他们没有教我QBasic帮助文件中的任何东西。。。如何根据发布的数据实例化未知类型 如果有帮助的话,理论上我可以将类型的名称作为字符串包含在发布的数据中。我希望避免这种情况,因为我似乎需要类型的全名 public void Save(object/dynamic whatever, string typename) { //Instantiate posted type //

我希望能够将任何序列化对象发布到操作方法,并实例化发布类型的新对象,以便使用
TryUpdateModel
。他们没有教我QBasic帮助文件中的任何东西。。。如何根据发布的数据实例化未知类型

如果有帮助的话,理论上我可以将类型的名称作为字符串包含在发布的数据中。我希望避免这种情况,因为我似乎需要类型的全名

public void Save(object/dynamic whatever, string typename) {
    //Instantiate posted type
    //TryUpdateModel
    context.Entry(Thing).State = EntityState.Modified;
    context.SaveChanges();
}
下面是一个序列化对象的示例

Thing.Id=1&Thing.Name=blah&Thing.OptionID=1&Thing.ListItems.index=1&Thing.ListItems%5B1%5D.Id=1&Thing.ListItems%5B1%5D.Name=whatever&Thing.ListItems%5B1%5D.OptionID=2&Thing.ListItems%5B1%5D.ThingID=1&Thing.ListItems%5B1%5D.EntityState=16
来自小提琴手

Thing.Id                            1
Thing.Name                          blah
Thing.OptionID                      1
Thing.ListItems.index               1
Thing.ListItems[1].Id               1
Thing.ListItems[1].Name             whatever
Thing.ListItems[1].OptionID         2
Thing.ListItems[1].ThingID          1
Thing.ListItems[1].EntityState      16

您可以编写一个使用反射和
typeName
参数的自定义模型活页夹:

public class MyModelBinder : DefaultModelBinder
{
    protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
    {
        var typeValue = bindingContext.ValueProvider.GetValue("typename");
        if (typeValue == null)
        {
            throw new Exception("Impossible to instantiate a model. The \"typeName\" query string parameter was not provided.");
        }
        var type = Type.GetType(
            (string)typeValue.ConvertTo(typeof(string)),
            true
        );
        var model = Activator.CreateInstance(type);
        bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, type);
        return model;
    }
}
然后简单地说:

[HttpPost]
public ActionResult Save([ModelBinder(typeof(MyModelBinder))] object model) 
{
    context.Entry(model).State = EntityState.Modified;
    context.SaveChanges();
    return View();
}

对相关参数使用自定义模型绑定器。然后参数可以是任何类型,比如
IGorilla.Bas
@bzlm我想知道是否需要这样做。我在MVC书籍和网上都有定制模型活页夹的例子。在这一点上我有点不知所措,或者我的咖啡水平可能有点高。这些例子似乎有不同的重点。你能告诉我如何使活页夹识别未知类型并通知控制器该类型的正确方向吗?我需要使用反射吗?谢谢。如果您明确表示某个操作方法的某个参数使用某个模型绑定器(即,
MyActionMethod([ModelBinder(typeof(MyModelBinder))]MyModel-MyModel)
),则不涉及猜测、识别或反射。它将仅仅依靠
MyModelBinder
myModel
(通过HTTP传递)转换为
myModel
。这是显式的和透明的,当您不想隐藏发生复杂绑定的事实时,它非常有用。您也可以为类型注册模型绑定,以避免在每个操作方法的参数上都需要该属性。@bzlm感谢您的回复。但我想我不明白。
MyModel
是否表示某种动态类型?action方法如何在运行时知道类型是什么?与默认设置不同,
MyModelBinder
需要做什么?唯一的动态类型是
dynamic
。但这在这里并不相关,因为action方法指定在所有模型绑定发生之后所需的最终结果类型。您问题中的示例可以使用默认模型绑定器提供的复杂模型绑定功能来完成,但是如果在编译时不知道生成的类型,那么action方法如何知道如何处理传递给该方法的对象?你在这里的实际情况是什么?你肯定不希望把事情概括得过于笼统?非常感谢你,达林。这对我非常有帮助。我们应该指出,这可能会造成安全问题,因为您允许某人指示您的系统创建任意类型的对象并为其属性设置值。是否有已知的.NET核心端口?