MVC4最佳实践,包括Logic

时间:2013-12-05 21:02:23

标签: c# asp.net-mvc asp.net-mvc-4

我正在学习MVC并怀疑我是否以低效的方式编写控制器和模型。

我制作了以下示例来试图说明我的情况:

我倾向于将大部分逻辑放在我的模型中。一个简单的例子如下:

  public partial class TestModel
  {
    public List<TestObject> ReportData
    {
      get
      {
        TestRepository rep = new TestRepository ();
        return rep.GetData(IdObject);
      }
    }

    public int IdObject{ get; set; }
   }

只要设置了有效的IdObject,此模型就会生成ReportData。这种方法的一个优点是它可以导致更小的行动方法。

  public class TestController
  {
    public ActionResult Test1()
    {
      return View(new TestModel());
    }

    [HttpGet]
    public ActionResult Test2()
    {
      return View(new TestModel());
    }

    [HttpPost]
    public ActionResult Test3(TestModel model)
    {
      return View(model);
    }
}

而不是:

  public class TestController
  {
    public ActionResult Test1()
    {
      TestModel model = new TestModel();
      TestRepository rep = new TestRepository ();
      model.ReportData = rep.GetData(IdObject);
      return View(model);
    }

    [HttpGet]
    public ActionResult Test2()
    {
      TestModel model = new TestModel();
      TestRepository rep = new TestRepository ();
      model.ReportData = rep.GetData(IdObject);
      return View(model);
    }

    [HttpPost]
    public ActionResult Test3(TestModel model)
    {
      TestRepository rep = new TestRepository ();
      model.ReportData = rep.GetData(IdObject);
      return View(model);
    }
}

所以最后我通过在我的模型中尽可能多地使用逻辑来减少代码重用。 我眼中的另一个好处是,我可以让大多数属性只读,忘记某些东西或某人覆盖它们(打开colsed原则)。

我采用这种方法的问题是,有时属性的计算代价很高(它们可能来自数据库,或者可能是处理器密集型计算),并且有时会多次进行计算。

例如,如果我有一个包含以下代码的视图:

@if (Model.ReportData.Count() > 0)
                {
                    foreach (var item in Model.ReportData)
                    {
                        item
                    }
}

如何确保数据不是一次又一次地计算?如何更好地编写我的模型和控制器代码,是否有一些建议的最佳实践?

2 个答案:

答案 0 :(得分:2)

通常,逻辑应该在控制器中,而不是模型中。您可以让控制器调用共享私有方法,以避免重复自己。例如:

型号:

  public partial class TestModel
  {
    public List<TestObject> ReportData { get; set; }
    public int IdObject{ get; set; }
  }

控制器:

public class TestController
  {
    public ActionResult Test1()
    {
      return View(CreateTestModel());
    }

    [HttpGet]
    public ActionResult Test2()
    {
      return View(CreateTestModel());
    }

    [HttpPost]
    public ActionResult Test3(TestModel model)
    {
      return View(CreateTestModel());
    }

    private TestModel CreateTestModel() {
      TestModel model = new TestModel();
      TestRepository rep = new TestRepository ();
      model.ReportData = rep.GetData(IdObject);
      return model
    }
}

这也解决了当您的视图访问属性时没有计算任何数据的问题,因为您的控制器会填充属性,因此从模型中访问它们不会导致重新计算。

答案 1 :(得分:1)

到目前为止,我在这个问题上看到的最佳答案是Steve Smith在 ASPConf2012 上的ASP.NET MVC Solution Best Practices演示文稿。虽然它可能看起来像一个“长视频”,但它是值得的。

在其中,Smith采用现有解决方案并重构代码以遵循“Onion Architecture”,并向您展示MVC架构中哪些代码工件属于哪些。看到“之前”和“之后”代码库有助于理解“为什么”。

enter image description here

Here's the source code用于Smith在他的演示文稿中查看的示例应用程序。