+1-888-365-2779
Try Now
More in this section

PageMethods

7 posts, 0 answered
  1. George
    George  avatar
    204 posts
    Registered:
    05 Sep 2006
    25 Jan 2011
    Link to this post
    Hi Team,

    I was trying to apply this workaround (http://www.chadscharf.com/index.php/2009/11/creating-a-page-method-scriptmethod-within-an-ascx-user-control-using-ajax-json-base-classes-and-reflection/) for calling page methods from user controls in sitefinity.

    The reason why i want to do this is because I want to use JQuery alert to create a Friend Requests page similar to the facebook friend requests page. Whenever the user accepts a request, he will get the friend accepted message instead of the buttons.

    Anyhoo, the problem with this implementation is that i want to add the PageServiceRequest server method to every page. I thought i can do this by creating a custom internal page class that inherits from the Telerik.Cms.Web.InternalPage and then change the cmsentrypage's inheritance class. Basically i need to create a custom CmsPageBase and i would add this method to it. I thought InternalPage might do the same but it wasn't the case.

    When i try to call a page method, i get PageServiceRequest server method failed as if the page does not see this method. 

    Is there any better way to accomplish what i am trying to do here (I know i can use a webservice and page methods) or is there anyway to fix this using this approach?

    Appreciate your input.

    Best,

    George
  2. George
    George  avatar
    204 posts
    Registered:
    05 Sep 2006
    26 Jan 2011
    Link to this post
    Any input on the above anyone?
  3. Radoslav Georgiev
    Radoslav Georgiev avatar
    3370 posts
    Registered:
    01 Feb 2016
    27 Jan 2011
    Link to this post
    Hello George ,

    Thank you for using our services.

    Can you please show us the override you have done to the InternalPage class and the user control you are using. Basically this approach should be done either through the internal page class or through the master page you use for your template.

    Greetings,
    Radoslav Georgiev
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  4. George
    George  avatar
    204 posts
    Registered:
    05 Sep 2006
    28 Jan 2011
    Link to this post
    Hi Radoslav,

    CustomInternalPage

    public partial class CustomInternalPage : Telerik.Cms.Web.InternalPage
      {
          /// <summary>
          /// Raises the <see cref="E:System.Web.UI.Control.Init"/> event to initialize the page.
          /// </summary>
          /// <param name="e">An <see cref="T:System.EventArgs"/> that contains the event data.</param>
          protected override void OnInit(EventArgs e)
          {
              base.OnInit(e);
              RegisterPageServiceRequestProxy();
          }
     
          /// <summary>
          /// Registers the page service request proxy. This is used by any user controls and/or master pages that also want to
          /// encapsulate web methods without having to put all of them in the page.
          /// </summary>
          /// <remarks>AJAX Voodoo!</remarks>
          private void RegisterPageServiceRequestProxy()
          {                
              System.Web.UI.ScriptManager.RegisterClientScriptBlock(
                  this,
                  GetType(),
                  "PageServiceRequestProxy",
                  "function InvokeServiceRequest(typeName,methodName,successCallback,failureCallback){if(PageMethods.PageServiceRequest){try{var parms=[];for(var i=4;i<arguments.length;i++){parms.push(arguments[i]);}PageMethods.PageServiceRequest(typeName,methodName,parms,successCallback,failureCallback);}catch(e){alert(e.toString());}}}",
                  true);
          }
     
          /// <summary>
          /// Creates a generic ScriptMethod for use on ANY public static method, whether it is in a UserControl, MasterPage or some other random place.
          /// </summary>
          /// <param name="typeName">Name of the type.</param>
          /// <param name="methodName">Name of the method.</param>
          /// <param name="args">The args.</param>
          /// <returns>The string/value type result OR a JSON serialized instance of the object returned by the target of the invocation.</returns>
          [WebMethod(EnableSession = true)]
          [ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = false)]
          public static string PageServiceRequest(string typeName, string methodName, object[] args)
          {
              Type ctl = Type.GetType(typeName);
              if (ctl != null)
              {
                  object o = ctl.InvokeMember(
                      methodName,
                        System.Reflection.BindingFlags.Static
                      | System.Reflection.BindingFlags.InvokeMethod
                      | System.Reflection.BindingFlags.Public
                      | System.Reflection.BindingFlags.IgnoreCase,
                      null, null, args ?? new object[] { });
                  if (o != null)
                  {
                      if (o is string || o.GetType().IsValueType)
                          return o.ToString(); // If it is a string or value type, return a string
     
                      // If it is a complex object, return a serialized version of it.
                      var serializer = new JavaScriptSerializer();
                      return serializer.Serialize(o); // allow anonymous types, etc
                  }
              }
              return "{}"; // return an empty JSON object
          }
      }

    cmsentrypoint.aspx

    <%@ Page Inherits="Telerik.Cms.Web.CustomInternalPage" MasterPageFile="~/Sitefinity/Dummy.master" %>

    The best way for this to work is to add the code above to the CmsPageBase instead of InternalPage but i understand that this is not possible. I think we could fix this issue with an HTTP Handler to make the PageServiceRequest function available for every page.

    Best,

    G
  5. Radoslav Georgiev
    Radoslav Georgiev avatar
    3370 posts
    Registered:
    01 Feb 2016
    01 Feb 2011
    Link to this post
    Hello George ,

    Thank you for providing the sample code. With the initial setup provided from the custom internal page and following the blog post, I was not able to make this work as I would always get PageMethods is undefined JavaScript error. Then I went to the ScriptManager control on my master page and set it to enable page methods:
    <asp:ScriptManager ID="ScriptManager1" EnablePageMethods="true" runat="server">
    </asp:ScriptManager>

    This property setting will make the ScriptManager render the required PageMethods scripts on the page.

    Regards,
    Radoslav Georgiev
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  6. George
    George  avatar
    204 posts
    Registered:
    05 Sep 2006
    02 Feb 2011
    Link to this post
    Hi Radoslav,

    I have already the EnablePageMethod's attribute set to true to enable PageMethods. The next thing i did, i created a web method on one of my user controls that inherits from BaseUserControl and i tried calling this method .... I get the following error: The server method PageServiceRequest failed

    [UserControlScriptMethod]
    public static bool AcceptFriend()
    {
        return true;
     
         
    }

    function promptAcceptFriend() {
        jConfirm('Are you sure you want to add this friend?', 'Accept Friendship',
                        function (r) {
                            if (r == true) {
                                AcceptFriend(acceptFriend_Success, acceptFriend_Failure);
                            }
     
                            return false;
                        });
     
                        return false;
     
        }
     
        // Delegate functions for the GetTime method
        function acceptFriend_Success(result) {alert(result); }
        function acceptFriend_Failure(result) {alert(result.get_message()); }


    public class BaseUserControl : System.Web.UI.UserControl
    {
        /// <summary>
        /// Raises the <see cref="E:System.Web.UI.Control.PreRender"/> event.
        /// </summary>
        /// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
            RegisterUserControlWebMethods();
        }
     
        /// <summary>
        /// Registers the user control web methods tagged with the UserControlWebMethodAttribute
        /// </summary>
        private void RegisterUserControlWebMethods()
        {
            foreach (MethodInfo method in this.GetType().GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod))
                if (method.GetCustomAttributes(typeof(UserControlScriptMethodAttribute), true).Length > 0)
                    RegisterUserControlWebMethod(method);
     
            Type baseType = this.GetType().BaseType;
            if (baseType != null && (baseType.Namespace == null || !baseType.Namespace.StartsWith("System")))
                foreach (MethodInfo method in baseType.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod))
                    if (method.GetCustomAttributes(typeof(UserControlScriptMethodAttribute), true).Length > 0)
                        RegisterUserControlWebMethod(method);
        }
     
        /// <summary>
        /// Registers a user control web method based on the methodInfo signature through reflection.
        /// </summary>
        /// <param name="method">The method.</param>
        /// <remarks>AJAX Voodoo!</remarks>
        private void RegisterUserControlWebMethod(MethodInfo method)
        {
            string blockName = string.Concat(method.Name, "_webMethod_uc");
     
            StringBuilder funcBuilder = new StringBuilder();
            funcBuilder.Append("function ");
            funcBuilder.Append(method.Name);
            funcBuilder.Append("(successCallback,failureCallback");
            foreach (var par in method.GetParameters())
                funcBuilder.AppendFormat(",{0}", par.Name);
            funcBuilder.Append("){if(PageMethods.PageServiceRequest){try{var parms=[];for(var i=2;i<arguments.length;i++){parms.push(arguments[i]);}PageMethods.PageServiceRequest(");
            funcBuilder.AppendFormat("'{0}','{1}'", method.DeclaringType.AssemblyQualifiedName, method.Name);
            funcBuilder.Append(",parms,successCallback,failureCallback);}catch(e){alert(e.toString());}}}");
     
            ScriptManager.RegisterClientScriptBlock(this.Page, this.Page.GetType(), blockName, funcBuilder.ToString(), true);
        }
    }

    [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = false)]
    public sealed class UserControlScriptMethodAttribute : Attribute
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="UserControlScriptMethodAttribute"/> class.
        /// </summary>
        public UserControlScriptMethodAttribute() { }
    }
  7. Radoslav Georgiev
    Radoslav Georgiev avatar
    3370 posts
    Registered:
    01 Feb 2016
    03 Feb 2011
    Link to this post
    Hi George ,

    I have attached my sample project, where I was able to make this work with the code from the blog post. You can observe the attached image that the page methods execute correctly on my side.

    Greetings,
    Radoslav Georgiev
    the Telerik team
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
Register for webinar
7 posts, 0 answered