Implenting a service operating in the web is very useful, especially if you have to share part of your data or funcionallity with other people. We are going to implement a simply service implementing the four mathematical operations.

Basics:

  • WCF: the acronym stands for Windows Communication Foundation. A WCF service is very similar to the concept of Web Service, but it is optimized and unify differents architecure types. From the .NET Framework 4.0 you can’t create a new Web Service project. The only way is use an older framework and then import it in a 4.0 or later version. Anyway, this is not a good practice, the WCF Service are better than Web Service and there is no reason to keep using an old tool.

To create a WCF Service, we need to create a WCF Service Library project. Look this link if you don’t know how to do it (only the “Creating a Service” paragraph). The link select the VB project, but here I’ll use C# code, so you should select the C# version.

Once you have created the project, delete the Service.cs and IService.cs file. We are going to re-create them ourself.

Create two class files: CalcService.cs and ICardService.cs.

In the ICardService.cs write this:


using System;
using System.ServiceModel;
using System.ServiceModel.Web;

namespace calc
{
[ServiceContract]
public interface ICalcService
{
[OperationContract]
[WebGet(UriTemplate = "AddW/{n1}/{n2}", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
string Add(string n1, string n2);
[OperationContract]
[WebGet(UriTemplate = "SubW/{n1}/{n2}", BodyStyle = WebMessageBodyStyle.Wrapped)]
string Subtract(string n1, string n2);
[OperationContract]
[WebGet(UriTemplate = "MulW/{n1}/{n2}", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
string Multiply(string n1, string n2);
[OperationContract]
[WebGet(UriTemplate = "DivW/{n1}/{n2}", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
string Divide(string n1, string n2);
}
}

The “[WebGet(UriTemplate…)]” code lines aren’t mandatory. We use them to make the WCF Service usable also from a web browser.

In the CalcService.cs write this:


using System;
using System.Configuration;
using System.IdentityModel.Selectors;
using System.ServiceModel;

namespace calc
{
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class CalcService : ICalcService
{
public string Add(string n1, string n2)
{
try
{
return (double.Parse(n1) + double.Parse(n2)).ToString();
}
catch (Exception e )
{
return "Nan";
}
}
public string Subtract(string n1, string n2)
{
try
{
return (double.Parse(n1) - double.Parse(n2)).ToString();
}
catch { return "Nan"; }

}
public string Multiply(string n1, string n2)
{
try
{
return (double.Parse(n1) * double.Parse(n2)).ToString();
}
catch { return "Nan"; }
}
public string Divide(string n1, string n2)
{
try
{
return (double.Parse(n1) / double.Parse(n2)).ToString();
}
catch { return "Nan"; }
}
}

public class CustomPass : UserNamePasswordValidator //System.IdentityModel.dll
{
private const string USERNAME_ELEMENT_NAME = "userName";

private const string PASSWORD_ELEMENT_NAME = "password";

private const string FAULT_EXCEPTION_MESSAGE = "UserName or Password is incorrect!";

public override void Validate(string userName, string password)
{
var validateUserName =     ConfigurationManager.AppSettings[USERNAME_ELEMENT_NAME];
var validatePassword = ConfigurationManager.AppSettings[PASSWORD_ELEMENT_NAME];
var validateCondition = userName.Equals(validateUserName) &&     password.Equals(validatePassword);
if (!validateCondition)
{
throw new FaultException(FAULT_EXCEPTION_MESSAGE);
}
}
}
}

The CustomPass class is used in for the Authentication. We’ll see it after.

And, finally, this is how the App.config file has to be:


<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
<add key="userName" value="JOHN"/>
<add key="password" value="SMITH"/>
</appSettings>
<system.web>
<compilation debug="true" />
</system.web>

<system.serviceModel>
<standardEndpoints/>
<bindings >
<basicHttpBinding>
<binding name="SecurityByTransport">
<security mode="TransportCredentialOnly">
<transport clientCredentialType="Basic"/>
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="calc.CalcService" behaviorConfiguration="customBehavior">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="SecurityByTransport" name="base" contract="calc.ICalcService" >
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" name="mex" contract="IMetadataExchange" />
<endpoint address="web" behaviorConfiguration="webHttp" binding="webHttpBinding"
bindingConfiguration="" name="web" contract="calc.ICalcService">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8733/Design_Time_Addresses/calc/" />
</baseAddresses>
</host>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="webHttp">
<webHttp/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior >
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
<behavior name="customBehavior">
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="True" />
<serviceCredentials>
<userNameAuthentication
userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="calc.CustomPass, calc"/>
</serviceCredentials>
</behavior>

</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="webHttpBinding" scheme="http" />
</protocolMapping>
</system.serviceModel>
</configuration>

This App.config has more tags than the one created with the tutorial for make a new WCF Service Library wizard. There the endpoint to be used from browser and the option for the authentication.

You can try the service making it run and testing with the Visual Studio client. (Note: the async method won’t work with this client) You can also call the service from a browser, for example, with this link: http://localhost:8733/Design_Time_Addresses/calc/AddW/5/5

If you publish this project and take it in a IIS Server, you can use it, also with a public address and share it.

Read this post to see how you can use it from a client.

Advertisements