Implementing MVP Pattern using UserControls with WCF Database Operations in Entity Framework and LINQ – Part II

 

In this part of the tutorial – We first code for the CustomerService.cs by implementing ICustomerService.cs interface. We use LINQ queries to code database transactions. Then we create a host application (here it is a Console application) which operates the WCF service. Then we create a sample website for implementing MVP Pattern to access WCF. In the website, we implement some UserControls for fetching/updating/deleting records from the database.

Want to skip PART II –

Implementing MVP Pattern using UserControls with WCF Database Operations in Entity Framework and LINQ – Part I

 

Implementing MVP Pattern using UserControls with WCF Database Operations in Entity Framework and LINQ – Part III

 

First we start coding CustomerService.cs –

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EntityDataModelProject;

namespace CustomersDBServiceLibrary
{
    public class CustomerService : ICustomerService
    {
        public Customer GetCustomerById(int customerID)
        {
            using (CustomersDBEntities model = new CustomersDBEntities())
            {
                Customer c = new Customer();
                var custDetails = (from customer in model.Customers
                                  where customer.Id == customerID
                                  select customer).First();

                c.customerId = custDetails.Id;
                c.customerName = custDetails.CustomerName;
                c.customerEmail = custDetails.CustomerEmail;
                c.customerDOB = custDetails.CustomerDOB;

                return c;
            }
        }

        public List<Customer> GetAllCustomers()
        {
            List<Customer> customers = new List<Customer>();
            using (CustomersDBEntities model = new CustomersDBEntities())
            {
                var custs = (from customer in model.Customers
                             select customer);

                foreach (EntityDataModelProject.Customer cst in custs)
                {
                    Customer c = new Customer();

                    c.customerId = cst.Id;
                    c.customerName = cst.CustomerName;
                    c.customerEmail = cst.CustomerEmail;
                    c.customerDOB = cst.CustomerDOB;

                    customers.Add(c);
                }
            }
            return customers;
        }

        public void InsertCustomer(Customer customerDetails)
        {
            using (CustomersDBEntities model = new CustomersDBEntities())
            {
                EntityDataModelProject.Customer cust = new EntityDataModelProject.Customer();

                cust.CustomerName = customerDetails.customerName;
                cust.CustomerEmail = customerDetails.customerEmail;
                cust.CustomerDOB = customerDetails.customerDOB;

                model.AddToCustomers(cust);

                model.SaveChanges();
            }
        }

        public void UpdateCustomer(Customer customerDetails)
        {
            using (CustomersDBEntities model = new CustomersDBEntities())
            {
                var customer = (from cust in model.Customers
                               where cust.Id == customerDetails.customerId
                               select cust).FirstOrDefault();

                customer.CustomerName = customerDetails.customerName;
                customer.CustomerEmail = customerDetails.customerEmail;
                customer.CustomerDOB = customerDetails.customerDOB;

                model.SaveChanges();
            }
        }

        public void DeleteCustomerById(int customerId)
        {
            using (CustomersDBEntities model = new CustomersDBEntities())
            {
                var customer = (from cust in model.Customers
                                where cust.Id == customerId
                                select cust).FirstOrDefault();

                model.Customers.DeleteObject(customer);
                model.SaveChanges();
            }
        }

    }
}

The last procedure remaining in creating a WCF service is to configure it to end points. In this example tutorial, we configure our WCF service to basic HTTP binding.

To configure a WCF service, replace the code in app.config fileof ‘CustomersDBServiceLibrary’ as shown below –

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  
  <connectionStrings>
    <add name="CustomersDBEntities" connectionString="metadata=res://*/CustomersModel.csdl|
         res://*/CustomersModel.ssdl|res://*/CustomersModel.msl;provider=System.Data.SqlClient;
         provider connection string=&quot;Data Source=RAMILU-PC\SQLEXPRESS;Initial Catalog=CustomersDB;
         Integrated Security=True;Pooling=False;MultipleActiveResultSets=True&quot;" 
         providerName="System.Data.EntityClient" />
  </connectionStrings>
  
  <system.web>
    <compilation debug="true" />
  </system.web>
  <system.serviceModel>
    <services>
      <service name="CustomersDBServiceLibrary.CustomerService">
        <clear />
        <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"
          listenUriMode="Explicit">
          <identity>
          </identity>
        </endpoint>
        <endpoint address="http://localhost:8080/customerservice" binding="basicHttpBinding"
          bindingConfiguration="" bindingName="basic" contract="CustomersDBServiceLibrary.ICustomerService" />
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost/" />
          </baseAddresses>
        </host>
      </service>
    </services>
    <behaviors>
      <serviceBehaviors>
        <behavior>
          <serviceMetadata httpGetEnabled="True"/>
          <serviceDebug includeExceptionDetailInFaults="False" />
        </behavior>
      </serviceBehaviors>
    </behaviors>
  </system.serviceModel>

</configuration>

================================================================================================

STEP # 4 – Hosting WCF Service

Create a simple Console application which will host the WCF service created in step # 3.

================================================================================================

  1. Right Click –> ‘MVPwithWCF’ solution in the solution explorer –> Add –> New Project
  2. Select Visual C# –> Windows Template –> Console Application Template
  3. Name –> ‘CustomersDBServiceHost’
  4. Click OK

Open Program.cs (this file is automatically created on project creation time) or else do create a class of suitable name.

Before writing any code to host our WCF service. We need to add some references –

  1. Right Click ‘CustomersDBServiceHost’ in solution explorer –> Add Reference –> Projects tab –> select ‘CustomersDBServiceLibrary’ –> click OK.
  2. Right Click ‘CustomersDBServiceHost’ in solution explorer –> Add Reference –> .NET tab –> select ‘System.ServiceModel’ –> click OK.
  3. Also place a app.config file with end point configuration from the ‘CustomerDBServiceLibrary’ into ‘CustomersDBServiceHost’.

Now place the following code in the Program.cs –

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceModel;
using CustomersDBServiceLibrary;

namespace CustomersDBServiceHost
{
    class Program
    {
        static void Main(string[] args)
        {
            ServiceHost schost = new ServiceHost(typeof(CustomerService));
            schost.Open();

            Console.WriteLine("CustomerService is running...Please press enter to stop the service!!!");
            Console.ReadLine();

            schost.Close();
        }
    }
}

Once the coding part is done, we have to set the startup object for the ‘CustomerDBServiceHost’ – Right Click ‘CustomerDBServiceHost’ –> Select Properties –> Set StartUp Object to ‘Program.cs’

This completes hosting of WCF Service.

With this we completed the background processing units of the reqirement. Now lets start up with a new website which will implement MVP Pattern.

================================================================================================

STEP # 5 – Create a Website for MVP Pattern implementation

Here we create a normal ASP.Net website and use the WCF service which was created in Step # 4.

================================================================================================

  1. Right Click ‘MVPwithWCF’ Solution in the Solution Explorer of VS 2010
  2. Add –> New Website…
  3. Visual C# –> ASP.Net Empty Website –> Name: MVPWesite
  4. Click OK

First we add reference to our WCF service.

  1. For adding a service Reference to our website first we got to know the base address of the metadata (which is responsible for exchanging data to and from WCF).
  2. Typically, it will be found in the app.config file of the host as the base address. So here in this case it is ‘http://localhost/mex’.
  3. So once we have the metadata address, Right Click MVPWebsite in Solution Explorer –> Add Service Reference –> Enter the metadata address and Click Go.
  4. Give name to the namespace – here it is ‘CustomerServiceWebReference’. Click Finish.
  5. A web reference to the WCF CustomerService has been added in the App_WebReferences folder of the solution explorer.
  6. Similarly add reference to ‘CustomerDBServiceLibrary’.

================================================================================================

STEP # 6 – MVP Pattern Implementation

Lets code for Model, View and Presenter classes.

================================================================================================

Lets get started with a interface for the Model – Model class typically holds the Business logic. So in this case it holds the logic for WCF Client.

First create a folder ‘Model’ in App_Code folder of the website, then create a class – IModel.cs –

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using CustomersDBServiceLibrary;

namespace MVPCode
{
    public interface IModel
    {
        List<KeyValuePair<int,string>> GetCustomersList();
        CustomersDBServiceLibrary.Customer GetCustomer(int Id);
        void DBOperation(string command, Customer cust = null, int id = 0);
    }
}

Create a Model Class (int the same folder –Model of App_code) which implements IModel interface –

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using CustomerServiceWebReference;
using CustomersDBServiceLibrary;

namespace MVPCode
{
    public class Model : IModel
    {
        public List<KeyValuePair<int, string>> GetCustomersList()
        {
            List<KeyValuePair<int, string>> LstKeyValues = new List<KeyValuePair<int, string>>();

            CustomerServiceClient client = new CustomerServiceClient("basic_ICustomerService");
            List<Customer> lstcust = client.GetAllCustomers().ToList();

            foreach (Customer c in lstcust)
            {
                KeyValuePair<int,string> kvp = new KeyValuePair<int,string>(c.customerId,c.customerName);              
                LstKeyValues.Add(kvp);
            }
            return LstKeyValues;
        }

        public CustomersDBServiceLibrary.Customer GetCustomer(int Id)
        {
            Customer c = new Customer();

            CustomerServiceClient client = new CustomerServiceClient("basic_ICustomerService");
            c = client.GetCustomerById(Id);

            return c;
        }

        public void DBOperation(string command, CustomersDBServiceLibrary.Customer cust = null, int id = 0)
        {
            CustomerServiceClient client = new CustomerServiceClient("basic_ICustomerService");

            switch (command)
            {
                case "Insert":
                    client.InsertCustomer(cust);
                    break;
                case "Delete":
                    client.DeleteCustomerById(id);
                    break;
                case "Update":
                    client.UpdateCustomer(cust);
                    break;
                default:       
                    break;
            }
        }
    }
}

Once the Model classes are created, Lets create UserControl UI –

  1. Right Click ‘MVPWebsite’ in solution explorer –> Add New Item –> Select Visual C#
  2. Select ‘WebUserControl’ template (select Place code in separate File Checkbox) –> Name: CustomerListUserControl.ascx
  3. Click OK
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="CustomerListUserControl.ascx.cs" Inherits="CustomerListUserControl" %>
Select a Customer - 
<asp:DropDownList ID="DropDownList1" runat="server" Height="25px" Width="163px">
</asp:DropDownList>

 

We will come back to the CodeBehind of the UserControl sooner. For time being, UI will be created.

Lets create one more UserControl in the similar fashion – Name: CustomerUserControl.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeFile="CustomerUserControl.ascx.cs" Inherits="CustomerUserControl" %>
<div>
    Customer Id -
    <asp:TextBox ID="txtId" runat="server" ReadOnly="true"></asp:TextBox>
    <asp:RequiredFieldValidator ID="RequiredFieldValidator3" ValidationGroup="Customer" 
    ControlToValidate="txtId" runat="server" ErrorMessage="RequiredFieldValidator"></asp:RequiredFieldValidator>
    <asp:CompareValidator ID="CompareValidator1" ControlToValidate="txtId" ValidationGroup="Customer" 
    Type="Integer" Operator="DataTypeCheck" runat="server" ErrorMessage="CompareValidator"></asp:CompareValidator>

    <br />

    Customer Name - 
    <asp:TextBox ID="txtName" runat="server"></asp:TextBox>
    <asp:RequiredFieldValidator ID="RequiredFieldValidator2" ValidationGroup="Customer" 
    ControlToValidate="txtName" runat="server" ErrorMessage="RequiredFieldValidator"></asp:RequiredFieldValidator>

    <br />

    Customer Email -
    <asp:TextBox ID="txtEmail" runat="server"></asp:TextBox>
    <asp:RequiredFieldValidator ID="RequiredFieldValidator1" ValidationGroup="Customer" 
    ControlToValidate="txtEmail" runat="server" ErrorMessage="RequiredFieldValidator"></asp:RequiredFieldValidator>

    <br />

    Customer DOB -
    <asp:TextBox ID="txtDOB" runat="server"></asp:TextBox>
    <asp:RequiredFieldValidator ID="RequiredFieldValidator4" ValidationGroup="Customer" 
    ControlToValidate="txtDOB" runat="server" ErrorMessage="RequiredFieldValidator"></asp:RequiredFieldValidator>
    <asp:CompareValidator ID="CompareValidator2" ValidationGroup="Customer" ControlToValidate="txtDOB" 
    Type="Date" Operator="DataTypeCheck" runat="server" ErrorMessage="CompareValidator"></asp:CompareValidator>

    <br />
    <br />

    <asp:Button ID="btnInsert" runat="server" Text="Insert" ValidationGroup="Customer" 
        onclick="btnInsert_Click" />
    <asp:Button ID="btnUpdate" runat="server" Text="Update" ValidationGroup="Customer"
        onclick="btnUpdate_Click" />
    <asp:Button ID="btnDelete" runat="server" Text="Delete" ValidationGroup="Customer"
        onclick="btnDelete_Click" />

    <br />

    <asp:Label ID="lblMessage" runat="server"></asp:Label>

</div>

 

With this we end PART II of the tutorial.

To Follow up with the further more concepts lying in the creation of MVP Pattern along with the codebehind’s of the UserControls, especially with View and Presenter classes creation, Kindly look at the next part (PART III) of the tutorial.

Implementing MVP Pattern using UserControls with WCF Database Operations in Entity Framework and LINQ – Part I

 

Implementing MVP Pattern using UserControls with WCF Database Operations in Entity Framework and LINQ – Part III

Disclaimer:

All coding and suggestions made in the above discussion is strictly in point of view of the author. It is neither mentioned any where nor even concluded that this is the only possible way to go with, as there will be always a chance for a new approach in achieving the same requirement (in context of programming). The above mentioned code is strictly written and explained for the sake of new comers to C# and ASP.NET world.

You may also like...

  • Tuan Ta

    Thank you for this post.

    I have built my project based on it. I have some question for you?

    – Why we need IModel?
    – Should we apply Model like Repository pattern? And 1 present able to have multiple Models?
    – Presenter can call Service directly?

    Looking for your answer.
    Thanks

  • RamiVemula

    @Tuan – Repository pattern using Dependency injection is more appropriate. Service can be called from Model Repository itself. Imodel is one more layer of contracting, which I used.

  • Godfrey

    I amnew to this and have tried to work this tutorial for a couple of hours. I used VisualStudio 2012. I am having all kinds of problems with missing methods and other items. Is it possible to get a download of the functional project please. If you cannot put it on the site, maybe you can email it?

    Thank you.
    Godfrey

  • Godfrey

    In class Model the following could not work:

    public CustomersDBServiceLibrary.Customer GetCustomer(int Id) {
    Customer c = new Customer();

    }

    because it is an ambiguous reference. What is or am I doing wrong?