5

Substitution コントロールで使用するメソッドは文字列を返す必要がありますが、サーバー側でレンダリングする必要があるサーバー コントロールの Web フォームでドーナツ キャッシュを使用するにはどうすればよいでしょうか。
たとえば、Loginview コントロール?

4

3 に答える 3

6

UPDATE これは完全に機能する例です。ここで起こっていることがいくつかあります:

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

これらの関連する質問を参照してください。

于 2010-07-23T14:16:13.963 に答える
0

Micahの答えが省略されたことの 1 つは、置換関数は であり、パラメーターstaticを受け入れHttpContext、 を返す必要があるということstringです。詳細については、この msdn ページを参照してください。

また、 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に再び感謝します

于 2012-07-30T17:42:55.790 に答える
-1

これはできないと確信しています。Substitutionコントロールは、outputcachedページに文字列を挿入することしかできません。
これは、サーバーコントロールの出力全体について考える場合に意味があります。これは<table>、慎重に作成されたすべてのマークアップや<script>、ページに大量の注入を必要とするものを混乱させる可能性がありますが、単一の文字列を注入することは、比較的簡単です。

于 2010-06-29T07:19:25.697 に答える