ASP.NET MVC 3.0中的状态模式

时间:2011-10-05 07:56:00

标签: c# asp.net-mvc asp.net-mvc-3 design-patterns

我的申请表中有一个注册页面。它有3个状态和1个错误状态(如果有任何错误):

  1. 填写基本信息
  2. 选择包
  3. 说谢谢
  4. 错误
  5. 现在我想在这里使用状态模式。首先我创建了一个控制台应用程序,没问题。现在我想在我的MVC应用程序中实现这个逻辑,但我对结构感到困惑。我的意思是我需要多少视图,模型和控制器以及放置逻辑的位置。

2 个答案:

答案 0 :(得分:5)

1个控制器RegistrationController

6种行动方法

  • 获取索引的GET + POST(填写基本信息)
  • GET + POST for Package
  • GET for Thank you
  • GET for Error

这是让你的思绪开始的粗略代码:

public class RegistrationController : Controller
{
    public ActionResult Index()
    {
        RegistrationState model = RegistrationState.Init();
        // just display the "Fill Basic Info" form
        return View(model);
    }

    [HttpPost]
    public ActionResult Index(RegistrationState data)
    {
        // process data and redirect to next step
        this.TempData["RegState"] = data;
        if (!this.ModelState.IsValid || data.State == State.Error)
        {
            // error should handle provided state and empty one as well
            return RedirectToAction("Error");
        }
        return RedirectToAction("Package");
    }

    public ActionResult Package()
    {
        RegistrationState data = this.TempData["RegState"] as RegistrationState;
        if (data == null)
        {
            return RedirectToAction("Error");
        }

        // get packages and display them
        IList<Package> model = this.repository.GetPackages();
        return View(new Tuple.Create(data, model));
    }

    [HttpPost]
    public ActionResult Package(RegistrationState data)
    {
        // process data blah blah blah
    }

    // and so on and so forth
    ....
}

正如您所看到的,您仍然需要编写一些与MVC相关的代码来处理状态更改。在我的例子中,一切都是在动作方法中完成的。但也可以使用动作过滤器。如果你不能提出一个可以服务于许多不同状态对象的通用动作过滤器,那么最好只用动作方法编写代码。

另一种方法

如果你对Asp.net MVC足够了解你可以更进一步,并编写一个状态机ControllerFactory,它将在某种意义上与路由一起工作:

{StateObjectType}/{State}
因此,ControllerFactory能够将视图数据解析为已知的状态对象类型,并将执行传递给特定的操作。据国家报道。这将使它成为适合Asp.net MVC应用程序的特殊状态机。

更重要的问题当然是你是否可以使用这种模式创建整个应用程序,或者只是它的某些部分应该像这样工作。您当然可以将两种方法结合起来,并为每种方法提供适当的路由。

重要告示

  1. 您应该非常小心地定义错误状态,因为输入无效字段数据不应该导致错误状态,而是导致实际显示在具有无效数据的字段旁边的视图中的数据验证错误(即。无效日期提供为13/13/1313)。您的错误状态应仅用于与用户输入无关的实际对象状态错误。那会是什么超出我的想象。

    正如我在评论中所提到的,你应该查看一些Asp.net MVC介绍视频,你会看到验证如何在Asp.net MVC中运行。也很简单。

  2. 这种状态模式不是常规的Asp.net MVC开发人员会使用的,因为它很可能比采用普通方法更复杂的代码。在您决定之前进行分析。 Asp.net MVC代码非常干净,因此在其上添加额外的抽象可能会让人感到困惑。并且您的域模型(状态类)很可能具有更复杂的代码作为带有数据注释的简单POCO。

    在您的情况下,数据验证也会更复杂(与数据注释一起使用时),因为您的对象应根据状态进行验证,状态可能不同。 POCO对象始终经过验证。这可能意味着我们可能会使用更多类,但它们更小,更简单,更易于维护。

答案 1 :(得分:0)

我认为你让国家感到困惑。国家的例子是:

  1. 等待用户注册
  2. 用户注册成功
  3. 用户未成功注册
  4. 现在每个州都有一个页面:

    1. 本地主机:8034 /注册
    2. 本地主机:8034 /注册/成功
    3. 本地主机:8034 /注册/失败
    4. 如果用户因为将某些字段留空而无法注册,则它们将处于第一个状态,您将必须显示一些验证消息。

      因此,作为最小值,我将有一个名为Register的控制器和以下操作方法:

      1. 索引()GET / POST
      2. 成功()GET
      3. 失败()GET