WCF enables you to encapsulate processes, and expose just the methods and data neccessary to share
In this example we will design a WCF service to filter the access to a database, we will expose two methods and a class
The first step is begin a new WCF Application project
This is the interface of our service, a service dedicated to retrieve and insert data in a chemical elements table, with every Contract defined, plus one for providing information about possible exceptions to the client side
namespace Chemistry
{
[ServiceContract]
public interface IChemicalService
{
[OperationContract]
[FaultContract(typeof(AccessFault))]
Element[] GetElements();
[OperationContract]
[FaultContract(typeof(AccessFault))]
string InsertElement(Element element);
}
[DataContract]
public class Element
{
[DataMember]
public string AtomicSymbol { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string LatinName { get; set; }
}
[DataContract]
public class AccessFault
{
[DataMember]
public string ExceptionType { get; set; }
[DataMember]
public string StackTrace { get; set; }
}
}
The code file of our service implements this interface, so we implement these methods in it
This is the code for retrieve data, the method GetElements()
public Element[] GetElements()
{
try
{
SqlCommand retrieveCommand = new SqlCommand()
{
Connection = OpenConnection(),
CommandType = CommandType.StoredProcedure,
CommandText = "P_SELECT_ELEMENTS",
CommandTimeout = 20
};
SqlDataReader reader =
retrieveCommand.ExecuteReader(CommandBehavior.CloseConnection);
Element[] Elements = new Element[0];
int index = 0;
while (reader.Read())
{
Array.Resize<Element>(ref Elements, Elements.Length + 1);
Element element = new Element()
{
AtomicSymbol = reader[0].ToString(),
Name = reader[1].ToString(),
LatinName = reader[2].ToString()
};
Elements[index++] = element;
}
return Elements;
}
catch (Exception ex)
{
AccessFault fault = new AccessFault()
{ ExceptionType = ex.GetType().ToString(),
StackTrace = ex.StackTrace };
throw new FaultException<AccessFault>
(fault, new FaultReason(ex.Message));
}
}
And this is the method for inserting data
public string InsertElement(Element element)
{
try
{
SqlCommand insertCommand = new SqlCommand()
{
Connection = OpenConnection(),
CommandType = CommandType.StoredProcedure,
CommandText = "P_INSERT_ELEMENT",
CommandTimeout = 20,
};
insertCommand.Parameters.AddRange(new SqlParameter[] {
new SqlParameter("@asymbol", element.AtomicSymbol),
new SqlParameter("@name", element.Name),
new SqlParameter("@latinname", element.LatinName)});
insertCommand.ExecuteNonQuery();
insertCommand.Connection.Close();
return element.AtomicSymbol;
}
catch (Exception ex)
{
AccessFault fault = new AccessFault()
{ ExceptionType = ex.GetType().ToString(),
StackTrace = ex.StackTrace };
throw new FaultException<AccessFault>
(fault, new FaultReason(ex.Message));
}
}
Now we will test the io of the service with WCF Test Client tool. Execute the service from Visual Studio and add the Url to WCF Test Client
The next step is deploying the service for its usage from different points. For this we run inetmgr, and add a new web site. Make sure your IIS is configured to allow ASP.NET v4.0 applications. You can set up this configuration with the next prompt command
After this we publish the service
Now we browse our service from IIS HostedChemicalService web site
While configuring the web site and the parameters for the service publication, we can choose any port, minding it's not busy by other application, in our case the deployment Url is
http://localhost:9789/ChemicalService.svc
The final step is calling the service layer for interacting with the database. With this purpose we create a client application, called ChemicalClient, and we add the Service Reference to the project
The code is as follows
private void btnGetElements_Click(object sender, EventArgs e)
{
try
{
ChemicalServiceClient client = new ChemicalServiceClient();
Element[] elements = client.GetElements();
dgvElements.DataSource = elements.ToList();
lblResult.Text = elements.Length.ToString() + " were found";
}
catch (FaultException<AccessFault> ex)
{
lblResult.Text = ex.Message +
ex.Detail.ExceptionType + ex.Detail.StackTrace;
}
}
private void btnInsertElement_Click(object sender, EventArgs e)
{
try
{
ChemicalServiceClient client = new ChemicalServiceClient();
Element elemToInsert = new Element()
{
AtomicSymbol = txtAtomicSymbol.Text,
Name = txtName.Text,
LatinName = txtLatinName.Text
};
string elemKey = client.InsertElement(elemToInsert);
lblResult.Text = elemKey + " was added correctly";
}
catch (FaultException<AccessFault> ex)
{
lblResult.Text = ex.Message +
ex.Detail.ExceptionType + ex.Detail.StackTrace;
}
}
With a correct execution, we get the next result
<METHOD SOFTWARE © 2012>