在 ASCX 依赖于父 ASPX 的 ASCX 处理程序中创建 UserControl 的实例

发布于 2024-08-21 05:15:13 字数 1076 浏览 2 评论 0原文

我发现这篇关于在 .ASHX 处理程序中创建 ASP.NET UserControls 实例的非常有用的文章 Scott Guthrie

不幸的是,我现在有一个要求,我需要创建一个依赖于父页面的 UserControl 实例。既然如此,我无法使用相同的方法来创建 UserControl。

谁能建议我如何解决这个问题?创建父页面的实例然后获取它包含的 UserControl 的内容涉及什么?

仅供参考&具体来说,我正在处理的依赖类型,UserControl 是一个存在于主要情况说明书页面上的面板。根据用户的配置首选项,在 Factsheet 的基类 FactsheetBuilderPage 中动态生成不同的控件,并将其包含在页面中。

UserControl 具有属性,例如:

public DateTime EffectiveDate
{
    get
    {
        return ((FactsheetBuilderPage)this.Page).EffectiveDate;
    }
}

public Site ConfiguredSite
{
    get { return ((FactsheetBuilderPage)this.Page).SiteConfiguration; }
}

public ConfiguredFund Fund
{
    get
    {
        return ((FactsheetBuilderPage)this.Page).Fund;
    }
}

它引用 FactsheetBuilderPage 类,这意味着我需要创建一个 FactsheetBuilderPage 类以供其引用。

理想情况下,我能够解决这个问题,而无需修改现有的代码库,因为重构这将是一个真正的痛苦!

谢谢大家

戴夫

I found this extremely useful article on creating instances of ASP.NET UserControls in .ASHX Handlers by Scott Guthrie.

Unfortunately I now have a requirement now where I need to create an instance of a UserControl which has a dependency on the parent page. This being the case, I can't use the same method to create the UserControl.

Can anyone suggest how I might go about this? What is involved in creating an instance of the Parent page and then getting the contents of the UserControl it contains?

Just for reference & to be specific on the type of depenendency I'm dealing with, the UserControl is a panel that exists on a main Factsheet page. Depending on the user's configuration preferences, different controls are dynamically generated in the Factsheet's base class FactsheetBuilderPage, and included on the page.

The UserControl has properties, such as:

public DateTime EffectiveDate
{
    get
    {
        return ((FactsheetBuilderPage)this.Page).EffectiveDate;
    }
}

public Site ConfiguredSite
{
    get { return ((FactsheetBuilderPage)this.Page).SiteConfiguration; }
}

public ConfiguredFund Fund
{
    get
    {
        return ((FactsheetBuilderPage)this.Page).Fund;
    }
}

which reference the FactsheetBuilderPage class, which means I need to create a FactsheetBuilderPage class for it to reference.

Ideally I'd be able to resolve this issue without having to modify the existing code base, because refactoring this will be a real pain!!

Thanks guys

Dave

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

囚你心 2024-08-28 05:15:13

恐怕你走进了这个。如果您要创建一个依赖于其页面的用户控件,那么为什么要将它分开呢?用户控件用于创建模块化。它们不应该依赖于页面。

也就是说,依赖是什么?既然您显然不想要该页面,那么也许您可以在没有页面的情况下提供所需的内容。

You walked into this one, I'm afraid. If you're going to make a user control that is dependent on its page, then why is it separate? A user control is used to create modularity. They are not supposed to be dependent on the page.

That said, what is the dependence? Since you obviously don't want the page, then maybe you can provide what is needed without the page.

酸甜透明夹心 2024-08-28 05:15:13

好的,解决方案是将 UserControl 的属性更改为自动,而不是仅仅使用引用父页面的 getter。

public ConfiguredFund Fund { get; set; }

public DateTime EffectiveDate { get; set; }

public Site ConfiguredSite { get; set; }

现在这意味着在实例化用户控件时我必须显式地为这些属性赋值。这允许我在任何地方创建此 UserControl 的实例,而无需父页面,只要我可以提供其所需的数据即可。

然后在我的处理程序中,创建 UserControl 的实例并分配它所需的属性:

private MyUserControl GetUserControl(int id)
{
    MyUserControl myUc = GetUserControl("Controls/MyUserControl.ascx");

    myUc.Fund = new ConfiguredFund(id);
    myUc.EffectiveDate = DateTime.Now;
    myUc.ConfiguredSite = siteManager.GetSiteById(2);

    return myUc;
}

然后为了获取渲染的 html,我使用 Scott Guthrie 代码的稍微修改版本:

public static string RenderView(MyUserControl viewControl, object data)
{
    Page pageHolder = new Page();

    if (data != null)
    {
        Type viewControlType = viewControl.GetType();
        FieldInfo field = viewControlType.GetField("Data");

        if (field != null)
        {
            field.SetValue(viewControl, data);
        }
        else
        {
            throw new Exception("View file doesn't have a public Data property");
        }
    }

    pageHolder.Controls.Add(viewControl);

    StringWriter output = new StringWriter();
    HttpContext.Current.Server.Execute(pageHolder, output, false);

    return output.ToString();
}

谢谢大家

Dave

Ok, so the solution turned out to be changing the UserControl's properties to be automatic, instead of just having a getter that referrs to the parent page.

public ConfiguredFund Fund { get; set; }

public DateTime EffectiveDate { get; set; }

public Site ConfiguredSite { get; set; }

Now it means that I have to explicitely assign values to these properties when the user control is being instantiated. This allows me to create an instance of this UserControl anywhere without the need for the parent page, as long as I can supply its required data.

then in my Handler, create an instance of the UserControl and assign the properties it needs:

private MyUserControl GetUserControl(int id)
{
    MyUserControl myUc = GetUserControl("Controls/MyUserControl.ascx");

    myUc.Fund = new ConfiguredFund(id);
    myUc.EffectiveDate = DateTime.Now;
    myUc.ConfiguredSite = siteManager.GetSiteById(2);

    return myUc;
}

then to get the rendered html, I use a slightly modified version of Scott Guthrie's code:

public static string RenderView(MyUserControl viewControl, object data)
{
    Page pageHolder = new Page();

    if (data != null)
    {
        Type viewControlType = viewControl.GetType();
        FieldInfo field = viewControlType.GetField("Data");

        if (field != null)
        {
            field.SetValue(viewControl, data);
        }
        else
        {
            throw new Exception("View file doesn't have a public Data property");
        }
    }

    pageHolder.Controls.Add(viewControl);

    StringWriter output = new StringWriter();
    HttpContext.Current.Server.Execute(pageHolder, output, false);

    return output.ToString();
}

Thanks Guys

Dave

活泼老夫 2024-08-28 05:15:13

您可以通过多种方法创建和执行页面。一种是使用 BuildManager 类实例化页面,如下所示:

Page page = BuildManager.CreateInstanceFromVirtualPath("/my/app/page.aspx", typeof(MyPageClass) ) as Page;

但是,如果您需要页面在当前请求上下文中执行,请尝试以下方式:

Page page = new MyPageClass();  
page.AppRelativeVirtualPath = 
         context.Request.AppRelativeCurrentExecutionFilePath; 
page.ProcessRequest(context);

这当然是 由 Rick Strahl 提供

You can create and execute a page by a couple of methods. One is to use the BuildManager class to instantiate a page, like so:

Page page = BuildManager.CreateInstanceFromVirtualPath("/my/app/page.aspx", typeof(MyPageClass) ) as Page;

But if you need your page to execute in the current request context, try it this way:

Page page = new MyPageClass();  
page.AppRelativeVirtualPath = 
         context.Request.AppRelativeCurrentExecutionFilePath; 
page.ProcessRequest(context);

This is of course courtesy of Rick Strahl.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文