1

我有一个稍微长一点的概念性问题,我想知道是否有人可以帮助我。

在 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) 

如果传入的 T 是接口而不是模型本身,则 createdRecords 不能像这样绑定,并且我找不到将表单数据映射到编译时未知类型的实例的真正方法。

我想知道是否有一种简单的方法可以在传入的对象类型的实例之间进行这种映射,我可以在运行时弄清楚,是否有其他方法可以设置我忽略的,或者如果这两者事情将是太多的工作,我不应该尝试这样的事情并像现在这样为每个模型构建一个控制器?

4

1 回答 1

0

以防其他人在未来发现此问题,这就是我迄今为止为解决我的问题所做的工作。首先,我下载了impromptu-interface代码库,它在处理动态类型时非常有用。

然后对于抽象控制器的保存方法,重要的是我可以绑定回原始对象类型,我这样做了。

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

从这里开始,一切都从前到后。也许有更好的方法,但这是迄今为止我能想到的最好的方法。

于 2013-05-16T13:56:06.750 回答