【问题标题】:How to use ASP.Net server controls inside of Substitution control?如何在 Substitution 控件中使用 ASP.Net 服务器控件?
【发布时间】:2011-03-09 11:13:07
【问题描述】:

虽然我们在 Substitution 控件中使用的方法应该返回字符串,但是如何在应该呈现在服务器端的服务器控件上的 Web 表单中使用 donut caching
比如Loginview控件?

【问题讨论】:

    标签: asp.net caching substitution webforms donut-caching


    【解决方案1】:

    更新 现在这是一个完整的工作示例。这里发生了一些事情:

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

    查看这些相关问题:

    【讨论】:

    【解决方案2】:

    Micah 的答案遗漏了一点,替换函数必须是static,接受HttpContext 参数,并返回string。请参阅this msdn page 了解更多信息。

    我还扩展了Micah 的助手类,使其更加灵活。

    标记

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

    实施

    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 { }
            }
        }
    
    }
    

    再次感谢Micah 提供代码

    【讨论】:

      【解决方案3】:

      相当确定您不能这样做 - 替换控件将允许您将字符串插入到输出缓存页面中。
      如果您考虑服务器控件的整个输出,这是有道理的,这可能是&lt;table&gt;,它会破坏您精心制作的所有标记和/或需要将&lt;script&gt; 加载到页面中的东西 - 而注入单个字符串是相对简单的。

      【讨论】:

        猜你喜欢
        • 2012-07-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-02
        • 1970-01-01
        • 1970-01-01
        • 2010-11-01
        • 1970-01-01
        相关资源
        最近更新 更多