Silverlight is a client side technology, in order to do anything related to data, whether being fetching it or saving it, requires communication with the server. This can be done via lot of methods, common among them are WCF and WCF RIA services. WCF RIA is just an extension WCF services. We are going to user WCF in this post in order to upload images onto the server.
The following post is the continuation of my previous post on How to snap image of any control in silverlight where I’d described the full process of snapping image of any silverlight control.
In the end of the process described, what we had left with was the stream of the snapped image. Now, what next step would be is to pass that stream to the server. Being client side technology, Silverlight have no access to system’s hardware therefore the image have to be passed to server in order to be uploaded. This Client to Server communication, we’ll be handling via WCF service. As I promised, that in the next post, I will be using picture of a beautiful girl (if you are a girl reading this, remember I don’t break my promises.) So we are going to upload image of ‘Natalie Portman’. In order to do so, a small change has to be made in the previous project’s mainpage.xaml file. Replace the <canvas/> tag with the following code.
1: <Image Grid.Column="1" Name="Canvals1" Source="/Uploading;component/Images/Natalie.jpg"/>
Add any image of your interest in the Images folder of client project.
Note: Only add the image of a beautiful girl, as silverlight respond very well to it.
That’s it with the image. Next is to create the service in the server that will actually receive the stream of the image that client will send. So, Create a ‘Service’ folder in the web project, and then add a WCF Service UploadImageService.svc to it.
After adding the service, visual studio would have navigated you to the interface IUploadImageService.cs. If not, just open the file. Change the function ‘DoWork’ In your interface to the following:
1: [ServiceContract]
2: public interface IUploadImageService
3: {
4: [OperationContract]
5: void Upload(byte[] bytes);
6: }
By doing this, we’ve declared that we are going to use a function named ‘Upload’ which will return nothing, but do take an argument in the form of byte array. Once we’ve declared that, we are ready to use it. In order to do so, we need to implement the interface. So, open the class file UploadImageService.svc.cs and implement IUploadImageService interface to UploadImageService class. Then implement the unimplemented methods. This will create a method ‘Upload’ in the class. Now, to upload the image, we are going to use two classes,
- FileStream
- BinaryWriter
File stream basically creates the stream of the file mentioned in the filepath. And BinaryWriter writes bytes in that filestream. Following is the overall structure of the class UploadImageService.
1: public class UploadImageService : IUploadImageService
2: {
3: public void Upload(byte[] bytes)
4: {
5: FileStream fileStream = null;
6: BinaryWriter writer = null;
7: try
8: {
9: fileStream = new FileStream(@"d:\myimage.png", FileMode.Create, FileAccess.Write);
10: writer = new BinaryWriter(fileStream);
11: writer.Write(bytes);
12:
13: }
14: catch (Exception ex)
15: {
16: }
17: finally
18: {
19: if (fileStream != null)
20: {
21: fileStream.Close();
22: }
23: if (writer != null)
24: {
25: writer.Close();
26: }
27: }
28:
29: }
30: }
With this, one more step and our service will be ready to be used by clients. Web.config file has to be modified so as to make the clients to communicate with the service through service endpoints. I am not going to show steps to configure the configuration file creating endpoints binding etc. It’s already been described in Easy way to perform duplexing in Silverlight. Instead, here is the whole code of my web.config file.
1: <?xml version="1.0"?>
2: <configuration>
3: <system.serviceModel>
4: <bindings>
5: <basicHttpBinding>
6: <binding name="BasicHttpBinding_DBService"
7: maxBufferPoolSize="2147483647"
8: maxReceivedMessageSize="2147483647" maxBufferSize="2147483647">
9: <readerQuotas maxDepth="2147483647"
10: maxArrayLength="2147483647" maxBytesPerRead="2147483647"
11: maxNameTableCharCount="2147483647"
12: maxStringContentLength="2147483647"/>
13: <security mode="None"/>
14: </binding>
15: </basicHttpBinding>
16: </bindings>
17: <behaviors>
18: <serviceBehaviors>
19: <behavior name="BehaviourOfService">
20: <dataContractSerializer maxItemsInObjectGraph="655360"/>
21: <serviceMetadata httpGetEnabled="true"/>
22: <serviceDebug includeExceptionDetailInFaults="true"/>
23: </behavior>
24: </serviceBehaviors>
25: </behaviors>
26: <services>
27: <service behaviorConfiguration="BehaviourOfService"
28: name="Uploading.Web.Services.UploadImageService">
29: <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
30: <endpoint binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_DBService"
31: contract="Uploading.Web.Services.IUploadImageService"/>
32: </service>
33: </services>
34: <serviceHostingEnvironment
35: aspNetCompatibilityEnabled="false" multipleSiteBindingsEnabled="true"/>
36: </system.serviceModel>
37: <system.web>
38: <compilation debug="true"/>
39: </system.web>
40: </configuration>
1: byte[] bytes = stream.ToArray();
2: UploadImageServiceClient _client = new UploadImageServiceClient();
3: _client.UploadAsync(bytes);
So our over all button click even would be:
1: private void button1_Click(object sender, RoutedEventArgs e)
2: {
3: MemoryStream stream = new MemoryStream();
4: Export(Canvals1,stream,new PngBitmapEncoder());
5: BitmapImage img = new BitmapImage();
6: img.SetSource(stream);
7: image2.Source = img;
8: byte[] bytes = stream.ToArray();
9: UploadImageServiceClient _client = new UploadImageServiceClient();
10: _client.UploadAsync(bytes);
11: }
Compile the project and run it. You will see ‘Natalie Portman’s’ image on the left side in the browser. Click on the snap button. If everything was right, you’ll get no error, no code break, and in drive d: the image should be uploaded with the name ‘MyImage.png’. Here is the link of the overall project: http://www.4shared.com/rar/uuSDvw61/Uploading.html.
0 comments