0

我发现这篇关于在 .ASHX 处理程序中创建 ASP.NET 用户控件实例的文章非常有用,作者是Scott Guthrie

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

谁能建议我如何解决这个问题?创建父页面的实例然后获取它包含的 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 类供它引用。

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

多谢你们

戴夫

4

3 回答 3

3

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

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

于 2010-02-10T22:13:38.550 回答
1

好的,所以解决方案结果是将 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();
}

多谢你们

戴夫

于 2010-02-12T10:34:17.053 回答
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);

这当然是由 Rick Strahl 提供的

于 2010-02-10T22:08:05.803 回答