C# 减少重复代码

C# 减少重复代码,c#,asp.net-mvc,asp.net-mvc-3,reflection,razor,C#,Asp.net Mvc,Asp.net Mvc 3,Reflection,Razor,我刚刚开始使用MVC设计模式,并爱上了它 我唯一讨厌的是它似乎产生了大量重复的代码。比如说 我有一个标准的MVC应用程序,在一个项目中包含我的DB(模型),在另一个项目中与我的控制器/视图/视图模型分离,在另一个项目中与我的测试方法分离。一切都很好 型号: 现在,我的DB项目中有一堆不错的EF4类,我必须在实际项目中使用ViewModels来访问我的数据。没问题 控制器: 然而,我拥有的每个控制器基本上都做着同样的事情。它从ViewModels获取和设置数据,因此,虽然每个控制器只获取不同的数据

我刚刚开始使用MVC设计模式,并爱上了它

我唯一讨厌的是它似乎产生了大量重复的代码。比如说

我有一个标准的MVC应用程序,在一个项目中包含我的DB(模型),在另一个项目中与我的控制器/视图/视图模型分离,在另一个项目中与我的测试方法分离。一切都很好

型号: 现在,我的DB项目中有一堆不错的EF4类,我必须在实际项目中使用ViewModels来访问我的数据。没问题

控制器: 然而,我拥有的每个控制器基本上都做着同样的事情。它从ViewModels获取和设置数据,因此,虽然每个控制器只获取不同的数据,但它们基本上都以相同的方式执行相同的工作。(我目前有9个,但很容易爆炸到超过50个)

例如:

public class Dummy1Controller : Controller
{
    private MyProj.Data.Entities _entities = new Data.Entities();
    private MyProj.Data.Entities2 _coreEntities = new Data.Entities2();

    //GET: /Customers/
    public ActionResult Index()
    {
        if (_entities.table1.Count() == 0) return View();

        var pastObj = _entities.table1.First();
        return View(new Table1ViewModel()
        {
            Id = pastObj.Id,
            FirstName = pastObj.FirstName,
            LastName = pastObj.LastName,
            .
            .
            .
            .
        });
    }
}

public class Dummy2Controller : Controller
{
    private MyProj.Data.Entities _entities = new Data.Entities();
    private MyProj.Data.Entities2 _coreEntities = new Data.Entities2();

    //GET: /Vehicles/
    public ActionResult Index()
    {
        if (_entities.table2.Count() == 0) return View();

        var pastObj = _entities.table2.First();
        return View(new Table1ViewModel()
        {
            RegNo = pastObj.RegNo,
            Make = pastObj.Make,
            Model = pastObj.Model,
            .
            .
            .
            .
        });
    }
}

public class Dummy3Controller : Controller
{
    private MyProj.Data.Entities _entities = new Data.Entities();
    private MyProj.Data.Entities2 _coreEntities = new Data.Entities2();

    //GET: /Invoices/
    public ActionResult Index()
    {
        if (_entities.table3.Count() == 0) return View();

        var pastObj = _entities.table3.First();
        return View(new Table1ViewModel()
        {
            InvNo = pastObj.InvNo,
            Amount = pastObj.Amount,
            Tax = pastObj.Tax,
            .
            .
            .
            .
        });
    }
}
观点: 从控件生成的每个视图都非常有效。Execpt,唯一改变的是数据(带有标签和文本框的字段)。再一次,它们都做同样的工作(但使用不同的数据集)

@model MyProject.Web.ViewModels.Table1ViewModel
@{
ViewBag.Title=“Index”;
}
顾客
@LabelFor(x=>x.Id)
@Html.TextBoxFor(model=>model.Id)
@LabelFor(x=>x.FirstName)
@Html.TextBoxFor(model=>model.FirstName)
@LabelFor(x=>x.LastName)
@Html.TextBoxFor(model=>model.LastName)
.
.
.
.
@{Html.RenderAction(“Index”,“FooterPartial”);}
--------------------------------------------------------------------------------------
@模型MyProject.Web.ViewModels.Table2ViewModel
@{
ViewBag.Title=“Index”;
}
车辆
@LabelFor(x=>x.RegNo)
@Html.TextBoxFor(model=>model.RegNo)
@LabelFor(x=>x.Make)
@Html.TextBoxFor(model=>model.Make)
@LabelFor(x=>x.PatientID)
@Html.TextBoxFor(model=>model.model)
.
.
.
.
@{Html.RenderAction(“Index”,“FooterPartial”);}
--------------------------------------------------------------------------------------
@模型MyProject.Web.ViewModels.Table3ViewModel
@{
ViewBag.Title=“Index”;
}
发票联
@LabelFor(x=>x.InvNo)
@Html.TextBoxFor(model=>model.InvNo)
@LabelFor(x=>x.Amount)
@Html.TextBoxFor(model=>model.Amount)
@LabelFor(x=>x.Tax)
@Html.TextBoxFor(model=>model.Tax)
.
.
.
.
@{Html.RenderAction(“Index”,“FooterPartial”);}
问题: 我想做一个单一的控制器,并使其动态。这样它就可以从不同的视图模型中读取数据。(为什么9个或50个控制器基本上做相同的工作)

然后我想对视图做同样的处理。这样可以动态生成不同的字段。(为什么有9或50个视图都做相同的工作)。如果视图基于控制器,则视图应能够根据其属性进行更改

基本上,我所要做的就是找到一种方法,告诉控制器从viewmodel X或VM-Y或VM-Z ect读取,它应该能够生成属性,检索相关数据,并将其传递给视图,视图在接收时将生成带有标签和文本框的字段

我想我想知道是否有任何方法可以使用反射来实现这一点。因为视图模型是具有简单属性的基本类。可以潜在地创建一个基本控制器类,该类具有一个方法来读取指定的viewmodel对象、获取其属性、同时读入关联表并将该表中的字段与该类中的属性相匹配。最后,可以将表中的记录传递给显示器。然后可以使用某种razor、c#或javascript基于此自动生成视图

如果可能或不可能,欢迎任何提示。

您可以使用删除用于在模型/实体之间复制值的所有代码

还考虑使用布局、数据注释属性和模板(用Html.DisplayFor和HTML .EddioRoto)缩小视图。


您可以研究创建通用基本控制器类的可能性,该类将采用模型和实体的类型,并包含CRUD操作的公共逻辑,但是,这可能是一个太远的步骤,会阻碍您以后的开发。

我认为一个动态控制器可能是一个太远的步骤-当您将所有内容都设置为通用,然后其中一个视图需要比简单的数据库映射更复杂的内容时会发生什么-您是否扩展了“通用视图控制器”来处理这些问题这可能会结束

您可能应该看看Automapper,以消除处理viewmodels时的一些重复性


您可以为对象或ur基类生成EditFor/Model templates,不管它是什么,然后只创建一个视图,它将接受您的模型及其元数据(在mvc metadataproviders的帮助下),并根据需要动态构建字段。
它可以在mvc2中实现,但是你也可以很容易地将这种技术应用到MVC3中。。

我在一个mi工作的项目中使用了这样一个模板,我有几十个不同的实体,它们都有相同的外观和感觉。在我自己的Metadataprovider的帮助下,这也帮助我获得字段的顺序以及它们在每个视图中的可视性,我构建了一个视图来精确显示我的所有实体

我同意这里的其他人的观点
@model MyProject.Web.ViewModels.Table1ViewModel

@{
    ViewBag.Title = "Index";
}

<link href="@Url.Content("~/Content/CSS/GenericDetailStyles.css")" rel="stylesheet" type="text/css" />

<section id="content">
    <div id="table">
        <div>
            <h2>Customer</h2>
        </div>
        <div class="row">
            <div class="left">@Html.LabelFor(x=>x.Id)</div>
            <div class="right">@Html.TextBoxFor(model => model.Id)</div>
        </div>
        <div class="row">
            <div class="left">@Html.LabelFor(x=>x.FirstName)</div>
            <div class="right">@Html.TextBoxFor(model => model.FirstName)</div>
        </div>
        <div class="row">
            <div class="left">@Html.LabelFor(x=>x.LastName)</div>
            <div class="right">@Html.TextBoxFor(model => model.LastName)</div>
        </div>
        .
        .
        .
        .
    </div>
</section>

@{Html.RenderAction("Index", "FooterPartial");}


--------------------------------------------------------------------------------------


@model MyProject.Web.ViewModels.Table2ViewModel

@{
    ViewBag.Title = "Index";
}

<link href="@Url.Content("~/Content/CSS/GenericDetailStyles.css")" rel="stylesheet" type="text/css" />

<section id="content">
    <div id="table">
        <div>
            <h2>Vehicle</h2>
        </div>
        <div class="row">
            <div class="left">@Html.LabelFor(x=>x.RegNo)</div>
            <div class="right">@Html.TextBoxFor(model => model.RegNo)</div>
        </div>
        <div class="row">
            <div class="left">@Html.LabelFor(x=>x.Make)</div>
            <div class="right">@Html.TextBoxFor(model => model.Make)</div>
        </div>
        <div class="row">
            <div class="left">@Html.LabelFor(x=>x.PatientID)</div>
            <div class="right">@Html.TextBoxFor(model => model.Model)</div>
        </div>
        .
        .
        .
        .
    </div>
</section>

@{Html.RenderAction("Index", "FooterPartial");}


--------------------------------------------------------------------------------------


@model MyProject.Web.ViewModels.Table3ViewModel

@{
    ViewBag.Title = "Index";
}

<link href="@Url.Content("~/Content/CSS/GenericDetailStyles.css")" rel="stylesheet" type="text/css" />

<section id="content">
    <div id="table">
        <div>
            <h2>Invoice</h2>
        </div>
        <div class="row">
            <div class="left">@Html.LabelFor(x=>x.InvNo)</div>
            <div class="right">@Html.TextBoxFor(model => model.InvNo)</div>
        </div>
        <div class="row">
            <div class="left">@Html.LabelFor(x=>x.Amount)</div>
            <div class="right">@Html.TextBoxFor(model => model.Amount)</div>
        </div>
        <div class="row">
            <div class="left">@Html.LabelFor(x=>x.Tax)</div>
            <div class="right">@Html.TextBoxFor(model => model.Tax)</div>
        </div>
        .
        .
        .
        .
    </div>
</section>

@{Html.RenderAction("Index", "FooterPartial");}