But main objective behind this article is to show how to deal with DTO classes?
Data Transfer Object class explanation
This is a normal class, which WCF or service uses to communicate with the client. This class is exposed as Data Contract . WCF cannot put Data Contract on the class which is having constructors and methods. So, the business class generated by ORM (here it is Entity model) having methods, constructor and all. And that cannot be exposed as Data Contract. So we need some converter which will convert business class to DTO and DTO class to Business class.
See below image for complete description
Part "B" -> Here Business class is getting generated
Part "D" -? Converter
We will reach solution along with different part of above image
Solution:
Database (Part "A" of the image)
I am using the below table for sample. You could use any table. Name of the table is WCF and it is having two columns Name and EmpId and both are nvarchar.
Data Model (Part "B" of the image)
Step 1:
Create a WCF Service application. To do this select Proejct -> New -> Web -> WCF Service Application. Delete all the default code created. Now you have an empty contract with the name IService1 and Service implantation as Service1.
Step 2:
Right click at the project in solution explorer. And select Add New Item. From the dialog box click on Data tab and select ADO.Net Entity Model. From here create an entity model. Give some name and click on Add. After that click on Next.
From here select the Database , you want to work on
Select the table or tables and click Finish to create the Data model
You will get and .edmx file. Which will have all the tables drawn along with their relationship. Since we have selected only one table, so there is only one table depicted.
Go to solution explorer and click on Model1.Designer.cs (If you have changed the default name while creating data model to let ABC then select in solution explorer ABC.edmx.cs)
Model1.edmx.cs
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.3053
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
[assembly: global::System.Data.Objects.DataClasses.EdmSchemaAttribute()]
// Original file name:
// Generation date: 7/15/2009 8:35:01 PM
namespace DataContractSample
{
/// <summary>
/// There are no comments for kpmgdemoEntities in the schema.
/// </summary>
public partial class kpmgdemoEntities : global::System.Data.Objects.ObjectContext
{
/// <summary>
/// Initializes a new kpmgdemoEntities object using the connection string found in the 'kpmgdemoEntities' section of the application configuration file.
/// </summary>
public kpmgdemoEntities() :
base("name=kpmgdemoEntities", "kpmgdemoEntities")
{
this.OnContextCreated();
}
/// <summary>
/// Initialize a new kpmgdemoEntities object.
/// </summary>
public kpmgdemoEntities(string connectionString) :
base(connectionString, "kpmgdemoEntities")
{
this.OnContextCreated();
}
/// <summary>
/// Initialize a new kpmgdemoEntities object.
/// </summary>
public kpmgdemoEntities(global::System.Data.EntityClient.EntityConnection connection) :
base(connection, "kpmgdemoEntities")
{
this.OnContextCreated();
}
partial void OnContextCreated();
/// <summary>
/// There are no comments for WCF in the schema.
/// </summary>
public global::System.Data.Objects.ObjectQuery<WCF> WCF
{
get
{
if ((this._WCF == null))
{
this._WCF = base.CreateQuery<WCF>("[WCF]");
}
return this._WCF;
}
}
private global::System.Data.Objects.ObjectQuery<WCF> _WCF;
/// <summary>
/// There are no comments for WCF in the schema.
/// </summary>
public void AddToWCF(WCF wCF)
{
base.AddObject("WCF", wCF);
}
}
/// <summary>
/// There are no comments for kpmgdemoModel.WCF in the schema.
/// </summary>
/// <KeyProperties>
/// EmpId
/// </KeyProperties>
[global::System.Data.Objects.DataClasses.EdmEntityTypeAttribute(NamespaceName="kpmgdemoModel", Name="WCF")]
[global::System.Runtime.Serialization.DataContractAttribute(IsReference=true)]
[global::System.Serializable()]
public partial class WCF : global::System.Data.Objects.DataClasses.EntityObject
{
/// <summary>
/// Create a new WCF object.
/// </summary>
/// <param name="name">Initial value of Name.</param>
/// <param name="empId">Initial value of EmpId.</param>
public static WCF CreateWCF(string name, string empId)
{
WCF wCF = new WCF();
wCF.Name = name;
wCF.EmpId = empId;
return wCF;
}
/// <summary>
/// There are no comments for Property Name in the schema.
/// </summary>
[global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(IsNullable=false)]
[global::System.Runtime.Serialization.DataMemberAttribute()]
public string Name
{
get
{
return this._Name;
}
set
{
this.OnNameChanging(value);
this.ReportPropertyChanging("Name");
this._Name = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, false);
this.ReportPropertyChanged("Name");
this.OnNameChanged();
}
}
private string _Name;
partial void OnNameChanging(string value);
partial void OnNameChanged();
/// <summary>
/// There are no comments for Property EmpId in the schema.
/// </summary>
[global::System.Data.Objects.DataClasses.EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)]
[global::System.Runtime.Serialization.DataMemberAttribute()]
public string EmpId
{
get
{
return this._EmpId;
}
set
{
this.OnEmpIdChanging(value);
this.ReportPropertyChanging("EmpId");
this._EmpId = global::System.Data.Objects.DataClasses.StructuralObject.SetValidValue(value, false);
this.ReportPropertyChanged("EmpId");
this.OnEmpIdChanged();
}
}
private string _EmpId;
partial void OnEmpIdChanging(string value);
partial void OnEmpIdChanged();
}
}
-
This is the generated class by ADO.Net entity Data model.
-
This class contains WCF (name of the table) partial class. See in above code , Red rectangle.
-
WCF class is business class and contains Data members , methods and constructor.
-
So WCF cannot expose this as Data Contract.
Service (Part "D" of the image)
Here we will create the DTO class and converter class.
-
DTO class. Just right click and add a class. This class contains exactly the same number of property with exactly same data type of the business class got created by the Entity model.
WCFDTO.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ServiceModel ;
using System.Runtime.Serialization;
namespace DataContractSample
{
[DataContract]
public class WCFDTO
{
[DataMember]
public string Name { get; set; }
[DataMember]
public string EmpId { get; set; }
}
}
-
Converter class. This class will convert
WCFDTO class to WCF class and vice versa. This is a very simple static class, which is having two static methods. One to convert
WCF to WCFDTO and one to convert
WCFDTO to WCF.
Right click and add one more class. Give name of this class as Converter.
Converter.csusing System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace DataContractSample
{
public static class Converter
{
public static WCFDTO ConvertWCFtoWCFDTO(WCF obj)
{
WCFDTO objdto = new WCFDTO();
objdto.EmpId = obj.EmpId ;
objdto .Name = obj.Name ;
return objdto;
}
public static WCF ConvertWCFDTOtoWCF(WCFDTO obj)
{
WCF objdto = new WCF();
objdto.EmpId = obj.EmpId;
objdto.Name = obj.Name;
return objdto;
}
}
}
Service (Part "C" of the image)
-
Create the Contract. This contains operations for CRUD operation.
IService1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace DataContractSample
{
[ServiceContract]
public interface IService1
{
[OperationContract]
WCFDTO Find(string empid);
[OperationContract]
List<WCFDTO> All();
[OperationContract]
void InsertData(WCFDTO obj);
[OperationContract]
void Updatedata(WCFDTO obj);
[OperationContract]
void DeleteData(WCFDTO obj);
}
}
-
Implement the service
This is the simple CRUD operation on ADO.Net Entity model. For complete description on how to perform CRUD operation on ADO.Net Entity model, read my other articles.
Service1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace DataContractSample
{
public class Service1 : IService1
{
kpmgdemoEntities _ent;
public WCFDTO Find(string Empid)
{
_ent = new kpmgdemoEntities();
WCF res = (from r in _ent.WCF where r.EmpId == Empid select r).First();
return Converter.ConvertWCFtoWCFDTO(res);
}
public void InsertData(WCFDTO obj)
{
_ent = new kpmgdemoEntities();
WCF insertingobject = Converter.ConvertWCFDTOtoWCF(obj);
_ent.AddObject("WCF", insertingobject);
_ent.SaveChanges();
}
public void Updatedata(WCFDTO obj)
{
_ent = new kpmgdemoEntities();
WCF res = (from r in _ent.WCF where r.EmpId == obj.EmpId select r).First();
//WCF insertingobject = Converter.ConvertWCFDTOtoWCF(obj);
res.Name = obj.Name;
_ent.AcceptAllChanges();
}
public void DeleteData(WCFDTO obj)
{
_ent = new kpmgdemoEntities();
WCF res = (from r in _ent.WCF where r.EmpId == obj.EmpId select r).First();
//WCF insertingobject = Converter.ConvertWCFDTOtoWCF(obj);
_ent.DeleteObject(res);
_ent.SaveChanges();
}
public List<WCFDTO> All()
{
_ent = new kpmgdemoEntities();
var res = from r in _ent.WCF select r;
List<WCFDTO> abc= res.ToList().ConvertAll(new Converter<WCF,WCFDTO>(Converter.ConvertWCFtoWCFDTO));
return abc;
}
}
}
Build and host the service. For my purpose, I am hosting the service in .Net Web server. You may choose any options.
Client (Part "E" of the image)
Create a client and consume the service by adding the Service Reference.
For my purpose, I am creating a console application client in the same solution as of service.
After Console application creation, I added a Service Reference of the service. To do so, Right clicks in Service in solution explorer and add service reference.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TestClient.ServiceReference1;
namespace TestClient
{
class Program
{
static void Main(string[] args)
{
Service1Client proxy = new Service1Client();
WCFDTO result = proxy.Find("U18949");
Console.Read();