Creating a WCF Service, Business Object and Data Submission with Silverlight 4

Exclusive offer: get 50% off this eBook here
Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

Microsoft Silverlight 4 Business Application Development: Beginner’s Guide — Save 50%

Build enterprise-ready business applications with Microsoft Silverlight 4 with this book and eBook

$32.99    $16.50
by Frank LaVigne | April 2010 | Beginner's Guides Microsoft Web Development Web Graphics & Video

Packt are due to launch a new Enterprise brand, into which future Silverlight titles will be published. For more information on that launch, look here.

In this article by Frank LaVigne, author of Microsoft Silverlight 4 Business Application Development, we shall:

  • Create a WCF service and business object for receiving data
  • Submitting data to the server

Data applications

When building applications that utilize data, it is important to start with defining what data you are going to collect and how it will be stored once collected. In the last chapter, we created a Silverlight application to post a collection of ink strokes to the server. We are going to expand the inkPresenter control to allow a user to submit additional information.

Most developers would have had experience building business object layers, and with Silverlight we can still make use of these objects, either by using referenced class projects/libraries or by consuming WCF services and utilizing the associated data contracts.

Time for action – creating a business object

We'll create a business object that can be used by both Silverlight and our ASP.NET application. To accomplish this, we'll create the business object in our ASP.NET application, define it as a data contract, and expose it to Silverlight via our WCF service.

Start Visual Studio and open the CakeORamaData solution. When we created the solution, we originally created a Silverlight application and an ASP.NET web project.

  1. In the web project, add a reference to the System.Runtime.Serialization assembly.
  2. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

  3. Right-click on the web project and choose to add a new class. Name this class ServiceObjects and click OK.
  4. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

  5. In the ServiceObjects class file, replace the existing code with the following code:
  6. using System;
    using System.Runtime.Serialization;

    namespace CakeORamaData.Web
    {
    [DataContract]
    public class CustomerCakeIdea
    {
    [DataMember]
    public string CustomerName { get; set; }
    [DataMember]
    public string PhoneNumber { get; set; }
    [DataMember]
    public string Email { get; set; }
    [DataMember]
    public DateTime EventDate { get; set; }
    [DataMember]
    public StrokeInfo[] Strokes { get; set; }
    }

    [DataContract]
    public class StrokeInfo
    {
    [DataMember]
    public double Width { get; set; }
    [DataMember]
    public double Height { get; set; }
    [DataMember]
    public byte[] Color { get; set; }
    [DataMember]
    public byte[] OutlineColor { get; set; }
    [DataMember]
    public StylusPointInfo[] Points { get; set; }
    }

    [DataContract]
    public class StylusPointInfo
    {
    [DataMember]
    public double X { get; set; }
    [DataMember]
    public double Y { get; set; }
    }
    }

  7. What we are doing here is defining the data that we'll be collecting from the customer.

What just happened?

We just added a business object that will be used by our WCF service and our Silverlight application. We added serialization attributes to our class, so that it can be serialized with WCF and consumed by Silverlight.

The [DataContract] and [DataMember] attributes are the serialization attributes that WCF will use when serializing our business object for transmission. WCF provides an opt-in model, meaning that types used with WCF must include these attributes in order to participate in serialization. The [DataContract] attribute is required, however if you wish to, you can use the [DataMember] attribute on any of the properties of the class.

By default, WCF will use the System.Runtime.Serialization.DataContractSerialzer to serialize the DataContract classes into XML. The .NET Framework also provides a NetDataContractSerializer which includes CLR information in the XML or the JsonDataContractSerializer that will convert the object into JavaScript Object Notation (JSON). The WebGet attribute provides an easy way to define which serializer is used.

For more information on these serializers and the WebGet attribute visit the following MSDN web sites:
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializer.aspx.
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.netdatacontractserializer.aspx.
http://msdn.microsoft.com/en-us/library/system.runtime.serialization.json.datacontractjsonserializer.aspx.
http://msdn.microsoft.com/en-us/library/system.servicemodel.web.webgetattribute.aspx.

Windows Communication Foundation (WCF)

Windows Communication Foundation (WCF) provides a simplified development experience for connected applications using the service oriented programming model. WCF builds upon and improves the web service model by providing flexible channels in which to connect and communicate with a web service. By utilizing these channels developers can expose their services to a wide variety of client applications such as Silverlight, Windows Presentation Foundation and Windows Forms.

Service oriented applications provide a scalable and reusable programming model, allowing applications to expose limited and controlled functionality to a variety of consuming clients such as web sites, enterprise applications, smart clients, and Silverlight applications.

When building WCF applications the service contract is typically defined by an interface decorated with attributes that declare the service and the operations. Using an interface allows the contract to be separated from the implementation and is the standard practice with WCF.

You can read more about Windows Communication Foundation on the MSDN website at: http://msdn.microsoft.com/en-us/netframework/aa663324.aspx.

Time for action – creating a Silverlight-enabled WCF service

Now that we have our business object, we need to define a WCF service that can accept the business object and save the data to an XML file.

  1. With the CakeORamaData solution open, right-click on the web project and choose to add a new folder, rename it to Services.
  2. Right-click on the web project again and choose to add a new item. Add a new WCF Service named CakeService.svc to the Services folder. This will create an interface and implementation files for our WCF service. Avoid adding the Silverlight-enabled WCF service, as this adds a service that goes against the standard design patterns used with WCF:
  3. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

    The standard design practice with WCF is to create an interface that defines the ServiceContract and OperationContracts of the service. The interface is then provided, a default implementation on the server. When the service is exposed through metadata, the interface will be used to define the operations of the service and generate the client classes. The Silverlight-enabled WCF service does not create an interface, just an implementation, it is there as a quick entry point into WCF for developers new to the technology.

  4. Replace the code in the ICakeService.cs file with the definition below. We are defining a contract with one operation that allows a client application to submit a CustomerCakeIdea instance:
  5. using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;

    namespace CakeORamaData.Web.Services
    {
    // NOTE: If you change the interface name "ICakeService" here,
    you must also update the reference to "ICakeService" in Web.config.
    [ServiceContract]
    public interface ICakeService
    {
    [OperationContract]
    void SubmitCakeIdea(CustomerCakeIdea idea);
    }
    }

  6. The CakeService.svc.cs file will contain the implementation of our service interface. Add the following code to the body of the CakeService.svc.cs file to save the customer information to an XML file:
  7. using System;
    using System.ServiceModel.Activation;
    using System.Xml;

    namespace CakeORamaData.Web.Services
    {
    // NOTE: If you change the class name "CakeService" here, you
    must also update the reference to "CakeService" in Web.config.
    [AspNetCompatibilityRequirements(RequirementsMode =
    AspNetCompatibilityRequirementsMode.Allowed)]
    public class CakeService : ICakeService
    {
    public void SubmitCakeIdea(CustomerCakeIdea idea)
    {
    if (idea == null) return;
    using (var writer = XmlWriter.Create(String.Format(@"C:\
    Projects\CakeORama\Customer\Data\{0}.xml", idea.CustomerName)))
    {
    writer.WriteStartDocument();

    //<customer>
    writer.WriteStartElement("customer");
    writer.WriteAttributeString("name", idea.CustomerName);
    writer.WriteAttributeString("phone", idea.PhoneNumber);
    writer.WriteAttributeString("email", idea.Email);

    // <eventDate></eventDate>
    writer.WriteStartElement("eventDate");
    writer.WriteValue(idea.EventDate);
    writer.WriteEndElement();

    // <strokes>
    writer.WriteStartElement("strokes");

    if (idea.Strokes != null && idea.Strokes.Length > 0)
    {
    foreach (var stroke in idea.Strokes)
    {
    // <stroke>
    writer.WriteStartElement("stroke");

    writer.WriteAttributeString("width", stroke.Width.
    ToString());
    writer.WriteAttributeString("height", stroke.Height.
    ToString());

    writer.WriteStartElement("color");
    writer.WriteAttributeString("a", stroke.Color[0].
    ToString());
    writer.WriteAttributeString("r", stroke.Color[1].
    ToString());
    writer.WriteAttributeString("g", stroke.Color[2].
    ToString());
    writer.WriteAttributeString("b", stroke.Color[3].
    ToString());
    writer.WriteEndElement();

    writer.WriteStartElement("outlineColor");
    writer.WriteAttributeString("a", stroke.
    OutlineColor[0].ToString());
    writer.WriteAttributeString("r", stroke.
    OutlineColor[1].ToString());
    writer.WriteAttributeString("g", stroke.
    OutlineColor[2].ToString());
    writer.WriteAttributeString("b", stroke.
    OutlineColor[3].ToString());
    writer.WriteEndElement();

    if (stroke.Points != null && stroke.Points.Length > 0)
    {
    writer.WriteStartElement("points");
    foreach (var point in stroke.Points)
    {
    writer.WriteStartElement("point");
    writer.WriteAttributeString("x", point.
    X.ToString());
    writer.WriteAttributeString("y", point.
    Y.ToString());
    writer.WriteEndElement();
    }
    writer.WriteEndElement();
    }

    // </stroke>
    writer.WriteEndElement();
    }
    }

    // </strokes>
    writer.WriteEndElement();

    //</customer>
    writer.WriteEndElement();

    writer.WriteEndDocument();
    }
    }
    }
    }

    We added the AspNetCompatibilityRequirements attribute to our CakeService implementation. This attribute is required in order to use a WCF service from within ASP.NET.

  8. Open Windows Explorer and create the path C:\Projects\CakeORama\Customer\Data on your hard drive to store the customer XML files.
  9. One thing to note is that you will need to grant write permission to this directory for the ASP.NET user account when in a production environment.

  10. When adding a WCF service through Visual Studio, binding information is added to the web.config file. The default binding for WCF is wsHttpBinding, which is not a valid binding for Silverlight. The valid bindings for Silverlight are basicHttpBinding, binaryHttpBinding (implemented with a customBinding), and netTcpBinding. We need to modify the web.config, so that Silverlight can consume the service. Open the web.config file and add this customBinding section to the <system.serviceModel> node:
  11. <bindings>
    <customBinding>
    <binding name="customBinding0">
    <binaryMessageEncoding />
    <httpTransport>
    <extendedProtectionPolicy policyEnforcement="Never" />
    </httpTransport>
    </binding>
    </customBinding>
    </bindings>

  12. We'll need to change the <service> node in the web.config to use our new customBinding, (we use the customBinding to implement binary HTTP which sends the information as a binary stream to the service), rather than the wsHttpbinding from:
  13. <service behaviorConfiguration="CakeORamaData.Web.Services.
    CakeServiceBehavior"
    name="CakeORamaData.Web.Services.CakeService">
    <endpoint address="" binding="wsHttpBinding"
    contract="CakeORamaData.Web.Services.ICakeService">
    <identity>
    <dns value="localhost" />
    </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IM
    etadataExchange" />
    </service>

    To the following:

    <service behaviorConfiguration="CakeORamaData.Web.Services.
    CakeServiceBehavior"
    name="CakeORamaData.Web.Services.CakeService">
    <endpoint address="" binding="customBinding" bindingConfiguratio
    n="customBinding0"
    contract="CakeORamaData.Web.Services.ICakeService" />
    <endpoint address="mex" binding="mexHttpBinding" contract="IMeta
    dataExchange" />
    </service>

  14. Set the start page to the CakeService.svc file, then build and run the solution. We will be presented with the following screen, which lets us know that the service and bindings are set up correctly:
  15. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

  16. Our next step is to add the service reference to Silverlight. On the Silverlight project, right-click on the References node and choose to Add a Service Reference:
  17. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

  18. On the dialog that opens, click the Discover button and choose the Services in Solution option. Visual Studio will search the current solution for any services:
  19. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

  20. Visual Studio will find our CakeService and all we have to do is change the Namespace to something that makes sense such as Services and click the OK button:
  21. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

  22. We can see that Visual Studio has added some additional references and files to our project. Developers used to WCF or Web Services will notice the assembly references and the Service References folder:
  23. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

  24. Silverlight creates a ServiceReferences.ClientConfig file that stores the configuration for the service bindings. If we open this file, we can take a look at the client side bindings to our WCF service. These bindings tell our Silverlight application how to connect to the WCF service and the URL where it is located:
  25. <configuration>
    <system.serviceModel>
    <bindings>
    <customBinding>
    <binding name="CustomBinding_ICakeService">
    <binaryMessageEncoding />
    <httpTransport
    maxReceivedMessageSize="2147483647" maxBufferSize="2147483647">
    <extendedProtectionPolicy policyEnforcemen
    t="Never" />
    </httpTransport>
    </binding>
    </customBinding>
    </bindings>
    <client>
    <endpoint address="http://localhost:2268/Services/
    CakeService.svc"
    binding="customBinding" bindingConfiguration="Cust
    omBinding_ICakeService"
    contract="Services.ICakeService"
    name="CustomBinding_ICakeService" />
    </client>
    </system.serviceModel>
    </configuration>

Microsoft Silverlight 4 Business Application Development: Beginner’s Guide Build enterprise-ready business applications with Microsoft Silverlight 4 with this book and eBook
Published: April 2010
eBook Price: $32.99
Book Price: $54.99
See more
Select your format and quantity:

What just happened?

We created a Windows Communication Foundation service that is Silverlight ready. In the process, we also followed the best practice guidelines by defining a service interface and a separate implementation. The service accepts a complex data object and writes the data to an XML file.

We included the AspNetCompatibilityRequirements attribute to the CakeService.svc.cs class which is required in order to host a WCF service from within ASP.NET. We added to the class declaration rather than the interface, because it is implementation-specific and is only valid on class declarations.

We saw how easy it is to create a WCF service and add a service reference to a Silverlight application.

Data submission

Data collected from users does not provide a benefit unless the user can submit it and we can store the information for later retrieval. The ability to analyze and report on the data is how businesses acquire and maintain clients and customers, which is where the profits are derived from.

Time for action – submitting data to the server

Now that we have setup a form for data input and validated the data, we can now submit the data to the server using our WCF service. We need to submit the information to the server in order for the sales staff of Cake O Rama to be able to review and contact the customer.

  1. Switch back over to Visual Studio, open the MainPage.xaml.cs file and then add the following to the using statements:
  2. using CakeORamaData.Services;

  3. At the bottom of this file add the ConvertStrokesToStrokeInfoArray method. This method will convert the Silverlight Stroke objects from the inkPresenter to StrokeInfo objects as defined by our WCF service:
  4. private ObservableCollection<StrokeInfo>
    ConvertStrokesToStrokeInfoArray()
    {
    var strokeCollection = new ObservableCollection<StrokeInfo>();

    foreach (Stroke stroke in this.inkPresenter.Strokes)
    {
    var strokeInfo = new StrokeInfo
    {
    Width = stroke.DrawingAttributes.Width,
    Height = stroke.DrawingAttributes.Height,
    Color = new byte[]
    {
    stroke.DrawingAttributes.Color.A,
    stroke.DrawingAttributes.Color.R,
    stroke.DrawingAttributes.Color.G,
    stroke.DrawingAttributes.Color.B
    },
    OutlineColor = new byte[]
    {
    stroke.DrawingAttributes.OutlineColor.A,
    stroke.DrawingAttributes.OutlineColor.R,
    stroke.DrawingAttributes.OutlineColor.G,
    stroke.DrawingAttributes.OutlineColor.B
    }
    };
    strokeCollection.Add(strokeInfo);

    var pointCollection = new ObservableCollection
    <StylusPointInfo>();
    strokeInfo.Points = pointCollection;
    foreach (StylusPoint point in stroke.StylusPoints)
    {
    var pointInfo = new StylusPointInfo
    {
    X = point.X,
    Y = point.Y
    };
    pointCollection.Add(pointInfo);
    }
    }
    return strokeCollection;
    }

    Note here that when we added a reference to the WCF service, our StrokeInfo[] array on the CustomerCakeIdea object was converted to a System.Collections.ObjectModel.ObservableCollection<StrokeInfo> by Silverlight.

  5. Go to the submitButton_Click method and modify it to resemble the following code:
  6. private void submitButton_Click(object sender, System.Windows.
    RoutedEventArgs e)
    {
    var bindingExpression = customerName.GetBindingExpression(TextBo
    x.TextProperty);
    bindingExpression.UpdateSource();

    bindingExpression = phoneNumber.GetBindingExpression(TextBox.
    TextProperty);
    bindingExpression.UpdateSource();

    bindingExpression = emailAddress.GetBindingExpression(TextBox.
    TextProperty);
    bindingExpression.UpdateSource();

    if (!Validation.GetHasError(customerName)
    && !Validation.GetHasError(phoneNumber)
    && !Validation.GetHasError(emailAddress))
    {
    var info = LayoutRoot.DataContext as CustomerInfo;

    var idea = new CustomerCakeIdea
    {
    CustomerName = info.CustomerName,
    PhoneNumber = info.PhoneNumber,
    Email = info.Email,
    EventDate = info.EventDate,
    Strokes = ConvertStrokesToStrokeInfoArray()
    };
    var client = new CakeServiceClient();
    client.SubmitCakeIdeaCompleted += new EventHandler
    <AsyncCompletedEventArgs>(OnCakeIdeaSubmissionComplete);
    client.SubmitCakeIdeaAsync(idea);
    }
    }

  7. Add the following method to handle the SubmitCakeIdeaCompleted event to display a MessageBox once the submission is complete:
  8. private void OnCakeIdeaSubmissionComplete(object sender,
    AsyncCompletedEventArgs e)
    {
    MessageBox.Show("Sketch has been submitted.");
    }

    Now we will test out our cake idea submission form and process. Build and run the solution in Visual Studio and when the Silverlight application loads in the browser input some information and draw a cake sketch:

    Microsoft Silverlight 4 Business Application Development: Beginner’s Guide
  9. When we submit the information to the server, we will get a MessageBox telling us that we submitted the information, as shown in the next screenshot:
  10. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide
  11. Open Windows Explorer and navigate to the path that we setup in the WCF service for storing the customer XML files, and open the newly submitted file. We should now have the data from the cake sketch and customer information in our XML file.
  12. Microsoft Silverlight 4 Business Application Development: Beginner’s Guide

    If we open the XML file, we should see the saved customer and ink stroke information:

    <?xml version="1.0" encoding="utf-8"?>
    <customer name="John Doe" phone="555-555-5555" email="jdoe@
    somewhere.com">
    <eventDate>2009-10-04T16:03:41.0966771-04:00</eventDate>
    <strokes>
    <stroke width="3" height="3">
    <color a="255" r="0" g="0" b="0" />
    <outlineColor a="0" r="0" g="0" b="0" />
    <points>
    <point x="92" y="189" />
    <point x="91" y="192" />
    <point x="90" y="197" />
    <point x="89" y="199" />
    <point x="88" y="208" />
    <point x="88" y="210" />
    <point x="88" y="212" />
    <point x="88" y="213" />
    </points>
    </strokes>
    </customer>

What just happened?

We placed code in the MainPage.xaml.cs file to ensure that all of our text input controls did not have any validation errors, by making use of the Validation class.

We made use of the CustomerCakeIdea business object to store the customer input and ink stroke data and sent that information to the server via the WCF service, where we saved the information to an XML file for later use by the sales staff. We used an anonymous delegate to handle the asynchronous response from the WCF service and utilized a messagebox to inform the user of the successful submission.

Summary

In this article, we discussed the following:

  • How to create a Windows Communication Foundation service
  • How to mark a business object for serialization in WCF
  • How to consume a WCF in Silverlight and process an asynchronous request

If you have read this article you may be interested to view :

Microsoft Silverlight 4 Business Application Development: Beginner’s Guide Build enterprise-ready business applications with Microsoft Silverlight 4 with this book and eBook
Published: April 2010
eBook Price: $32.99
Book Price: $54.99
See more
Select your format and quantity:

About the Author :


Frank LaVigne

Frank LaVigne has been hooked on software development since he was 12, when he got his own Commodore 64 computer. Since then, he's worked as developer for fi nancial fi rms on Wall Street and also in Europe. He has worked on various Tablet PC soluti ons and on building advanced user experiences in Silverlight and WPF. He lives in the suburbs of Washington, DC. He founded the CapArea.NET User Group Silverlight Special Interest Group and has been recognized by Microsoft as a Tablet PC MVP. He blogs regularly at www.FranksWorld.com.

 

Books From Packt


Microsoft Silverlight 4 Data and Services Cookbook
Microsoft Silverlight 4 Data and Services Cookbook

.NET Compact Framework 3.5 Data Driven Applications
.NET Compact Framework 3.5 Data Driven Applications

Django 1.1 Testing and Debugging
Django 1.1 Testing and Debugging

Building Websites with DotNetNuke 5
Building Websites with DotNetNuke 5

Blender 3D 2.49 Incredible Machines
Blender 3D 2.49 Incredible Machines

Moodle 1.9 Theme Design: Beginner's Guide
Moodle 1.9 Theme Design: Beginner's Guide

3D Game Development with Microsoft Silverlight 3: Beginner's Guide
3D Game Development with Microsoft Silverlight 3: Beginner's Guide

Pentaho 3.2 Data Integration: Beginner's Guide
Pentaho 3.2 Data Integration: Beginner's Guide


Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software