【问题标题】:Sharing data between User Controls without access to the Page class在不访问 Page 类的情况下在用户控件之间共享数据
【发布时间】:2015-03-20 01:16:16
【问题描述】:

我有两个用户控件,每个控件都需要调用相同的服务来获取一些数据。由于这两个用户控件位于同一页面上 - 这将导致调用服务两次,从性能角度来看这并不理想。

这些控件是 CMS 的一部分,因此我无法访问 aspx 页面 - 我的意思是,我无法将属性添加到 Page 类并使用它。

我认为可以做到这一点的一种方法是将数据存储在用户会话中。

因此,每个用户控件都会检查 Session,如果它为 null - 它会调用服务并填充 Session。

除了使用 Session,我还有哪些选择?

编辑:每个用户控件都需要调用以下服务,这是 CMS 的一部分:

 var personalizationService = new PersonalizationService();
 var userSegments = personalizationService.GetUserSegments();
 //get data based on userSegments

问题是 - 这两个用户控件可以在同一页面上,但在某些时候,用户可能会决定删除其中一个用户控件,或者在页面中添加第三个。

谢谢

【问题讨论】:

    标签: c# asp.net webforms user-controls


    【解决方案1】:

    这是个坏主意。用户控件应该是自包含的,并且不知道他们的环境。想想网格视图。

    aspx

    <asp:GridView runat="server" id="GridView1" />
    <asp:GridView runat="server" id="GridView2" />
    

    代码背后

    protected void Page_Load(object sender, EventArgs e)
    {
        if(!IsPostBack)
        {
            DataTable dt = Database.GetDataTable();
            GridView1.DataSource = dt;
            GridView2.DataSoure = dt;
            GridView1.DataBind();
            GridView2.DataBind();
        }
    }
    

    GridView 不会从 Session 中提取数据,你也不应该!相反,在您的用户控件中设置一个属性来传递数据。

    如果数据仅在当前页面之外具有相关性,那么您可能将其存储在会话中,但用户控件不应从会话中提取数据,您的页面应从会话中提取数据并将其传递给用户控件

    if(Session["ImportantData"] == null)
        {
        Session[ImportantData] = Database.GetImportantData();
        }
    MyUserControl1.Data = Session["ImportantData"] as ImportantDataClass;
    MyUserControl2.Data = Session["ImportantData"] as ImportantDataClass;
    

    响应您的编辑...

    var personalizationService = new PersonalizationService();
    MyUserControl1.PersonalizationService = personalizationService;
    MyUserControl2.PersonalizationService = personalizationService;
    

    顺便说一句,你不应该这样做new PersonalizationService(); 理想情况下,你应该从依赖注入中获得它,这样你就可以从一个集中位置换出实现。我倾向于使用Ninject,它可以做属性注入。

    [Ninject]
    public IPersonalizationService personalizationService {get; set;}
    
    protected void Page_Load(object sender, EventArgs e)
    {
        MyUserControl1.PersonalizationService = personalizationService;
    }
    

    【讨论】:

    • 是的,这就是我想用 Session 做的事情,但想知道是否有更好的方法。见我上面的编辑
    • 您设置用户控件的 PersonalizationService 属性的代码发生在 Page 的 Load 事件中,对吗?该页面还假设这两个用户控件位于该页面上,如果用户决定删除其中一个,则情况可能并非如此。我想得越多,我就越相信 Session 是唯一的选择
    • @VeselinVasilev 是的,我的假设是它发生在页面的加载事件中。但这并不意味着 Session 是唯一的选择,甚至是一个好的选择。如果您要动态添加用户控件,则在添加控件时将服务传递给控件。就是这么简单。例如public void AddControl1(){ /* add control to page */ control.PersonalizationService = personalizationService; } 不要使用 Session,用户控件应该是自包含的,而不是依赖于他们的环境。
    • 同意你的观点,但是这些用户控件是 CMS 中的小部件,内容编辑器可以随时在任何页面上拖放它们。所以,这让事情变得更复杂了。
    • @VeselinVasilev 不,它没有。添加小部件时运行一些代码,并将服务传递给它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多