Создайте экземпляр UserControl в обработчике ASHX, где ASCX Зависит от родительского ASPX

StackOverflow https://stackoverflow.com/questions/2240664

Вопрос

Я нашел эту чрезвычайно полезную статью о создании экземпляров ASP.NET UserControls в .Обработчики ASHX с помощью Скотт Гатри.

К сожалению, теперь у меня есть требование, когда мне нужно создать экземпляр UserControl, который зависит от родительской страницы.В таком случае я не могу использовать тот же метод для создания UserControl.

Кто-нибудь может подсказать, как я мог бы это сделать?Что связано с созданием экземпляра родительской страницы и последующим получением содержимого пользовательского элемента управления, который он содержит?

Просто для справки и конкретизации типа зависимости, с которой я имею дело, UserControl - это панель, которая существует на главной странице информационного бюллетеня.В зависимости от настроек конфигурации пользователя различные элементы управления динамически генерируются в базовом классе FactsheetBuilderPage справочной таблицы и включаются на страницу.

Пользовательский элемент управления обладает свойствами, такими как:

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, чтобы на него можно было ссылаться.

В идеале я мог бы решить эту проблему без необходимости изменять существующую кодовую базу, потому что рефакторинг этого будет настоящей болью!!

Спасибо, ребята

Дэйв

Это было полезно?

Решение 2

Итак, решение оказалось в том, чтобы изменить свойства 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-код, я использую слегка измененную версию кода Скотта Гатри:

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();
}

Спасибо, ребята

Дэйв

Другие советы

Боюсь, ты сам вляпался в это дело.Если вы собираетесь создать пользовательский элемент управления, который зависит от его страницы, то почему он отдельный?Пользовательский элемент управления используется для создания модульности.Предполагается, что они не должны зависеть от страницы.

Тем не менее, что такое зависимость?Поскольку вам, очевидно, не нужна эта страница, то, возможно, вы сможете предоставить то, что необходимо, без этой страницы.

Вы можете создать и запустить страницу несколькими способами.Один из них заключается в использовании класса BuildManager для создания экземпляра страницы, например:

Страница page = BuildManager.Создайте instancefromvirtualpath("/my/app/page.aspx", typeof(MyPageClass)) как страницу;

Но если вам нужно, чтобы ваша страница выполнялась в текущем контексте запроса, попробуйте сделать это следующим образом:

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

Это, конечно, любезно предоставлено Риком Стралом.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top