ASP.NET MVC 2 - 如何根据模型上下文正确切换视图?

时间:2011-04-08 18:53:12

标签: asp.net-mvc asp.net-mvc-2 asp.net-mvc-routing

我正在整理我的第一个MVC应用程序,并对如何正确实现我的目标提出疑问。这就是我正在尝试的......

我的应用程序中的一个区域显示了一批数据,一组Batch个对象。对于每个Batch,用户可以选择处理其数据。处理包括一系列步骤,我将以类似向导的视图链向用户呈现。

每个Batch都有一个类型。类型L的批次A可能包含X的记录,而类型M的批次B可能包含Y的记录。向导中的步骤将根据批次类型略有变化。我不想做的是(显然代码很差,只是为了说明):

ProcessController

public ActionResult StepOne(int id)
{
    var batch = BatchRepository.Batch.SelectById(id);
    var records = BatchRepository.Data.SelectForBatch(batch);

    switch (batch.BatchType)
    {
        case "X":
            return View("TypeXStepOne", records);
        case "Y":
            return View("TypeYStepOne", records);
        default:
            return View();
    }

}

public ActionResult StepTwo(int id)
{
    var batch = BatchRepository.Batch.SelectById(id);
    var records = BatchRepository.Data.SelectForBatch(batch);

    switch (batch.BatchType)
    {
        case "X":
            return View("TypeXStepTwo", records);
        case "Y":
            return View("TypeYStepTwo", records);
        default:
            return View();
    }

}

...

等等。这似乎是一种不好的做法,因为我的向导可能是4或5步,而且我目前有三种不同的批处理类型,这些操作中的代码量变得难以维护。

MVC在管理这方面可以做些什么?我想尽量减少所需的工作量,例如,如果引入了第四种类型。

我知道我可能会:

  • 每种批次类型的部分视图 然后进入向导中 真的没办法,虽然可以分享一些部分观点。

那么,每个批次类型都有一个专用的控制器会更好吗?我想我可以做这样的事情,其中​​批处理类型成为控制器名称。

BatchController

public ActionResult Process(int id)
{
    var batch = BatchRepository.Batch.SelectById(id);
    return RedirectToAction("StepOne", batch.BatchType, new { id = batch.Id });
}

但这取决于与控制器名称匹配的批处理类型名称,我也不一定喜欢。 更新:或者,最糟糕的情况是,我的三个批处理类型中只有一个switch语句,然后我可以转发到相应的控制器。

所以...想法!我需要他们。而且我没有这么远,我无法开始新的事情,我只是把想法作为MVC新手在脑海中挥舞。 MVC必须具有允许基于上下文进行动态视图切换的东西,无论是通过花哨的路由技术还是“ViewFactory”或其他一些技巧。

任何反馈都将不胜感激!

对于任何想知道的人,我都被困在.NET 3.5和IIS6上,这就是为什么我回到MVC 2而不是3。

UDPATE

这就是我现在正在推出的内容。我将BatchController分成多个控制器 - 每个批处理类型一个。由于它们大致相同,因此我创建了一个具有以下方法的抽象WizardController

public abstract ActionResult Step(int batchId, int stepNumber);

protected ViewResult ViewStep(int stepNumber, object model)
{
    return View(string.Format("Process\Step{0}", stepNumber), model);
}

在我的派生控制器中,例如:

public override ActionResult Step(int batchId, int stepNumber)
{
    var data = BatchRepository.BatchType.SelectByBatchId(batchId);

    return ViewStep(stepNumber, data);
}

这很快,看起来很脏,但在我学到更好的东西之前......谢谢!

2 个答案:

答案 0 :(得分:1)

您不需要switch语句。在适当的位置创建DisplayTemplates或EditorTempaltes文件夹,例如Views / Shared /并创建YourRecordType.cshtml文件,然后更改return语句以返回模型。例如

-View
 -Shared
  -DisplayTemplates
   -MyRecordTypeA.cshtml
   -MyRecordTypeB.cshtml

return View(records)

希望有所帮助。

答案 1 :(得分:1)

约定优于配置(新的硬编码),简单如下:

public ActionResult Step(int stepNo, int id)
{
    var batch = BatchRepository.Batch.SelectById(id);
    var records = BatchRepository.Data.SelectForBatch(batch);
    return View("Type"+batch.BatchType+"Step"+stepNo, records);    
}