This section illustrates creating an actual WCF service with Visual Studio 2015. We will develop an implementation for a WCF customer profile service. This example is similar to the Web API service example created earlier to allow comparison between the two methods for developing services. The following steps outline the process of exposing this functionality as a WCF service:
1. Start by creating a new WCF Service Application project. Name the project CustomerServices
.
2. Use Solution Explorer to rename the interface and service files to ICustomerProfile.cs
and CustomerProfile.svc
, respectively.
Note that the service also contains a markup file (not shown in Solution Explorer). You will need to right-click the service, CustomerProfile.svc
, in Solution Explorer and choose View Markup. Here you need to change the Service
attribute to point to your actual service name. Figure 19.19 shows an example.
3. Add a class to the project to represent the customer. (Consider this the model class for the customer, as you saw in the Web API example.) Name the class Customer.cs
.
4. Define the Customer
class as shown in Listing 19.14. Notice that this class uses the attribute DataContract
to indicate that the class represents a WCF service data contract. Each property of the class must also be marked as DataMember
.
using System.Runtime.Serialization;
namespace CustomerServices
{
[DataContract]
public class Customer
{
[DataMember]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Email { get; set; }
[DataMember]
public bool OptInEmail { get; set; }
[DataMember]
public string Notes { get; set; }
}
}
5. Open the ICustomerProfile.cs
file and remove the template code in the file. Here you will define an interface for working with the customer profile service. Start by marking the interface with the ServiceContract
attribute. Next, add method definitions for working with a Customer
instance. Each method definition should be marked with the OperationContract
attribute.
Your code should look similar to that in Listing 19.15. (Notice the similarities between this class and the Customer
model class created earlier in this chapter in the Web API sample.)
using System.Collections.Generic;
using System.ServiceModel;
namespace CustomerServices
{
[ServiceContract]
public interface ICustomerProfile
{
[OperationContract]
IEnumerable<Customer> GetList();
[OperationContract]
Customer Get(int id);
[OperationContract]
void Delete(int id);
[OperationContract]
void Create(Customer customer);
[OperationContract]
void Update(Customer customer);
}
}
6. Open the CustomerProfile.svc.cs
class file. Here you implement the code for the interface defined in the preceding step. To start, remove the template code inside the class definition. Next, add a class definition that implements the ICustomerProfile
interface. You should see a lightbulb in the code editor to help you stub out the implementation methods. Figure 19.20 shows an example.
7. Write code for each of the service methods to work with the data contract. Listing 19.16 shows the complete code. Notice that it looks a lot like the code created for the Web API sample. It, too, simulates database lookup by using a static list of customers in lieu of a database connection. It then just works with this collection through CRUD operations to get a customer, get a list of customers, create a new customer, update an existing customer, and delete a customer.
Notice that neither the class nor method definitions need to be marked with attributes. Instead, the interface takes care of that on our behalf.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Web;
using System.Text;
namespace CustomerServices
{
public class CustomerProfile : ICustomerProfile
{
static readonly List<Customer> _customers = new List<Customer>()
{
new Customer { Id = 1, Name = "Customer 1", Email = "[email protected]" },
new Customer { Id = 2, Name = "Customer 2", Email = "[email protected]" },
new Customer { Id = 3, Name = "Customer 3", Email = "[email protected]" }
};
public Customer Get(int id)
{
var customer = _customers.FirstOrDefault(x => x.Id == id);
if (customer == null)
{
throw new NullReferenceException(
string.Format("Customer {0} not found.", id.ToString()));
}
return customer;
}
public IEnumerable<Customer> GetList()
{
return _customers;
}
public void Create(Customer customer)
{
//Get next customer ID for collection.
customer.Id = 1 + _customers.Max(x => (int?)x.Id) ?? 0;
_customers.Add(customer);
}
public void Update(Customer customer)
{
//Get customer to be updated.
var customerToUpdate = _customers.FirstOrDefault(
x => x.Id == customer.Id);
if (customerToUpdate == null)
{
throw new NullReferenceException(
string.Format("Customer {0} not found.", customer.Id.ToString()));
}
else
{
//Simulate updating the customer values.
customerToUpdate.Name = customer.Name;
customerToUpdate.Notes = customer.Notes;
customerToUpdate.Email = customer.Email;
customerToUpdate.OptInEmail = customer.OptInEmail;
}
}
public void Delete(int id)
{
var customer = _customers.FirstOrDefault(x => x.Id == id);
if (customer == null)
{
throw new NullReferenceException(
string.Format("Customer {0} not found.", id.ToString()));
}
_customers.Remove(customer);
}
}
}