首页 > 解决方案 > 如何将不同的 ViewModel 传递给通用方法?

问题描述

我有一个用 C# MVC 5 编写的项目。有几个控制器/视图根据<input ...Razor 视图中的字段执行一组类似的功能。

当前每个控制器中都有将输入字段值保存到数据库表中的逻辑,然后允许检索这些保存的输入值并由它们填充视图的输入字段。

这些视图有许多相似之处,因此它们的几个字段在这些模型中重复。

在每个控制器中维护保存自己的字段的代码变得很困难,我想使用泛型来创建一个单一的、通用的例程来保存这些控制器中的任何一个的值。

例如,2 个简单的 ViewModel:

public class ViewModel1
{
    public string Name { get; set; }
    public int Unique1 { get; set; }
    ...
}

public class ViewModel2
{
    public string Name { get; set; }
    public int Unique2 { get; set; }
    ...
}

使用的数据库模型:

public class SavedInputs
{
        [Key] public int Id { get; set; }

        public string Name { get; set; }

        public int? Unique1 { get; set; }
        public int? Unique2 { get; set; }
}

现在我想创建一个可以保存 ViewModel 字段的函数。就像是:

public bool SaveToDb(T model)
{
    var inputs = new SavedInputs()
    {
        Name = model.Name,
        Unique1 = model.Unique1,
        Unique2 = model.Unique2
    }

    _db.SavedInputs.Add(inputs);

    ...
}

然后从每个控制器的 Save 操作:

public ActionResult SaveInputs(ViewModel1 model)
{
    var success = SaveToDb(model);
}

当然...上面的 SaveToDb() 不起作用,但希望它显示了我想要完成的工作。

标签: c#asp.net-mvc

解决方案


有很多方法可以做到这一点。

您可以拥有所有视图模型共享的公共接口或抽象类,它们具有您要保存的属性。然后SaveToDb只使用接口而不是泛型类型。然后,SaveToDb您可以从传入的模型中访问接口属性的所有属性,并对它们做任何您想做的事情。我想如果你只想拥有一些属性 null 那么抽象类是有意义的,因为你可以覆盖你想使用的任何东西,例如

public abstract class SavedInputsBase
{
    public virtual string Name { get; set; }
    public virtual int Unique1 { get; set; }
    public virtual int Unique2 { get; set; }
}

public class ViewModel1 : SavedInputsBase
{
    public override string Name { get; set; }
    public override int Unique1 { get; set; }
    ...
}

public class ViewModel2 : SavedInputsBase
{
    public override string Name { get; set; }
    public override int Unique2 { get; set; }
    ...
}

public bool SaveToDb(SavedInputsBase model)
{
    var inputs = new SavedInputs()
    {
        Name = model.Name,
        Unique1 = model.Unique1,
        Unique2 = model.Unique2
    }

    _db.SavedInputs.Add(inputs);
}

或者,您可以使用 Automapper nuget 包之类的东西,然后将视图模型映射SaveToDb到. 或者只是手动将它映射到您想要调用 SaveToDb 的任何地方。SavedInputsSavedInputs


推荐阅读