在ASHX处理程序中创建UserControl的实例,其中ASCX取决于父ASPX

时间:2010-02-10 22:01:40

标签: asp.net user-controls ihttphandler

我在Scott Guthrie的.ASHX处理程序中找到了关于创建ASP.NET UserControl实例的非常有用的文章。

不幸的是,现在我需要创建一个UserControl实例,该实例依赖于父页面。在这种情况下,我不能使用相同的方法来创建UserControl。

有谁能建议我怎么做?创建Parent页面的实例然后获取它包含的UserControl的内容涉及什么?

仅供参考&具体关于我正在处理的依赖性类型,UserControl是一个存在于主要Factsheet页面上的面板。根据用户的配置首选项,可以在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类供它引用。

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

谢谢你们

戴夫

3 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:1)

好的,所以解决方案结果是将UserControl的属性更改为自动,而不是只有一个引用父页面的getter。

public ConfiguredFund Fund { get; set; }

public DateTime EffectiveDate { get; set; }

public Site ConfiguredSite { get; set; }

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

然后在我的Handler中,创建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();
}

谢谢大家

戴夫

答案 2 :(得分:0)

您可以通过几种方法创建和执行页面。一种是使用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);

这当然是courtesy of Rick Strahl