Friday, December 21, 2012

Uploading images to server in silverlight

 

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.Winking smile) 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.


image


Note: Only add the image of a beautiful girl, as silverlight respond very well to it. Winking smile


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.


image




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,



  1. FileStream

  2. 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>

 

If you were with me through out the posts, just copying and pasting the above code in the config file will do it for you. Else you have to make some little bit changes. I’ll be writing post, describing on how to configure the web.config/app.config file(s) for WCF. Meanwhile the above code will be enough. Build the entire solution once. If it compiles without error you are lucky, xml for web.config worked for you. Now add the service reference of the service UploadImageService in the client project and name that reference as UploadImage.

 

image

 

Reaching so far was a challenge in itself, going forward from here is very easy. We need to call the ‘Upload’ function of our service and pass the byte array of our image to it. Three line of code will do it for you. Continuing from the previous post How to snap image of any control in silverlight in the button click event just add the following three lines:

 


   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.

Share this post

0 comments

:) :-) :)) =)) :( :-( :(( :d :-d @-) :p :o :>) (o) [-( :-? (p) :-s (m) 8-) :-t :-b b-( :-# =p~ :-$ (b) (f) x-) (k) (h) (c) cheer

 
© 2013 Neelesh Vishwakarma
Posts RSS Comments RSS
Back to top