Friday, April 22, 2016

WCF - Getting Started

In this post we are going to learn the basic concepts of WCF and how to create a basic WCF Service.


What is WCF?

WCF or Windows Communication Foundations is a Microsoft platform for creating, building and deploying network-distributed services.


The ABC of Windows Communication Foundation

The "ABC" is the basic concept and also the key to understand the WCF endpoint.
  • "A" stands for Address: Where is the service?
  • "B" stands for Binding: How do I talk to the service?
  • "C" stands for Contract: What can the service do for me?


"ABC" means that creating a WCF service is a three-step process:
  • You define a contract and implement it on a service
  • You choose or define a service binding that selects a transport along with quality of service, security and other options
  • You deploy an endpoint for the contract by binding it (using the binding definition, hence the name) to a network address.


Create a WCF project

Before we start with the three-step process to create a WCF we need to create a WCF project.

When you create the project it will already have a Contract and a Service, but we will create new ones.
Delete the files IService1.cs and Service1.svc.
Now we are ready to through the three-step process.


Step #1 - Defining and Implementing Service Contracts

The Service Contract will define what operations the service supports. An operation is an action that can be executed by the service, if we compare it to the ASMX web services the operation is like the Web Service Method.
To define a Service Contract we need to create an interface and mark it with the ServiceContractAttribute attribute and the methods with the OperationContractAttribute attribute.
First let`s add a WCF Service to the project.


When you add a new WCF Service the visual studio will create a Service and also the Contract. First let`s change the contract. This is shown in the following code.


    [ServiceContract]
    public interface IOnlineDinnerService
    {
        [OperationContract]
        String OrderDinner(int comboNumber);
    }

Above, the interface is marked with the ServiceContractAttribute attribute and the method with the OperationContractAttribute attribute, as explained before it is a requirement to create a WCF Service.
Now let`s implement the interface in the Service. This is shown in the following code.


    public class OnlineDinnerService : IOnlineDinnerService
    {
 
        public String OrderDinner(int comboNumber)
        {
            return $"You have ordered the combo number {comboNumber}. Your Order Number is {new Random().Next(1, 100)}";
        }
    }

Above, we implemented the contract, now we already have our Contract and our Service created, but as you can notice our service operations just accept simple types. What if we want to use a complex type? For that we need to create the Data Contracts.


What are Data Contracts?

The Data Contract describes the data that will be exchanged between a service and a client.
The WCF uses an engine called Data Contract Serializer to serialize and deserialize data.
By default the primitive types and certain types as String and DateTime can be serialize with no proper preparation, but new complex types need to be prepared as a Data Contract. The following code show how to do it.

    [DataContract]
    public class DinnerCombo
    {
        [DataMember]
        public int ComboNumber { get; set; }
        [DataMember]
        public Decimal Price { get; set; }
        [DataMember]
        public String Name { get; set; }
    }
Now that we already have defined a DataContract we are ready to create an operation using it. To do it, first let`s add an operation to the Service Contract (IOnlineDinnerService). This is shown in the following code.

        [OperationContract]
        List<DinnerCombo> GetDinnerCombos();
Now let`s implement the new service operation in the Service. To do it, edit the OnlineDinnerService service as in the following code.

        public List<DinnerCombo> GetDinnerCombos()
        {
            return new List<DinnerCombo>()
            {
                new DinnerCombo {ComboNumber =1, Name="X-Burguer Combo", Price=6.99M },
                new DinnerCombo {ComboNumber =2, Name="Fried Chicken Combo", Price=7.99M },
                new DinnerCombo {ComboNumber =3, Name="Rosted Beef and Desert", Price=8.99M }
            };
        }

Step #2 - Configuring the binding

Bindings are used to specify the transport, encoding, and protocol details required for clients and services to communicate with each other. WCF uses bindings to generate the underlying wire representation of the endpoint, so most of the binding details must be agreed upon by the parties that are communicating.
The WCF by default offers a lot of different bindings, each binding has different types of security, transport or protocols. You can check all system-provided bindings on https://msdn.microsoft.com/en-us/library/ms730879(v=vs.110).aspx.
There are two ways to configure a binding, imperatively in code and declaratively using configuration.
In this example we will do it declaratively in the application`s web config file using the BasicHttpBinding.

  <system.serviceModel>
    <services>
      <service name="WCF.GettingStarted.OnlineDinnerService">
        <endpoint address="" binding="basicHttpBinding" contract="WCF.GettingStarted.IOnlineDinnerService"></endpoint>
        <endpoint address="/mex" binding="mexHttpBinding" contract="IMetadataExchange"></endpoint>
      </service>
    </services>
     ...
  </system.serviceModel>
Above, we the service for our OnlineDinnerService and then we created 2 endpoints, the first one uses the basicHttpBinding to communicate with the service. The second one uses mexHttpBinding, this binding will enable the service to publish it`s metadata. Check the link https://msdn.microsoft.com/en-us/library/aa751951(v=vs.110).aspx for more details about publishing metadata.


Step #3 - Deploying and endpoint for the contract

In the Step #2 we defined the binding for the endpoint, in that same endpoint you can see the tag "contract", there we defined the contract for that endpoint.
Now our service has the OnlineDinnerService implementation and this service has an endpoint using the contract IOnlineDinnerService with the basicHttpBinding.


You can download the full from the github (https://github.com/rbercocano/WCF-Getting-Started).
Enjoy!

Tuesday, April 19, 2016

WebApi - Creating custom MediaTypeFormatter for CSV format

In this example we are going to create a custom formatter to generate CSV format response using WebApi.

The technology we will be using:
  • Visual Studio 2015
  • ASP.NET WebApi 5.2.3
  • C#


What is the Media Type Formatter?

The Media Type Formatter is used during the serialization process, in other words it`s the type used to translate a .NET Common Language Runtime (CLR) type into a format that can be transmitted over HTTP. The default formats are either JSON or XML.


A media type formatter, which is an object of type MediaTypeFormatter, performs the serialization in the ASP.NET Web API pipeline.

Step #1 - Create the MVC Project

In this example we will need to create a simple WebApi Project, no authentication is required.



Step #2 - Create a Model Class

Now we need to create a model class to be serialized to the CSV format. This is shown in the following code.


    public class Employee
    {
        public int EmployeeId { get; set; }
        public String Name { get; set; }
        public DateTime AdmissionDate { get; set; }
    }

Step #3 - Create the CSV Formatter

Now let`s create a custom formatter to handle the CSV format.
To do it we will need to create a class and inherit from BufferedMediaTypeFormatter. This is shown in the following code.


public class EmployeeCsvFormatter : BufferedMediaTypeFormatter
{
      public EmployeeCsvFormatter()
      {
            SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/csv"));
            SupportedEncodings.Add(new UTF8Encoding(encoderShouldEmitUTF8Identifier: false));
            SupportedEncodings.Add(Encoding.GetEncoding("iso-8859-1"));
      }
      public EmployeeCsvFormatter(MediaTypeMapping mediaTypeMapping) : this()
      {
            MediaTypeMappings.Add(mediaTypeMapping);
      }
 
      public EmployeeCsvFormatter(IEnumerable<MediaTypeMapping> mediaTypeMappings) : this()
      {
            foreach (var mediaTypeMapping in mediaTypeMappings)
                MediaTypeMappings.Add(mediaTypeMapping);
 
      }
}
Above, no matter which constructor you use, we always add text/csv media type to be supported for this formatter. We also allow custom MediaTypeMappings to be injected.
The MediaTypeFormatter also supports multiple Encodings and in the example above we added two encodings to the Formatter.

Now let`s override the methods: MediaTypeFormatter.CanWriteType and BufferedMediaTypeFormatter.WriteToStream .

In the MediaTypeFormatter.CanWriteType method we need to check if the type is supported with this formatter in order to write it or not.

 public override bool CanWriteType(System.Type type)
        {
            if (type == typeof(Employee))
            {
                return true;
            }
            else
            {
                Type enumerableType = typeof(IEnumerable<Employee>);
                return enumerableType.IsAssignableFrom(type);
            }
        }



Now we need to implement the BufferedMediaTypeFormatter.WriteToStream method. This method will write your CSV content to the Stream. This is shown in the following code.



public override void WriteToStream(Type type, object value, Stream writeStream, HttpContent content)
        {
            Encoding effectiveEncoding = SelectCharacterEncoding(content.Headers);
            using (var writer = new StreamWriter(writeStream))
            {
                var employees = value as IEnumerable<Employee>;
                if (employees != null)
                {
                    foreach (var employee in employees)
                        WriteItem(employee, writer);
 
                }
                else
                {
                    var singleProduct = value as Employee;
                    if (singleProduct == null)
                        throw new InvalidOperationException("Cannot serialize type");
 
                    WriteItem(singleProduct, writer);
                }
            }
        }
        private void WriteItem(Employee employee, StreamWriter writer)
        {
            writer.WriteLine("{0};{1};{2}", Escape(employee.EmployeeId),
                Escape(employee.Name), employee.AdmissionDate.ToString("d"));
        }
 
        static char[] _specialChars = new char[] { ';', '\n', '\r', '"' };
        private string Escape(object o)
        {
            if (o == null)
            {
                return "";
            }
            string field = o.ToString();
            if (field.IndexOfAny(_specialChars) != -1)
            {
                // Delimit the entire field with quotes and replace embedded quotes with "".
                return String.Format("\"{0}\"", field.Replace("\"", "\"\""));
            }
            else return field;
        }

Above, we are selecting the desired Encoding and we also have created two new methods to help on the content writing. Source: http://www.asp.net/web-api/overview/formats-and-model-binding/media-formatters

If you want to download your CSV when you call the WebApi, you can override the method MediaTypeFormatter.SetDefaultContentHeaders. This is shown in the following code.

public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
        {
            base.SetDefaultContentHeaders(type, headers, mediaType);
            headers.Add("Content-Disposition", "attachment; filename=Employees.csv");
            headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
        }


Step #4 - Register the formatter

Now that the formatter is created we need to register it. Go to your WebApiConfig class or to the Global.asax and add the following code.


config.Formatters.Add(new EmployeeCsvFormatter(new QueryStringMapping("format", "csv", "text/csv")));



The QueryStringMapping will map the query string "format=csv" to the EmployeeCsvFormatter.

Step #5 - Create the WebApi Controller

Now wee need to create the WebApi Controller with the action that will return the employees. This is shown in the following code.


    [RoutePrefix("api/Employee")]
    public class EmployeeController : ApiController
    {
        public Employee[] Get()
        {
            var result = new[]
                       {
                   new Employee {AdmissionDate = DateTime.Now.AddYears(-10), Name = "John;", EmployeeId = 1 },
                   new Employee {AdmissionDate = DateTime.Now.AddYears(-3), Name = "Mark", EmployeeId = 2 },
                   new Employee {AdmissionDate = DateTime.Now.AddYears(-5), Name = "Ann", EmployeeId = 3 }
               };
 
            return result;
        }
    }


Now we have everything ready, to test it execute the application and call the api ( /api/employee?format=csv ) to see the result. Enjoy!

Microservices – Creating Resilient Services

Dealing with unexpected failures is one of the hardest problems to solve, especially in a distributed system . A microservice needs to...