. net MVC在运行时将动态类型绑定到模型
本文关键字:类型 绑定 模型 动态 MVC 运行时 net | 更新日期: 2023-09-27 18:13:02
我有一个稍长的概念性问题,我想知道是否有人可以帮助我。
在MVC中,我建立了一个网站,使用kendoui的框架构建网格。
我网站上的所有网格都是完全相同的,除了它们使用的模型和需要为每个模型实现的CRUD方法。我在每个模型实现CRUD方法的接口的地方设置了一些东西,如下所示,以便在一个地方获得所有逻辑。
//Actual interface has variables getting passed
public interface IKendoModelInterface
{
void Save();
void Read();
void Delete();
}
public class Model1: IKendoModelInterface
{
[Key]
public int IdProperty1 { get; set; }
public int SomeProperty2 { get; set; }
public string SomeProperty3 { get; set; }
public void Save(){
//Implement Save
}
public void Read(){
//Implement Read
}
public void Delete(){
//Implement Delete
}
}
然后,为了加快编写所有脚手架动作方法所需的网格工作,我创建了一个抽象控制器,可以调用传递给它的模型的接口方法。
//Implement the AJAX methods called by the grid
public abstract class KendoGridImplController<T> : Controller where T : class, IKendoModelInterface
{
// Method called from kendo grid
public virtual ActionResult Create([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = "models")]IEnumerable<T> createdRecords)
{
//Invoke Create Method for Model and return results
}
public virtual ActionResult Read([DataSourceRequest]DataSourceRequest request, int Id)
{
//Invoke read method for model and return results
}
//Update and Delete also implemented..
}
然后,我只需要每个模型都有一个控制器来实现上面的抽象控制器,传入正在使用的模型的类型。
public class ResponsibilityMatrixController : KendoGridImplController<Model1>
{
//Set up the page the grid will be on
public ActionResult Index(int id)
{
return View("SharedGridView", id);
}
//Can override abstract methods if needed but usually won't need to
}
我想知道我是否可以更进一步,或者我是否已经走到了尽头。对我来说,它似乎只是更重复的代码,如果我必须创建一个控制器每个模型什么也不做,但在类型传递给抽象控制器,并调用相同的视图。
我昨天尝试了很长一段时间来弄清楚我是否可以动态地将类型分配给抽象控制器。我设置了一些东西,我通过字符串发送回模型的类型,我仍然可以调用所需的方法。它失败的地方是,默认情况下,映射不能再在任何控制器操作上完成,因为在编译时类型是未知的。如
public virtual ActionResult Create([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = "models")]IEnumerable<T> createdRecords)
createdRecords不能像这样绑定,如果传入的T是一个接口而不是模型本身,我发现没有真正的方法将表单数据映射到编译时不知道的类型的实例。
我想知道是否有一种简单的方法可以在传入的对象类型的实例之间进行映射这样我就可以在运行时弄清楚,是否有其他方法可以设置这个,但我忽略了或者这两种方法都太费时了我不应该像现在这样尝试这样为每个模型建立一个控制器?
如果将来有人发现这一点,这是我迄今为止为解决我的问题所做的。首先,我下载了临时接口代码库,它在处理动态类型时非常有用。
然后对于抽象控制器的保存方法,我可以绑定回原始对象类型,我这样做了。
// Method called from kendo grid
public virtual ActionResult Create([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = "models")]IEnumerable<ExpandoObject> createdRecords)
{
Type originalGridType = GetTypeOfModelUsingCustomCodeIDevelopedEarlier();
foreach (ExpandoObject record in createdRecords)
{
var convertedType = Impromptu.InvokeConvert(record, originalGridType);
T objectInstance = Impromptu.ActLike(convertedType);
objectInstance.Save();
}
}
然后我只需要在我的模型中添加一个转换,可以从ExpandoObject转换到我的模型。我仍然希望没有一个额外的方法,但是有了我编写的一些辅助方法,就不需要编写太多代码了。
public static implicit operator Model1(ExpandoObject expando)
{
Model1 model = new Model1();
//Set fields of model...
//....
return model;
}
从这里一切都是前后脚的。也许有更好的方法,但这是目前为止我能想到的最好的方法。