In the service interface layer, we need to modify a few classes, including the product fault class, the data contract class, and the service implementation classes.
We need to add a new file called ProductFault.cs
to the project FaultContracts
. This will be used to create a constructor with one string parameter.
The partial ProductFault
class should look like this:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyWCF.LINQNorthwind.FaultContracts { public partial class ProductFault { public ProductFault(string message) { this.faultMessage = message; } } }
For the data contract class, we need to make the following changes:
using
statement like this:using System.Data.Linq;
private
variable:private Binary lastUpdateVersion;
public
property:[WcfSerialization::DataMember(Name = "lastUpdateVersion", IsRequired = true, Order = 5)] public Binary LastUpdateVersion { get { return lastUpdateVersion; } set { lastUpdateVersion = value; } }
The reason we have to change the type for the member UnitPrice from decimal to decimal? is that in the database, the column UnitPrice is nullable, but in Service Factory, you can't specify a property of an entity class to be a nullable data type.
Also, Service Factory doesn't support the data type Binary
(timestamp), so we have to manually add the LastUpdateVersion
property to the product data contract.
We also need to change the ServiceImplementation
project. We will need to add a reference to the DataAccess
project, add a translator class, modify the data contract class, and implement the GetProduct
and UpdateProduct
operations.
We need to add two references to the ServiceImplementation
project.
In this solution, we can't ask the Service Factory to create the translator classes. This is because we now have to translate between the data contracts and the data entities defined within the LINQ to SQL designer class, while Service Factory is restricted to translating between the data contracts and the business entities defined within the BusinessEntities
project.
Because we can't use Service Factory, we have to manually add a translator class to translate between the ProductEntity
and the Product
data contract. We will call this translator class TranslateBetweenProductEntityAndProduct
, and the source code is very similar to the code in the previous chapters, except that now there is one more property to translate LastUpdateVersion
.
The ProductEntity
class here is the one inside the DataAccess
layer assembly, and not the one inside the BusinessEntities
assembly.
The translator class should be as follows:
using System; using MyWCF.LINQNorthwind.DataContracts; using MyWCF.LINQNorthwind.DataAccess; namespace MyWCF.LINQNorthwind.ServiceImplementation { public static class TranslateBetweenProductEntityAndProduct { public static MyWCF.LINQNorthwind.DataAccess.ProductEntity TranslateProductToProductEntity(MyWCF.LINQNorthwind. DataContracts.Product from) { MyWCF.LINQNorthwind.DataAccess.ProductEntity to = new MyWCF.LINQNorthwind.DataAccess.ProductEntity(); to.ProductID = from.ProductID; to.ProductName = from.ProductName; to.QuantityPerUnit = from.QuantityPerUnit; to.UnitPrice = from.UnitPrice; to.Discontinued = from.Discontinued; to.LastUpdateVersion = from.LastUpdateVersion; return to; } public static MyWCF.LINQNorthwind.DataContracts.Product TranslateProductEntityToProduct(MyWCF.LINQNorthwind. DataAccess.ProductEntity from) { MyWCF.LINQNorthwind.DataContracts.Product to = new MyWCF.LINQNorthwind.DataContracts.Product(); to.ProductID = from.ProductID; to.ProductName = from.ProductName; to.QuantityPerUnit = from.QuantityPerUnit; to.UnitPrice = from.UnitPrice; to.Discontinued = from.Discontinued; to.LastUpdateVersion = from.LastUpdateVersion; return to; } } }
Finally, for the WCF service, we need to implement the operations in the service contract. The Service Factory only generates empty operation methods, and we have to write the code by ourselves.
To implement the two get
and update
operations, we need to add a new partial class ProductService.cs
to the project, and customize this to contain the GetProduct
and UpdateProduct
methods. The GetProduct
method is the same as the one in Chapter 8, and the UpdateProduct
method should be as follows:
public override UpdateProductResponse UpdateProduct(UpdateProductRequest request) { ProductEntity productEntity; productEntity = TranslateBetweenProductEntityAndProduct.TranslateProductToProductEntity(request.Product); // call business entity layer to update a product bool updateResult = false; try { updateResult = productLogic.UpdateProduct(productEntity); } catch (Exception e) { throw new FaultException<ProductFault>(new ProductFault("could not update product. Error message:" + e.Message)); } // create a response message UpdateProductResponse response = new UpdateProductResponse(); response.UpdateResult = updateResult; // return the response message return response; }
Inside this method, we first translate the Product
object from the request message to a ProductEntity
object, and then call the business logic layer to update this project. If there is anything wrong with this update, we throw a Fault
back to the client. Otherwise, we return a response message back to the client.
As you can see, the source code in the interface layer is almost identical to the code in previous chapters, except for the different references to the ProductEntity
class.