Archive for the 'Web Services' Category

C# How to: Encoding Base64 Thumbnails

Article purpose

This details how to read files from the file system, create and then encoding to strings.

Sample source code

This is accompanied by a sample source code Visual Studio project which is available for download .

Images as Base64 strings

From :

Base64 is a group of similar encoding schemes that represent in an ASCII string format by translating it into a -64 representation. The Base64 term originates from a specific .

Base64 encoding schemes are commonly used when there is a need to encode binary data that need to be stored and transferred over media that are designed to deal with textual data. This is to ensure that the data remain intact without modification during transport. Base64 is commonly used in a number of applications including via , and storing complex data in .

From the definition quoted above the need for base64 encoding becomes more clear. From :

The base-64 digits in ascending order from zero are the uppercase characters "A" to "Z", the lowercase characters "a" to "z", the numerals "0" to "9", and the symbols "+" and "/". The valueless character, "=", is used for trailing padding.

encoding allows developers to expose binary data without potentially encountering conflicts in regards to the transfer medium. encoded binary data serves ideally when performing data transfer operations using platforms such as html, xml, email.

A common implementation of encoding can be found when transferring data. This article details how to convert/encode object to strings.

Base64 Image encoding implemented as an extension method

The code snippet listed below details the ToBase64String targeting the class.

public static string ToBase64String(this Image bmp)
{
    string base64String = string.Empty;
    MemoryStream memoryStream = null;

try { memoryStream = new MemoryStream(); bmp.Save(memoryStream, ImageFormat.Png); } catch (Exception exc) { return String.Empty; }
memoryStream.Position = 0; byte[] byteBuffer = memoryStream.ToArray();
memoryStream.Close();
base64String = Convert.ToBase64String(byteBuffer, Base64FormattingOptions.InsertLineBreaks); byteBuffer = null;
return base64String; }

The ToBase64String method writes the targeted object’s pixel data to a object using the Png . Next a array is extracted and passed to the method , which is responsible for implementing the encoding.

Creating an Image tag implementing a Base64 string

The sample source code in addition also defines an to generate html image tags to display a string encoded .

public static string ToBase64ImageTag(this Image bmp)
{
    string imgTag = string.Empty;
    string base64String = string.Empty;

base64String = bmp.ToBase64String();
imgTag = "<img src=\\"data:image/" + "png" + ";base64,"; imgTag += base64String + "\\" "; imgTag += "width=\\"" + bmp.Width.ToString() + "\\" "; imgTag += "height=\\"" + bmp.Height.ToString() + "\\" />";
return imgTag; }

The ToBase64ImageTag invokes the ToBase64String in order to retrieve encoded the data. The Html image tag has only to be slightly modified from the norm in order to accommodate encoded strings.

Creating Image thumbnails

The class conveniently provides the method , which we’ll be using to create from existing objects. The sample source code defines the method ToBase64Thumbnail, as listed below:

public static string ToBase64Thumbnail(this Image bmp, int width, int height, bool wrapImageTag)
{
    Image.GetThumbnailImageAbort callback = new Image.GetThumbnailImageAbort(ThumbnailCallback);

Image thumbnailImage = bmp.GetThumbnailImage(width, height, callback, new IntPtr());
string base64String = String.Empty;
if (wrapImageTag == true) { base64String = thumbnailImage.ToBase64ImageTag(); } else { base64String = thumbnailImage.ToBase64String(); }
thumbnailImage.Dispose();
return base64String; }
private static bool ThumbnailCallback() { return true; }

The ToBase64Thumbnail is defined as an targeting the class. The calling code is required to specify the width and height of the output and in addition whether to wrap the encoded string in an Html <img> tag.

Note the definition of ThumnailCallback, the method requires calling code to specify a callback delegate.

Based on the value of the parameter wrapImageTag, we next invoke either ToBase64ImageTag or ToBase64String, as defined/discussed earlier.

Reading Image files from the file system

The starting point in creating encoded would be to read the local file system, searching for files. The ToBase64Thumbnails method is defined as an targeting the string class. When invoking the ToBase64Thumbnails method users are expected to provide a directory path, width and height of output , whether to add Html <img> tags and which file types to process. The code snippet below details the implementation of the ToBase64Thumbnails method.

public static List<string> ToBase64Thumbnails(this string path, int width, int height, bool wrapImageTag, params string[] fileTypes)
{
    List<string> base64Thumbnails = new List<string>();

string searchFilter = String.Empty;
if (fileTypes != null) { for (int k = 0; k < fileTypes.Length; k++) { searchFilter += "*." + fileTypes[k];
if (k < fileTypes.Length - 1) { searchFilter += "|"; } } } else { searchFilter = "*.*"; }
string[] files = Directory.GetFiles(path, searchFilter);
for (int k = 0; k < files.Length; k++) { StreamReader streamReader = new StreamReader(files[k]); Image img = Image.FromStream(streamReader.BaseStream); streamReader.Close();
base64Thumbnails.Add(img.ToBase64Thumbnail(width, height, wrapImageTag));
img.Dispose(); }
return base64Thumbnails; }

The ToBase64Thumbnails method implements the static method in order to search a specified directory path. When invoking the ToBase64Thumbnails method the calling code can optionally specify a number of file extensions, which results in only files having file extensions conforming to the specified extensions being encoded.

Once an array of file paths have been determined the sample code iterates the array creating an object of each file specified. The final step required is to invoke the ToBase64Thumbnail.

The implementation

The sample source code defines a console based application, used to test/illustrate creating encoded based on a specified directory path.  Included in the sample code is a template html file. The Main method generates a list of encoded by invoking ToBase64Thumbnails, defined as an targeting the String class. The resulting encoded are defined as Html <img> tags, added to a copy of the html template file. The Console application’s definition:

static void Main(string[] args)
{
    string path = "Images";

List<string> thumbnailTags = path.ToBase64Thumbnails(100, 100, true, null);
StreamReader streamreader = new StreamReader("HtmlTemplate.htm"); StringBuilder htmlPage = new StringBuilder(streamreader.ReadToEnd()); streamreader.Close();
StringBuilder imageTags = new StringBuilder();
for (int k = 0; k < thumbnailTags.Count; k++) { imageTags.AppendLine("<p>"); imageTags.AppendLine(thumbnailTags[k]); imageTags.AppendLine("</p>"); }
htmlPage.Replace("<!--Tags_Placeholder-->", imageTags.ToString());
StreamWriter streamwriter = new StreamWriter("TempPage.htm", false, Encoding.UTF8); streamwriter.Write(htmlPage.ToString()); streamwriter.Close();
Process.Start("TempPage.htm");
Console.ReadKey(); }

The resulting encoded image viewed as html <img> tags forming part of an html file, as viewed in Microsoft Internet Explorer 9:

Base64Thumbnails

Advertisement

C# How to: Generate a Web Service from WSDL

Article purpose

Image FiltersWeb Service Definition Language (WSDL) is an Xml based schema that exactly details the custom data types and web service methods exposed by a web service. Developers usually generate web service client proxy code in order to call into web services. Since WSDL is an exact description of a web service it is also possible to generate code that represents the service in the form of web method stubs. This article illustrates how to generate a web service from WSDL.

Introduction

Image FiltersI’ve often found myself in a scenario where I have to interface with third parties via web services. It is often the case that third party service are proprietary, usually I find that I have very little control over the web services I’m required to interface to. Countless hours are wasted because of out dated test environments, missing/incorrect security certificates or even just trying to get hold of log files.

Image FiltersTime spent on development and testing can be significantly reduced in most cases if I had a local copy of a web service available to me. Having access to source code would be even more beneficial, being able to manipulate the data returned, testing timeouts etc. After surprisingly little effort I manage to develop a utility application capable of generating web method stubs and custom defined types in C# source code. The only required input in generating a web service is the WSDL of an existing web service.

Sample source code

Image FiltersThis article is accompanied by sample source code in a Visual Studio project which is available for download .

 

Input Web service WSDL

Image FiltersThe sample source accompanying this article defines a very simplistic web service, consisting of one web method HelloWorld(). The source code is listed below:

 [WebService (Namespace = "http://softwarebydefault.com" )]
 [WebServiceBinding (ConformsTo = WsiProfiles.BasicProfile1_1)]
 [System.ComponentModel.ToolboxItem (false )]
 public class TestWebService : System.Web.Services.WebService 
 {
     [WebMethod ]
     public string  HelloWorld()
     {
         return "Hello World";
     }
 }
 

The resulting WSDL is generated as illustrated by the following snippet:

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

<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://softwarebydefault.com" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" targetNamespace="http://softwarebydefault.com" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/">

  <wsdl:types>

    <s:schema elementFormDefault="qualified" targetNamespace="http://softwarebydefault.com">

      <s:element name="HelloWorld">

        <s:complexType />

      </s:element>

      <s:element name="HelloWorldResponse">

        <s:complexType>

          <s:sequence>

            <s:element minOccurs="0" maxOccurs="1" name="HelloWorldResult" type="s:string" />

          </s:sequence>

        </s:complexType>

      </s:element>

    </s:schema>

  </wsdl:types>

  <wsdl:message name="HelloWorldSoapIn">

    <wsdl:part name="parameters" element="tns:HelloWorld" />

  </wsdl:message>

  <wsdl:message name="HelloWorldSoapOut">

    <wsdl:part name="parameters" element="tns:HelloWorldResponse" />

  </wsdl:message>

  <wsdl:portType name="TestWebServiceSoap">

    <wsdl:operation name="HelloWorld">

      <wsdl:input message="tns:HelloWorldSoapIn" />

      <wsdl:output message="tns:HelloWorldSoapOut" />

    </wsdl:operation>

  </wsdl:portType>

  <wsdl:binding name="TestWebServiceSoap" type="tns:TestWebServiceSoap">

    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" />

    <wsdl:operation name="HelloWorld">

      <soap:operation soapAction="https://softwarebydefault.com/HelloWorld" style="document" />

      <wsdl:input>

        <soap:body use="literal" />

      </wsdl:input>

      <wsdl:output>

        <soap:body use="literal" />

      </wsdl:output>

    </wsdl:operation>

  </wsdl:binding>

  <wsdl:binding name="TestWebServiceSoap12" type="tns:TestWebServiceSoap">

    <soap12:binding transport="http://schemas.xmlsoap.org/soap/http" />

    <wsdl:operation name="HelloWorld">

      <soap12:operation soapAction="https://softwarebydefault.com/HelloWorld" style="document" />

      <wsdl:input>

        <soap12:body use="literal" />

      </wsdl:input>

      <wsdl:output>

        <soap12:body use="literal" />

      </wsdl:output>

    </wsdl:operation>

  </wsdl:binding>

  <wsdl:service name="TestWebService">

    <wsdl:port name="TestWebServiceSoap" binding="tns:TestWebServiceSoap">

      <soap:address location="http://localhost:6078/TestWS.asmx" />

    </wsdl:port>

    <wsdl:port name="TestWebServiceSoap12" binding="tns:TestWebServiceSoap12">

      <soap12:address location="http://localhost:6078/TestWS.asmx" />

    </wsdl:port>

  </wsdl:service>

</wsdl:definitions>

Generating the Web service from input WSDL

Image FiltersThe crux of this article revolves around the Generate method defined in the associated sample source code. The method makes use of the ServiceDescription and ServiceDescriptionImporter classes to reference the WSDL generated earlier. The code defined by the Generate method is very similar to the code that would generate web service client proxy code. Make note of the Style property of the ServiceDescriptionImporter object being set to ServiceDescriptionImportStyle.Server. By setting the style to server we indicate that any code generated should reflect the server interface. Had the property being set to ServiceDescriptionImportStyle.Client web service client proxy code would be generated.

Image FiltersAfter importing the service descriptions as defined by the specified WSDL and if no errors occurred we generate C# source code based on the service descriptions imported. The resulting source code generated is then saved to the file system based on the file path passed as method parameter.

 public  static  void  Generate(string  wsdlPath, string  outputFilePath)
 {
     if  (File.Exists(wsdlPath) == false )
     {
         return;
     }

     ServiceDescription  wsdlDescription = ServiceDescription .Read(wsdlPath);
     ServiceDescriptionImporter  wsdlImporter = new  ServiceDescriptionImporter ();

     wsdlImporter.ProtocolName = "Soap12";
     wsdlImporter.AddServiceDescription(wsdlDescription, null , null );
     wsdlImporter.Style = ServiceDescriptionImportStyle .Server;

     wsdlImporter.CodeGenerationOptions = System.Xml.Serialization.CodeGenerationOptions .GenerateProperties;

     CodeNamespace codeNamespace = new  CodeNamespace();
     CodeCompileUnit codeUnit = new  CodeCompileUnit();
     codeUnit.Namespaces.Add(codeNamespace);

     ServiceDescriptionImportWarnings importWarning = wsdlImporter.Import(codeNamespace, codeUnit);

     if  (importWarning == 0)
     {
         StringBuilder stringBuilder = new StringBuilder();
         StringWriter stringWriter = new StringWriter(stringBuilder);

         CodeDomProvider codeProvider = CodeDomProvider.CreateProvider("CSharp");
         codeProvider.GenerateCodeFromCompileUnit(codeUnit, stringWriter, new CodeGeneratorOptions());

         stringWriter.Close();

         File.WriteAllText(outputFilePath, stringBuilder.ToString(), Encoding.UTF8);
     }
     else 
     {
         Console.WriteLine(importWarning);
     }
 }
 

Image FiltersNotice the use of the CodeDomProvider class, creating an instance of this class allows us to generate source code. This class can also be used to compile source code to assemblies, in essence it allows developers access to a set of compilers accessible from code. As described by MSDN documentation:

A CodeDomProvider implementation typically provides code generation and/or code compilation interfaces for generating code and managing compilation for a single programming language. Several languages are supported by CodeDomProvider implementations that ship with the Windows Software Development Kit (SDK). These languages include C#, Visual Basic, C++, and JScript. Developers or compiler vendors can implement the ICodeGenerator and ICodeCompiler interfaces and provide a CodeDomProvider that extends CodeDOM support to other programming languages.

The Generated Code

Image FiltersThe code generated comes in the form of abstract classes and methods. The snippet below illustrates the raw generated code:

 [System.CodeDom.Compiler.GeneratedCodeAttribute("WSDLToWebService" , "1.0.0.0" )]
 [System.Web.Services.WebServiceAttribute(Namespace="http://softwarebydefault.com" )]
 [System.Web.Services.WebServiceBindingAttribute(Name="TestWebServiceSoap12" , Namespace="http://softwarebydefault.com" )]
 public  abstract  partial  class  TestWebService  : System.Web.Services.WebService {
     
     [System.Web.Services.WebMethodAttribute()]
     [System.Web.Services.Protocols.SoapDocumentMethodAttribute("https://softwarebydefault.com/HelloWorld" ,
         RequestNamespace="http://softwarebydefault.com" , ResponseNamespace="http://softwarebydefault.com" ,
         Use=System.Web.Services.Description.SoapBindingUse.Literal, 
         ParameterStyle=System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
     public  abstract  string  HelloWorld();
 }
 

Image FiltersThe code generated compiles without issue, but being declared abstract prevents the code from functioning as a web service implementation. I find the easiest method is to refactor the code instead of implementing inheritance. The snippet listed below represents the generated code refactored to reflect a web service implementation.

[System.CodeDom.Compiler.GeneratedCodeAttribute ("WSDLToWebService" , "1.0.0.0" )]
[System.Web.Services.WebServiceAttribute (Namespace = "http://softwarebydefault.com" )]
[System.Web.Services.WebServiceBindingAttribute (Name = "TestWebService" , Namespace = "http://softwarebydefault.com" )]
public  class  TestWebService  : System.Web.Services.WebService 
{
     [System.Web.Services.WebMethodAttribute()]
     [System.Web.Services.Protocols.SoapDocumentMethodAttribute("https://softwarebydefault.com/HelloWorld" ,
     RequestNamespace = "http://softwarebydefault.com" , ResponseNamespace = "http://softwarebydefault.com" ,
     Use = System.Web.Services.Description.SoapBindingUse.Literal, 
     ParameterStyle = System.Web.Services.Protocols.SoapParameterStyle.Wrapped)]
     public  string  HelloWorld()
     {
         return  "Hello Generated World" ;
     }
 }
 

Image FiltersThe TestWebService class and HelloWorld method is now no longer defined as abstract. In addition HelloWorld now defines a method body as required by not being an abstract method anymore.

 

About the Icons

I’ve written a number of articles exploring the topic of Colour filters. All of the Light bulb icon images featured in this article were generated from same source image, each having been manipulated by various colour filters. I made use of sample applications accompanying some of the articles I’ve published.

Image Filters Image Filters Image Filters Image Filters Image Filters Image Filters Image Filters Image Filters

If you are interested in Image filters or would like to download the sample applications and source code please have a look at the following links to articles published on this site:

 

Image Filters Image Filters Image Filters Image Filters Image Filters Image Filters Image Filters Image Filters

The original source image used to generate the icon images featured in this article has been licensed under the Creative Commons Attribution-Share Alike 3.0 Unported license and can be downloaded from .


Dewald Esterhuizen

Blog Stats

  • 843,493 hits

Enter your email address to follow and receive notifications of new posts by email.

Join 228 other subscribers

Archives


%d bloggers like this: