【问题标题】:Most Correct way to redirect page with Model-View-Presenter Pattern使用 Model-View-Presenter 模式重定向页面的最正确方法
【发布时间】:2010-01-15 19:35:25
【问题描述】:

在模型-视图-演示者模式中调用Response.Redirect 的最佳方式是什么?同时坚持正确的层分离?

【问题讨论】:

    标签: asp.net redirect separation-of-concerns mvp


    【解决方案1】:

    我处理此问题的一种方法是让演示者引发视图将订阅的事件(如Succeeded 或其他东西)。当演示者完成它的处理时,它会引发事件,该事件将由视图处理。在该处理程序中,视图将重定向到下一页。

    这样,演示者不需要了解任何有关页面或 URL 或任何内容的信息。它只知道它何时完成了任务并通过引发事件让视图知道。如果演示者成功或失败,您可以引发不同的事件,以防您需要重定向到不同的地方。

    【讨论】:

    • 我最近又在思考这个问题,与方法相比,使用事件真的有什么特别的优势吗?
    【解决方案2】:

    从概念上讲,我不知道这是否是最正确的方法。 但是我在上一个 MVP 应用程序中所做的是围绕 HttpContext.Current 创建一个包装器,我称之为 HttpRedirector。 我还为测试目的创建了一个虚拟重定向器。两者都跟踪最后一个重定向的 url,以便我可以在单元测试中检查当我在控制器/演示器上调用方法时重定向实际上发生了。使用 IOC 容器,我可以根据环境(生产/测试)切换 IRedirector 的实现。

    【讨论】:

    • 抽象的HttpContext我也很喜欢
    【解决方案3】:

    一旦奠定了基础,我们的工作方式就会很好。我敢肯定有几种方法可以给猫剥皮。 (反正谁给猫剥皮。猫很可爱!)

    首先,这仅适用于 ASP.Net 编译的 Web 项目,而不是网站。

    每个页面都应该继承一个自定义的抽象基类,看起来像这样:

    public abstract class PageBase : Page
    {
      private static string _baseUrl = "/";
    
      public static string BaseUrl
      {
        get { return _baseUrl; }
        set { _baseUrl = value; }
      }
    
      protected static string BuildUrl(string basePath)
      {
        if( !string.IsNullOrEmpty(basePath) && basePath.StartsWith("~/"))
        {
          basePath = basePath.replace("~/", BaseUrl);
        }
        return basePath;
      }
    
      protected static string LoadView(string path)
      {
        Response.Redirect(path);
      }
    }
    

    每个页面还实现了一个特定于页面的接口。每个页面特定的接口也继承自一个基本接口:

    public interface IPageBase()
    {
      void LoadView(string path);
    }
    

    然后每个页面定义它自己的 BaseUrl 版本。您可能需要考虑查询字符串/路径加密/等。

    最后,您的任何演示者(应该引用特定于页面的接口)都可以获取所需页面上的静态 BuildUrl() 以进行查看,然后使用返回的路径调用 LoadView()。

    【讨论】:

      【解决方案4】:

      这取决于您的演示者的通用性。如果您的演示者完全与 UI 无关(可以在 WinForms 和 WebForms 之间重用),那么您将不得不抽象重定向操作。在 WebForms 中,重定向操作将通过 Response.Redirect 在视图中实现。在 WinForms 中,(我否认有很多使用 WinForms 的经验)我的猜测是它将由 SomeForm.Show 实现。

      一个简单的、令人难以置信的选项是在视图的界面中包含一个 ShowViewX() 方法。您可以为视图可以逻辑重定向到的每个表单设置一个。或者,视图可以实现类似 Show(ConnectedViews) 的接口方法,其中 ConnectedViews 是一个枚举,其中包含每个视图的值,这些视图可以从特定视图“重定向”到。此枚举将存在于演示者级别。

      上述方法特定于视图-演示者对。您可以改为将其实现为系统范围的事物。逻辑与上面类似,在基本视图和演示器中实现。每个表单都有一个 ShowView__(),或者一个 Show(Views) 方法,其中 Views 是所有表单的枚举。

      这是封装和干燥性之间的折腾。

      【讨论】:

        猜你喜欢
        • 2020-08-19
        • 1970-01-01
        • 2010-09-13
        • 1970-01-01
        • 2012-07-03
        • 2014-10-08
        • 1970-01-01
        • 1970-01-01
        • 2010-12-31
        相关资源
        最近更新 更多