Consuming SF 4 REST service - Front- & Back-End Development - Front- & Back-End Development - Progress Community
 Front- & Back-End Development

Consuming SF 4 REST service

  • Consuming SF 4 REST service
  • Hi,

    I’m having a hard time consuming the SF4 webservices.

     

    Could you please be so kind to provide a code snippet that connects to “services/pages/PagesService.svc” and retrievs a “CollectionContext<PageViewModel>” from the methode “GetPagesAsTree”.

     

    I do receive a 405 error. I’m also not quite sure how to authenticate this request with the right user credentials.

    A code-snippet would be very helpful as I’m stuck with this basic step..:(

     

    What I’m trying to do: Connect to SF4 webservices from an .net windows-forms application which will be used as a migration tool for our old CMS.

    Thanx

  • Hello SolarX,

    GetPagesAsTree uses POST method to retrieve the data. GetPagesAsTree returns xml or jason that you should parse. You can use /PagesService.svc/xml/ which will return the data as  XML. You have to make web request where the method type is POST.(WebRequest.Create)

    By default the Get method is processed without authentication when you are not trying to create, delete or update an item.. Please check whether you make the proper POSt request. You can use GetPages which also returns all pages and parent IDs so you can make the relation easily.

    Best wishes,
    Ivan Dimitrov
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  • Thank you for your quick answer.
    Here is the code I'm using in a test project. When I call GetPagesAsTree at the end I get an "405 method not allowed" exception. Maybe my usage of the parameters is wrong.

    private void CallService()
           
                BasicHttpBinding binding = new BasicHttpBinding(BasicHttpSecurityMode.None);
                EndpointAddress address = new EndpointAddress("ffm-srv-ext-2a/.../");

                ChannelFactory<IPagesService> factory =
                    new ChannelFactory<IPagesService>(binding, address);
                factory.Open();

                IPagesService channel = factory.CreateChannel();

                string[] leafIds = new string[10];
                CollectionContext<PageViewModel> pageTree = channel.GetPagesAsTree(leafIds, "", 10, 10, 10, 10, "");

                factory.Close();
           
  • Hello SolarX,

    If you are using IIS 7.5 make sure to disable the WebDAV module. It restricting put and delete methods of webservices. You can check this article for more information.

    Regards,
    Radoslav Georgiev
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  • Hi,

    I've changed the web.config accordingly. Anyway WEBDav feature isn't installed on the server at all.
    Still getting the same error.

    Thanx for your help!
  • Hi SolarX,

    The problem is not coming from the parameters used. It is coming from the HttpBinding used. Try this :
    WebHttpBinding binding = new WebHttpBinding();
    EndpointAddress address = new EndpointAddress("http://localhost:4000/Sitefinity/services/pages/PagesService.svc/");
    ChannelFactory<IPagesService> factory =
        new ChannelFactory<IPagesService>(binding, address);
    factory.Endpoint.Behaviors.Add(new WebHttpBehavior());
    factory.Open();
    IPagesService channel = factory.CreateChannel();
    WcfPageContext page = channel.GetPage("35bb4ae9-d916-49f7-80db-cf8823746105", null, false);

    Or bellow is an alternative approach you can use to call the services:
    var request1 = (HttpWebRequest)WebRequest.Create("http://localhost:4000/Sitefinity/Services/Pages/PagesService.svc/tree/");
            request1.Method = "POST";
            string postData = @"[""365af67c-a4a5-4552-83d9-e5ceb2dcbc06""]";
            byte[] byteArray = Encoding.UTF8.GetBytes(postData);
            // Set the ContentType property of the WebRequest.
            request1.ContentType = "application/json";
            // Set the ContentLength property of the WebRequest.
            request1.ContentLength = byteArray.Length;
            // Get the request stream.
            Stream dataStream = request1.GetRequestStream();
            // Write the data to the request stream.
            dataStream.Write(byteArray, 0, byteArray.Length);
            // Close the Stream object.
            dataStream.Close();
            // Get the response.
            WebResponse response1 = request1.GetResponse();
            // Display the status.
            Console.WriteLine(((HttpWebResponse)response1).StatusDescription);
            // Get the stream containing content returned by the server.
            dataStream = response1.GetResponseStream();
            // Open the stream using a StreamReader for easy access.
            StreamReader reader = new StreamReader(dataStream);
            // Read the content.
            string responseFromServer = reader.ReadToEnd();
            // Display the content.
            Console.WriteLine(responseFromServer);
            // Clean up the streams.
            reader.Close();
            dataStream.Close();
            response1.Close();

    Regards,
    Radoslav Georgiev
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  • Great. That solved the 405 error !! Thanx :)

    I do now get an "Internal Server Error" exception when calling "GetPagesAsTree". From the server log I can see it should be a problem with the parameters I supply. Could you please provide further information about the required parameters.

    Thank you very much !!

    This is from the server app log:

    Exception information:

    Exception type: ArgumentNullException

    Exception message: Value cannot be null.

    Parameter name: g

     

    Request information:

    Request URL: ffm-srv-ext-2a/.../

    Request path: /SF4B/Sitefinity/services/pages/PagesService.svc/xml/tree/

    User host address: 10.73.11.73

    User: Anonymous

    Is authenticated: False

    Authentication Type: Sitefinity

    Thread account name: IIS APPPOOL\DefaultAppPool

     

    Thread information:

    Thread ID: 5

    Thread account name: IIS APPPOOL\DefaultAppPool

    Is impersonating: False

    Stack trace: at System.Guid..ctor(String g)

    at Telerik.Sitefinity.Modules.Pages.Web.Services.PagesService.GetPagesAsTreeInternal(String[] leafIds, String provider, Int32 nodesLimit, Int32 perLevelLimit, Int32 perSubtreeLimit, Int32 subtreesLimit, String root)

    at SyncInvokeGetPagesAsTreeInXml(Object , Object[] , Object[] )

    at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)

    at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)

    at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)

    at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)

    at System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

     

     

    Custom event details:

  • Hi SolarX,

    The  error is thrown, because one of the parameters you pass is not correct or null( but it should not be a null). The stack does not contain which of your parameters is the problematic one, but I suppose that this is leafIds.

    Greetings,
    Ivan Dimitrov
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  • Hi,

    that is what I thought.
    Since the parameters aren't documented yet, could you please provide a specific example for "GetPagesAsTree".
    I really need to get further with my project. What I need is to get a hierarchical list of all pages (structure of the site). Besides the parameters, is "GetPagesAsTree" the right method to achieve that?

    Thanx,

    Martin
  • Hi SolarX,

    GetPagesAsTree accepts the following parameters

    leafIds - The ids of the leaf pages - if empty array an error is thrown
    provider - provider that will be used - if null the default one is used
    nodesLimit - limit the number of nodes  - int value / 0 gets all
    perLevelLimit - limit level nodes - int value / 0 gets all
    subtreesLimit - limit the sub trees  - int value  / 0 gets all
    root - should be null to get all pages - type - string.


    The code that we sent you is a working sample which returns the data in JSON and we get the response as stream, but you could parse it as xml or directly use GetPagesAsTreeInXml



    Sincerely yours,
    Ivan Dimitrov
    the Telerik team

    Check out Telerik Trainer, the state of the art learning tool for Telerik products.
  • What file do we add your WebHttpBinding or HttpWebRequest code to.  Can you give instructions where to create the file and what to call it.
  • Hi Dean,

    It depends on from where you want to call the service - user control, custom control, page etc.
    The better option is using Sys.Net.WebRequest(); to call the service.

    All the best,
    Ivan Dimitrov
    the Telerik team
    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get now >>
  • Ivan

    If we were going to use the Sys.Net.WebRequest(); to call the service, do you have sample code and how to implement it.

    With Sitefinity 4.x, are all of the webpages stored in sql?
  • Hi Dean,

    This is a standard MS AJAX call.

    sample

           var wRequest = new Sys.Net.WebRequest();
            wRequest.set_url(this._generateNonBinderUrl(url, urlParams, keys));
            wRequest.set_httpVerb('POST');
            this._applyLocalizationHeaders(wRequest);

            if (data)
                var postData = Sys.Serialization.JavaScriptSerializer.serialize(data);
                wRequest.set_body(postData);
                wRequest.get_headers()["Content-Type"] = "application/json";
           
            else
                alert('POST method cannot be invoked without the data');
                return;
           

            var delegates = Success: successDelegate, Failure: failureDelegate, Caller: caller, Context: context ;
            wRequest.set_userContext(delegates);
            wRequest.add_completed(this.NonBinderCallbackDelegate);
        ,

    Best wishes,
    Ivan Dimitrov
    the Telerik team
    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get now >>