Как использовать серверные элементы управления ASP.Net внутри элемента управления замещением? - PullRequest
5 голосов
/ 29 июня 2010

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

Ответы [ 3 ]

6 голосов
/ 23 июля 2010

ОБНОВЛЕНИЕ Теперь это полностью рабочий пример.Здесь происходит несколько вещей:

  1. Воспользуйтесь обратным вызовом элемента управления подстановки для визуализации вывода необходимого вам пользовательского элемента управления.
  2. Используйте пользовательский класс страницы, который переопределяет VerifyRenderingInServerForm иEnableEventValidation для загрузки элемента управления, чтобы предотвратить появление ошибок, когда пользовательский элемент управления содержит серверные элементы управления, для которых требуется тег формы или проверка события.

Вот разметка:

<asp:Substitution runat="server" methodname="GetCustomersByCountry" />

Вот обратный вызов

public string GetCustomersByCountry(string country)
{
   CustomerCollection customers = DataContext.GetCustomersByCountry(country);

    if (customers.Count > 0)
        //RenderView returns the rendered HTML in the context of the callback
        return ViewManager.RenderView("customers.ascx", customers);
    else
        return ViewManager.RenderView("nocustomersfound.ascx");
}

Вот вспомогательный класс для визуализации пользовательского элемента управления

public class ViewManager
{
    private class PageForRenderingUserControl : Page
    {
        public override void VerifyRenderingInServerForm(Control control)
        { /* Do nothing */ }

        public override bool EnableEventValidation
        {
            get { return false; }
            set { /* Do nothing */}
        }
    }

    public static string RenderView(string path, object data)
    {
        PageForRenderingUserControl pageHolder = new PageForUserControlRendering();
        UserControl viewControl = (UserControl) pageHolder.LoadControl(path);

        if (data != null)
        {
            Type viewControlType = viewControl.GetType();
            FieldInfo field = viewControlType.GetField("Data");
            if (field != null)
            {
                field.SetValue(viewControl, data);
            }
            else
            {
                throw new Exception("ViewFile: " + path + "has no data property");
            }
        }

        pageHolder.Controls.Add(viewControl);
        StringWriter result = new StringWriter();
        HttpContext.Current.Server.Execute(pageHolder, result, false);
        return result.ToString();
    }
}

Смотрите этисвязанные вопросы:

0 голосов
/ 30 июля 2012

Одна вещь Михей не учел ответ, что функция подстановки должна быть static, принять параметр HttpContext и вернуть string. См. эту страницу MSDN для получения дополнительной информации.

Я также расширил класс помощников Миха , чтобы он стал немного более гибким.

Разметка

<asp:Substitution ID="Substitution1" MethodName="myFunction" runat="server" />

1020 * реализация внешнего *

public static string myFunction(HttpContext httpContext){
   ViewManager vm = new ViewManager();

   //example using a Button control

   Button b = new Button();
   b.Text = "click me"; //we can set properties like this

   //we can also set properties with a Dictionary Collection
   Dictionary<string,object> data =  new Dictionary<string,object>();
   data.add("Visible",true); 

   String s = vm.RenderView(b,data); //don't do anything (just for example)

   //we can also use this class for UserControls
   UserControl myControl = vm.GetUserControl("~mypath");

   data.clear();
   data.add("myProp","some value");

   return vm.RenderView(myControl,data); //return for Substitution control
}

Класс

using System.IO;
using System.ComponentModel;
public class ViewManager
{
    private PageForRenderingUserControl pageHolder;
    public ViewManager()
    {
        pageHolder = new PageForRenderingUserControl();
    }

    public UserControl GetUserControl(string path)
    {
        return (UserControl)pageHolder.LoadControl(path);
    }

    public string RenderView(Control viewControl, Dictionary<string, object> data)
    {
        pageHolder.Controls.Clear();
        //Dim viewControl As UserControl = DirectCast(pageHolder.LoadControl(Path), UserControl)

        if (data != null) {
            Type viewControlType = viewControl.GetType();


            dynamic properties = TypeDescriptor.GetProperties(viewControl);

            foreach (string x in data.Keys) {
                if ((properties.Item(x) != null)) {
                    properties.Item(x).SetValue(viewControl, data[x]);
                }
            }
        }

        pageHolder.Controls.Add(viewControl);
        StringWriter result = new StringWriter();
        HttpContext.Current.Server.Execute(pageHolder, result, false);
        return result.ToString();
    }

    private class PageForRenderingUserControl : Page
    {
        public override void VerifyRenderingInServerForm(Control control)
        {
            // Do nothing 
        }

        public override bool EnableEventValidation {
            get { return false; }
            // Do nothing 
            set { }
        }
    }

}

Еще раз спасибо Михе за код

0 голосов
/ 29 июня 2010

Я довольно уверен, что вы не можете сделать это - элемент управления Substitution будет только , позволяющий вставить строку в страницу с кэшем вывода.
Это имеет смысл, если вы подумаете обо всем выводе серверного элемента управления, который может быть <table>, который нарушит всю вашу тщательно созданную разметку и / или что-то, что требует загрузки <script>, введенной на страницу - тогда как инъекция одна строка - это нечто относительно простое.

...