ASP.NET MVC 3.0中的状态模式

8 c# asp.net-mvc design-patterns asp.net-mvc-3

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

  1. 填写基本信息
  2. 选择包
  3. 说谢谢
  4. 错误

现在我想在这里使用状态模式.首先我创建了一个控制台应用程序,没问题.现在我想在我的MVC应用程序中实现这个逻辑,但我对结构感到困惑.我的意思是我需要多少视图,模型和控制器以及放置逻辑的位置.

Rob*_*nik 5

1个控制器:RegistrationController

6种行动方式:

  • 索引的GET + POST(填写基本信息)
  • 包的GET + POST
  • GET谢谢
  • 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
    ....
}
Run Code Online (Sandbox Code Playgroud)

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

另一种方法

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

{StateObjectType}/{State}
Run Code Online (Sandbox Code Playgroud)

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

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

重要通知

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

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

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

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

  • 谢谢罗伯特.但我对观点还有一点疑问.我需要多少次观看1或4? (2认同)
  • @Shared:共同观看4次.每个州一个.但是你应该查看一些Asp.net MVC介绍视频,这些视频可以让你清楚这一点.Asp.net MVC有一个非常短的学习曲线,因为它非常简单和纯粹,所以它不应该花太多时间来了解它足以使这项工作.它也会让你明白为什么你需要为每个州提供一个视图.我想你知道Asp.net WebForms,因为很可能只有一个aspx页面用于所有这些...... (2认同)