代码之家  ›  专栏  ›  技术社区  ›  mhmd

如何在替换控件内使用ASP.NET服务器控件?

  •  5
  • mhmd  · 技术社区  · 14 年前

    虽然我们在替换控制中使用的方法应该返回字符串,那么如何使用 donut caching 在服务器控件上的Web窗体中,哪一个应呈现为服务器端?
    例如LoginView控件?

    3 回复  |  直到 12 年前
        1
  •  6
  •   Community CDub    8 年前

    更新 This is now a fully working example. 这里发生了一些事情:

    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
  •  0
  •   Community CDub    8 年前

    一件事 Micah 遗漏的答案是替换函数必须 static 接受一个 HttpContext 参数,并返回 string . 见 this msdn page 更多信息。

    我也延长了 弥迦 的helper类要更灵活一点。

    标记

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

    再次感谢 弥迦 为了代码

        3
  •  -1
  •   PhilPursglove    14 年前

    我是 相当地 当然你不能这样做-替代控制会 只有 允许将字符串插入OutputCached页。
    如果您考虑服务器控件的整个输出,这是有意义的,它可能是 <table> 这将破坏所有精心设计的标记和/或需要加载 <script> injected into the page - whereas injecting a single string is something that's relatively straightforward.

    推荐文章