Executing Service Operations (using .NET client)

In previous section, we discussed executing Service Operations using just a browser (and a plug-in) without writing any code. In this section, we discuss executing the same using .NET client.

 

We will create a simple .NET console application, which consumes PDS by executing a Service Operation named “CreateOrder”. 

1.    Open Visual Studio.

2.    From the File menu, click New Project.

3.    Provide new project information as shown below and click OK.

4.    Right-click “TestCreateOrder” and select Add Service Reference.

5.    In the “Add Service Reference” dialog, provide service URL and click Go.
You may be prompted for credentials to connect to service.

6.    Once it finds the service, provide namespace as shown below and click OK.

The proxy is created, as shown below.

7.    Add app.config to the project.

8.    Add the following to app.config:

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <appSettings>

    <add key="svcUri" value="http://YourServerName/PersonifyDataServicesBase/PersonifyData.svc" />

    <add key="EnableBasicAuthentication" value="true" />

    <add key="UserName" value="YourUserName" />

    <add key="Password" value="YourPassword" />

  </appSettings>

</configuration>

9.    Add a reference to “System.Configuration”.

10.  Add a reference to “Personify.DataServices.Serialization.dll” (usually found in “bin” folder available in “Personify Data Services” virtual folder).

11.  Add a couple of helper classes, as shown below.

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

using System.Data.Services.Client;

using Personify.DataServices.Tests.UnitTests.PersonifySvcRef;

using System.Net;

using System.IO;

using Personify.DataServices.Serialization;

using System.Xml.Linq;

 

namespace Personify.DataServices.Tests.UnitTests

{

    public static class SvcClient

    {

 

        static string sUri = System.Configuration.ConfigurationManager.AppSettings["svcUri"];

        static string EnableBasicAuthentication = System.Configuration.ConfigurationManager.AppSettings["EnableBasicAuthentication"];

        static string UserName = System.Configuration.ConfigurationManager.AppSettings["UserName"];

        static string Password = System.Configuration.ConfigurationManager.AppSettings["Password"];

        static Uri svcUri = new Uri(sUri);

 

        #region Helpers

 

 

        private static PersonifyEntitiesBase ctxt;

        public static PersonifyEntitiesBase Ctxt

        {

            get

            {

                if (ctxt == null)

                {

                    ctxt = new PersonifyEntitiesBase(svcUri);

 

                    //enable authentication if necessary

                    if (Convert.ToBoolean(EnableBasicAuthentication) == true)

                    {

                        var serviceCreds = new NetworkCredential(UserName, Password);

                        var cache = new CredentialCache();

                        cache.Add(svcUri, "Basic", serviceCreds);

                        ctxt.Credentials = cache;

                    }

                    ctxt.IgnoreResourceNotFoundException = true;

                }

                return ctxt;

            }

        }

 

        private static PersonifyEntitiesBase ctxtAnonymous;

        public static PersonifyEntitiesBase CtxtAnonymous

        {

            get

            {

                if (ctxtAnonymous == null)

                {

                    ctxtAnonymous = new PersonifyEntitiesBase(svcUri);

                    ctxtAnonymous.IgnoreResourceNotFoundException = true;

                }

                return ctxtAnonymous;

            }

        }

 

        public static ReturnType Post<ReturnType>(string SvcOperName, object o)

        {

            return DoPost<ReturnType>(SvcOperName, o, true);

        }

 

        public static ReturnType PostAnonymous<ReturnType>(string SvcOperName, object o)

        {

            return DoPost<ReturnType>(SvcOperName, o, false);

        }

 

        private static ReturnType DoPost<ReturnType>(string SvcOperName, object o, bool enableAuthentication)

        {

            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(sUri.TrimEnd('/') + "/" + SvcOperName);

            if (enableAuthentication)

            {

                NetworkCredential serviceCreds = new NetworkCredential(UserName, Password);

                CredentialCache cache = new CredentialCache();

                Uri uri = new Uri(sUri);

                cache.Add(uri, "Basic", serviceCreds);

                req.Credentials = cache;

            }

 

            req.Method = "POST";

            //req.ContentType = "application/x-www-form-urlencoded";

            req.ContentType = "application/xml";

            req.Timeout = 1000 * 60 * 15; // 15 minutes

 

            byte[] arr = o.ToSerializedByteArrayUTF8();

            req.ContentLength = arr.Length;

            Stream reqStrm = req.GetRequestStream();

            reqStrm.Write(arr, 0, arr.Length);

            reqStrm.Close();

 

            try

            {

                HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

                XDocument doc = XDocument.Load(resp.GetResponseStream());

                resp.Close();

                ReturnType oResp = doc.Root.Value.ToBusinessEntity<ReturnType>(SourceFormatEnum.XML);

                return oResp;

            }

            catch (WebException wex)

            {

                throw Personify.DataServices.Serialization.DataServiceExceptionUtil.ParseException(wex);

            }

        }

 

        public static ReturnType Create<ReturnType>()

        {

            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(

                string.Format("{0}/Create?EntityName='{1}'",

                    sUri.TrimEnd('/'),

                    typeof(ReturnType).Name)

                    );

            NetworkCredential serviceCreds = new NetworkCredential(UserName, Password);

            CredentialCache cache = new CredentialCache();

            cache.Add(new Uri(sUri), "Basic", serviceCreds);

 

            req.Credentials = cache;

            req.Method = "GET";

            req.ContentType = "application/xml";

            req.Timeout = 1000 * 60 * 15; // 15 minutes

 

            try

            {

                HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

                XDocument doc = XDocument.Load(resp.GetResponseStream());

                resp.Close();

                ReturnType oEntity = doc.Root.Value.ToBusinessEntity<ReturnType>(SourceFormatEnum.XML);

                return oEntity;

            }

            catch (WebException wex)

            {

                throw Personify.DataServices.Serialization.DataServiceExceptionUtil.ParseException(wex);

            }

        }

 

        public static ReturnType Save<ReturnType>(object entityToSave)

        {

 

            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(

                string.Format("{0}/Save?EntityName='{1}'",

                    sUri.TrimEnd('/'),

                    typeof(ReturnType).Name)

                    );

            NetworkCredential serviceCreds = new NetworkCredential(UserName, Password);

            CredentialCache cache = new CredentialCache();

            Uri uri = new Uri(sUri);

            cache.Add(uri, "Basic", serviceCreds);

 

            req.Credentials = cache;

            req.Method = "POST";

            req.ContentType = "application/xml";

            req.Timeout = 1000 * 60 * 15; // 15 minutes

 

            byte[] arr = entityToSave.ToSerializedByteArrayUTF8();

            req.ContentLength = arr.Length;

            Stream reqStrm = req.GetRequestStream();

            reqStrm.Write(arr, 0, arr.Length);

            reqStrm.Close();

 

            try

            {

                HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

                XDocument doc = XDocument.Load(resp.GetResponseStream());

                resp.Close();

                ReturnType oResp = doc.Root.Value.ToBusinessEntity<ReturnType>(SourceFormatEnum.XML);

                return oResp;

            }

            catch (WebException wex)

            {

                throw Personify.DataServices.Serialization.DataServiceExceptionUtil.ParseException(wex);

            }

        }

 

        public static ReturnType Delete<ReturnType>(object entityToDelete)

        {

 

            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(

                string.Format("{0}/Delete?EntityName='{1}'",

                    sUri.TrimEnd('/'),

                    typeof(ReturnType).Name)

                    );

            NetworkCredential serviceCreds = new NetworkCredential(UserName, Password);

            CredentialCache cache = new CredentialCache();

            Uri uri = new Uri(sUri);

            cache.Add(uri, "Basic", serviceCreds);

 

            req.Credentials = cache;

            req.Method = "POST";

            req.ContentType = "application/xml";

            req.Timeout = 1000 * 60 * 15; // 15 minutes

 

            byte[] arr = entityToDelete.ToSerializedByteArrayUTF8();

            req.ContentLength = arr.Length;

            Stream reqStrm = req.GetRequestStream();

            reqStrm.Write(arr, 0, arr.Length);

            reqStrm.Close();

 

            try

            {

                HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

                XDocument doc = XDocument.Load(resp.GetResponseStream());

                resp.Close();

                ReturnType oResp = doc.Root.Value.ToBusinessEntity<ReturnType>(SourceFormatEnum.XML);

                return oResp;

            }

            catch (WebException wex)

            {

                throw Personify.DataServices.Serialization.DataServiceExceptionUtil.ParseException(wex);

            }

        }

 

        public static string FileUpload(byte[] fileContent, string TargetFileName)

        {

            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(sUri.TrimEnd('/') + "/FileUpload?fileName='" + TargetFileName + "'");

            NetworkCredential serviceCreds = new NetworkCredential(UserName, Password);

            CredentialCache cache = new CredentialCache();

            Uri uri = new Uri(sUri);

            cache.Add(uri, "Basic", serviceCreds);

            req.Credentials = cache;

            req.Method = "POST";

            req.Timeout = 1000 * 60 * 20; // 20 minutes

            req.SendChunked = true;

 

            req.ContentLength = fileContent.Length;

            Stream reqStrm = req.GetRequestStream();

            reqStrm.Write(fileContent, 0, fileContent.Length);

            reqStrm.Close();

 

            try

            {

                HttpWebResponse resp = (HttpWebResponse)req.GetResponse();

                XDocument doc = XDocument.Load(resp.GetResponseStream());

                resp.Close();

                return doc.Root.Value;

            }

            catch (WebException wex)

            {

                throw Personify.DataServices.Serialization.DataServiceExceptionUtil.ParseException(wex);

            }

 

 

        }

 

        #endregion

 

    }

 


 


 


    public static class SerializationUtils

    {

        public static TargetType ToBusinessEntity<TargetType>(this string source)

        {

            XmlSerializer x = new XmlSerializer(typeof(TargetType));

            return (TargetType)x.Deserialize(new StringReader(source));

        }

 

        public static byte[] ToSerializedByteArrayUTF8(this object o)

        {

            if (o == null)

            {

                return null;

            }

            else

            {

                return Encoding.UTF8.GetBytes(o.ToSerializedXml());

            }

        }

 

        public static string ToSerializedXml(this object o)

        {

            if (o == null)

            {

                return null;

            }

            XmlSerializer x = new XmlSerializer(o.GetType());

            StringWriter sw = new StringWriter();

            x.Serialize(sw, o);

            return sw.ToString();

        }

    }

 

    public class DataServiceClientException : Exception

    {

 

        public DataServiceClientException(string Message, string StackTrace, Exception InternalException)

            : base(Message, InternalException)

        {


            _stackTrace = StackTrace;


        }  

        private string _stackTrace;

        public override string StackTrace

        {

            get

            {

                return _stackTrace;

            }

        }

    }

 

    public static class DataServiceExceptionUtil

    {

        public static DataServiceClientException ParseException(WebException wex)

        {

            HttpWebResponse respEx = (HttpWebResponse)wex.Response;

            XDocument doc = XDocument.Load(respEx.GetResponseStream());

            return ParseExceptionRecursive(doc.Root);

        }

        private static DataServiceClientException ParseExceptionRecursive(XElement errorElement)

        {

 

            string DataServicesMetadataNamespace = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";

            XName xnCode = XName.Get("code", DataServicesMetadataNamespace);

            XName xnType = XName.Get("type", DataServicesMetadataNamespace);

            XName xnMessage = XName.Get("message", DataServicesMetadataNamespace);

            XName xnStackTrace = XName.Get("stacktrace", DataServicesMetadataNamespace);

            XName xnInternalException = XName.Get("internalexception", DataServicesMetadataNamespace);

            XName xnInnerError = XName.Get("innererror", DataServicesMetadataNamespace);

 

            switch (errorElement.Name.LocalName)

            {

                case "error":

                case "innererror":

                case "internalexception":

                    DataServiceClientException internalException2 =

                                errorElement.Element(xnInternalException) != null ?

                                            ParseExceptionRecursive(errorElement.Element(xnInternalException)) : null;

                    if (internalException2 != null) return internalException2;

                    DataServiceClientException internalException =

                                errorElement.Element(xnInnerError) != null ?

                                            ParseExceptionRecursive(errorElement.Element(xnInnerError)) : null;

                    if (internalException != null) return internalException;

                    string code = errorElement.Element(xnCode) != null ?

                                            errorElement.Element(xnCode).Value.ToString() : String.Empty;

                    string message = errorElement.Element(xnMessage) != null ?

                                            errorElement.Element(xnMessage).Value.ToString() : String.Empty;

                    string stackTrace = errorElement.Element(xnStackTrace) != null ?

                                            errorElement.Element(xnStackTrace).Value.ToString() : String.Empty;

                    return new DataServiceClientException(

                        message,

                        stackTrace,

                        (internalException == null ? internalException2 : internalException)

                        );

 

                default:

                    throw new InvalidOperationException("Could not parse WebException to DataServiceClientException");

            }

        }

    }

}

12.  Modify the “Program.cs” as shown below:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Data.Services.Client;

using TestCreateOrder.PersonifySvcRef;

 

namespace TestCreateOrder

{

    class Program

    {

        staticvoid Main(string[] args)

        {

            try

            {

                DataServiceCollection<CreateOrderLineInput> Orderlines;

                Orderlines = newDataServiceCollection<CreateOrderLineInput>(null, TrackingMode.None);

 

                CreateOrderLineInput Line = new CreateOrderLineInput();

                Line.ProductId = 609;

                Line.BaseUnitPrice = 25;

                Orderlines.Add(Line);

 

                Line = newCreateOrderLineInput();

                Line.ProductId = 194;

                Line.BaseUnitPrice = 25;

 

                DataServiceCollection<CreateSubOrderLineInput> OrderSublines;

                OrderSublines = newDataServiceCollection<CreateSubOrderLineInput>(null, TrackingMode.None);

 

                CreateSubOrderLineInput Subline = new CreateSubOrderLineInput();

                Subline.ProductId = 195;

                Subline.BaseUnitPrice = 25;

                OrderSublines.Add(Subline);

 

                Line.SubOrderLines = OrderSublines;

                Orderlines.Add(Line);

 

 

                Line = new CreateOrderLineInput();

                Line.ProductId = 176;

                Line.BaseUnitPrice = 15;

                Orderlines.Add(Line);

 

 

                Line = new CreateOrderLineInput();

                Line.ProductId = 81;

                Line.AllowBackOrder = false;

                Orderlines.Add(Line);

 

 

                CreateOrderInput op = newCreateOrderInput()

                {

                   ShipMasterCustomerID = "000000000009",

                   OrderLines = Orderlines,

                };

 

                CreateOrderOutput resp = SvcClient.Post<CreateOrderOutput>("CreateOrder", op);

                if (string.IsNullOrEmpty(resp.OrderNumber))

                    Console.WriteLine("Test failed");

                else

                    Console.Write("Order number: " + resp.OrderNumber.ToString());

            }

            catch (Exception ex)

            {

                Console.WriteLine(ex.Message);

            }

 

            Console.ReadLine();

        }

    }

}

13.  Once executed, the output should look like the following:

 

See also:

·            Creating Service Operations using Personify Data Services

·            Executing Service Operations (without code)

·            CRUD Operations