我怎样才能使一个控制器动作采取动态参数? [英] How can I make a Controller Action take a dynamic parameter?

查看:71
本文介绍了我怎样才能使一个控制器动作采取动态参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够发布任何序列化对象的操作方法和实例张贴类型的新对象,以便使用 TryUpdateModel 。他们没有教我的任何这方面的东西的在QBasic中的帮助文件...我如何实例化基础上,发布的数据未知类型?

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

 公共无效保存(对象/动态什么的,字符串类型名){
    //实例类型发布
    // TryUpdateModel
    context.Entry(事).STATE = EntityState.Modified;
    context.SaveChanges();
}

下面是一个序列化对象的例子

<$p$p><$c$c>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嗒嗒
Thing.OptionID 1
Thing.ListItems.index 1
Thing.ListItems [1] .ID 1
Thing.ListItems [1] .Name点什么
Thing.ListItems [1] .OptionID 2
Thing.ListItems [1] .ThingID 1
Thing.ListItems [1] .EntityState 16


解决方案

您可以写,它使用反射和的typeName 参数自定义模型绑定:

 公共类MyModelBinder:DefaultModelBinder
{
    保护覆盖对象CreateModel(ControllerContext controllerContext,ModelBindingContext的BindingContext,类型modelType)
    {
        VAR typeValue = bindingContext.ValueProvider.GetValue(类型名称);
        如果(typeValue == NULL)
        {
            抛出新的异常(无法实例化一个模型\\的typeName \\未提供查询字符串参数);
        }
        VAR类型= Type.GetType(
            (字符串)typeValue.ConvertTo(typeof运算(字符串))
            真正
        );
        VAR模型= Activator.CreateInstance(类型);
        bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(()=&GT;型号,类型);
        回归模型;
    }
}

,然后简单:

  [HttpPost]
公众的ActionResult保存([ModelBinder的(typeof运算(MyModelBinder))对象模型)
{
    context.Entry(模型).STATE = EntityState.Modified;
    context.SaveChanges();
    返回查看();
}

I would like to be able to post any serialized object to an action method and instantiate a new object of the posted type in order to use TryUpdateModel. They didn't teach me any of this stuff in the QBasic help file... How can I instantiate the unknown type based on the posted data?

If it would help, I could theoretically include the name of the type as a string in the posted data. I was hoping to avoid that because it seemed like I would need the full name of the type.

public void Save(object/dynamic whatever, string typename) {
    //Instantiate posted type
    //TryUpdateModel
    context.Entry(Thing).State = EntityState.Modified;
    context.SaveChanges();
}

Here is an example of a serialized object

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

From Fiddler

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

解决方案

You could write a custom model binder which uses reflection and the typeName parameter:

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

and then simply:

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

这篇关于我怎样才能使一个控制器动作采取动态参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆