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

 

In this part of the tutorial, we carry on with the construction of MVP Pattern. First we start with the creation of View interfaces for the UserControls (which we created in PART II). Then we create the presenter classes, which will take the corresponding instances of views and then manipulate the view using Model classes (there by achieving code portability). Once we are done with the presenter classes, we implement the View interfaces in the codebehind of the UserControls. Finally we create a sample ASP.Net web page (typically webform), and use the UserControls for database transactions.

Want to skip PART I –

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 II

 

Lets get started with the View interface for CustomerListUserControl.ascx –

  1. Create a folder ‘View’ in App_code folder of the ‘MVPWebsite’, then create a class ‘ICustomerListView.cs’ –
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using CustomersDBServiceLibrary;

namespace MVPCode
{
    public interface ICustomerListView
    {
        void populateDDL(List<KeyValuePair<int, string>> items);
        string SelectedValueDDL { get; set; }
        bool postback { get; set; } 
        Customer ShowCustomer { get; set; }

        CustomerListPresenter Presenter { get; }
        event EventHandler SelectionChanged;
        event EventHandler refreshDDL;
     }
}
  1. Create a view for CustomerUserControl.ascx in the similar fashion (in the same ‘View’ folder), Name it as ICustomerView.cs –
using System;
using System.Collections.Generic;
using System.Linq;
using CustomersDBServiceLibrary;

namespace MVPCode
{
    public interface ICustomerView
    {
        string Name { get; set; }
        string Email { get; set; }
        string DOB { get; set; }
        string CustId { get; set; }
        string message { set; }
        Customer GetCustomer { get; set; }

        void populateUC(Customer c);

        CustomerPresenter Presenter { get; }
        event EventHandler InsertCommand;
        event EventHandler UpdateCommand;
        event EventHandler DeleteCommand;
    }
}

Now, its time for Presenter classes –

  1. Create a folder ‘Presenter’ in the App_code folder, then create a presenter class for CustomerListUserControl.ascx – Name it ‘CustomerListPresenter.cs’ –
using System;
using System.Collections.Generic;
using System.Linq;

namespace MVPCode
{
    public class CustomerListPresenter
    {
        private ICustomerListView _view;
        private Model _model;
        public CustomerListPresenter(ICustomerListView view)
        {
            _view = view;
            _model = new Model();
        }

        public virtual void OnViewLoaded()
        {
            List<KeyValuePair<int,string>> lst = _model.GetCustomersList();

            _view.populateDDL(lst);
            _view.SelectionChanged += new EventHandler(_view_SelectionChanged);
            _view.postback = true;
        }
        void _view_SelectionChanged(object sender, EventArgs e)
        {
            LoadCurrentCustomerOnView();
        }
        private void LoadCurrentCustomerOnView()
        {
            Model m = new Model();
            _view.ShowCustomer = m.GetCustomer(Convert.ToInt32(_view.SelectedValueDDL));
        }
        public virtual void OnViewInitialized()
        {
            _view.refreshDDL +=new EventHandler(_view_refreshDDL);
        }
        void _view_refreshDDL(object sender, EventArgs e)
        {
            List<KeyValuePair<int, string>> lst = _model.GetCustomersList();

            _view.populateDDL(lst);
        }
    }
}
  1. Create a presenter class for CustomerUserControl.ascx – Name it:- CustomerPresenter.cs –
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using CustomersDBServiceLibrary;

namespace MVPCode
{
    public class CustomerPresenter
    {
        private ICustomerView _view;
        private Model model;

        public CustomerPresenter(ICustomerView view)
        {
            _view = view;
            model = new Model();
        }
        public virtual void OnViewLoaded()
        {
            Customer c = new Customer();
            if ((!String.IsNullOrEmpty(_view.DOB.ToString())) & (!String.IsNullOrEmpty(_view.Email))
                & (!String.IsNullOrEmpty(_view.CustId.ToString())) & (!String.IsNullOrEmpty(_view.Name)))
            {
                if (HttpContext.Current.Session["CurrentCustId"] != null)
                {
                    if (HttpContext.Current.Session["CurrentCustId"].ToString() == _view.CustId)
                    {
                        c.customerDOB = Convert.ToDateTime(_view.DOB);
                        c.customerEmail = _view.Email;
                        c.customerName = _view.Name;
                        c.customerId = Convert.ToInt32(_view.CustId);
                    }
                    else
                    {
                        if (Convert.ToInt32(_view.CustId) != 0)
                        {
                            c = model.GetCustomer(Convert.ToInt32(_view.CustId));
                            HttpContext.Current.Session["CurrentCustId"] = c.customerId;
                        }
                        else
                        {
                            c = model.GetCustomer(Convert.ToInt32(HttpContext.Current.Session["CurrentCustId"].ToString()));
                            HttpContext.Current.Session["CurrentCustId"] = c.customerId;
                        }
                    }
                }
            }
            else
            {
                if (HttpContext.Current.Session["CurrentCustId"] != "delete"
                    | HttpContext.Current.Session["CurrentCustId"] == null)
                {
                    c = model.GetCustomer(Convert.ToInt32(_view.CustId));
                    HttpContext.Current.Session["CurrentCustId"] = c.customerId;
                }
                else
                {
                    c = null;
                    HttpContext.Current.Session["CurrentCustId"] = null;
                }
            }
            if (c != null)
            {
                _view.populateUC(c);
            }

            _view.InsertCommand += new EventHandler(_view_InsertCommand);
            _view.UpdateCommand += new EventHandler(_view_UpdateCommand);
            _view.DeleteCommand += new EventHandler(_view_DeleteCommand);
        }

        void _view_InsertCommand(object sender, EventArgs e)
        {
            try
            {
                Customer c = new Customer();

                c.customerEmail = _view.Email;
                c.customerDOB = Convert.ToDateTime(_view.DOB);
                c.customerName = _view.Name;

                model.DBOperation("Insert", c);

                _view.message = "Successfully Inserted!!!";
            }
            catch (Exception ex)
            {
                _view.message = ex.Message;
            }
           // ClearControls();
        }

        void _view_UpdateCommand(object sender, EventArgs e)
        {
            try{
            Customer c = new Customer();

            c.customerEmail = _view.Email;
            c.customerDOB = Convert.ToDateTime(_view.DOB);
            c.customerName = _view.Name;
            c.customerId = Convert.ToInt32(_view.CustId);

            model.DBOperation("Update", c);

            _view.message = "Successfully Updated!!!";
            //ClearControls();
                        }
            catch (Exception ex)
            {
                _view.message = ex.Message;
            }
        }

        void _view_DeleteCommand(object sender, EventArgs e)
        {
            model.DBOperation("Delete", id: Convert.ToInt32(_view.CustId));

            _view.message = "Successfully Deleted!!!";
            HttpContext.Current.Session["CurrentCustId"] = "delete";
            ClearControls();
        }

        void ClearControls()
        {
            _view.CustId = "";
            _view.DOB = "";
            _view.Email = "";
            _view.Name = "";
        }
    }
}

The final step remained in the MVP architecture is to implement the Views we created above in the UserControls codebehind.

  1. Open Codebehind of CustomerListUserControl.ascx, and place the below code –
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using CustomersDBServiceLibrary;
using MVPCode;

public partial class CustomerListUserControl : System.Web.UI.UserControl,MVPCode.ICustomerListView
{
    private CustomerListPresenter _presenter;
    private List<KeyValuePair<int, string>> items;
    public event EventHandler SelectionChanged;
    public event EventHandler refreshDDL;

    protected void Page_Load(object sender, EventArgs e)
    {
            _presenter = new CustomerListPresenter(this);
            if (!this.IsPostBack)
            {
                this._presenter.OnViewLoaded();
            }
            this._presenter.OnViewInitialized();
    }

    public CustomerListPresenter Presenter
    {
        get { return _presenter; }
    }

    public bool postback
    {
        set { DropDownList1.AutoPostBack = value; }
        get { return DropDownList1.AutoPostBack; }
    }

    public string SelectedValueDDL
    {
        set { DropDownList1.SelectedValue = value; }
        get { return DropDownList1.SelectedValue; }
    }

    public Customer ShowCustomer
    {
        get;
        set;
    }

    public void populateDDL(List<KeyValuePair<int, string>> lst)
    {
        DropDownList1.Items.Clear();
        DropDownList1.Items.Add(new ListItem("Select","0"));
        foreach (KeyValuePair<int, string> val in lst)
        {
            DropDownList1.Items.Add(new ListItem(val.Value, val.Key.ToString()));
        }
    }
    protected void btnRefresh_Click(object sender, EventArgs e)
    {
        OnRefreshButtonClicked(e);
    }
    protected void OnRefreshButtonClicked(EventArgs e)
    {
        if (refreshDDL != null)
        {
            refreshDDL(this, e);
        }
    }
}

Similarly implement the corresponding view of CustomerUserControl.ascx –

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using CustomersDBServiceLibrary;
using MVPCode;

public partial class CustomerUserControl : System.Web.UI.UserControl,ICustomerView
{
    public event EventHandler InsertCommand;
    public event EventHandler UpdateCommand;
    public event EventHandler DeleteCommand;
    private CustomerPresenter _presenter;
    protected void Page_Load(object sender, EventArgs e)
    {
        _presenter = new CustomerPresenter(this);
        if (this.IsPostBack)
        {
            this._presenter.OnViewLoaded();
        }
    }
    public CustomerPresenter Presenter
    {
        get { return _presenter; }
    }
    public Customer GetCustomer
    {
        get;
        set;
    }
    public string message
    {
        set { lblMessage.Text = value; }
    }
    public string Name
    {
        get { return txtName.Text; }
        set { txtName.Text = value; }
    }

    public string CustId
    {
        get { return txtId.Text; }
        set { txtId.Text = value.ToString(); }
    }

    public string Email
    {
        get { return txtEmail.Text; }
        set { txtEmail.Text = value; }
    }

    public string DOB
    {
        get { return txtDOB.Text;  }
        set { txtDOB.Text = value.ToString(); }
    }

    public void populateUC(Customer c)
    {
        Name = c.customerName;
        Email = c.customerEmail;
        CustId = c.customerId.ToString();
        DOB = c.customerDOB.ToShortDateString();
    }
    protected void btnInsert_Click(object sender, EventArgs e)
    {
        OnInsertButtonClicked(e);
    }
    protected void OnInsertButtonClicked(EventArgs e)
    {
        if (InsertCommand != null)
        {
            InsertCommand(this, e);
        }
    }
    protected void btnUpdate_Click(object sender, EventArgs e)
    {
        OnUpdateButtonClicked(e);
    }
    protected void OnUpdateButtonClicked(EventArgs e)
    {
        if (UpdateCommand != null)
        {
            UpdateCommand(this, e);
        }
    }
    protected void btnDelete_Click(object sender, EventArgs e)
    {
        OnDeleteButtonClicked(e);
    }
    protected void OnDeleteButtonClicked(EventArgs e)
    {
        if (DeleteCommand != null)
        {
            DeleteCommand(this, e);
        }
    }
}

With this we completed the MVP Pattern implementation in the website.

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

STEP # 7 – Default.aspx creation

We create a sample Webform for implementation of our UserControls and MVP Pattern.

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

  1. Right Click ‘MVPWebsite’ in the solution Explorer –> Add New Item –> Visual C#
  2. Select Webform Template –> Name: Default.aspx (select Place code in separate file)
  3. click OK.

IMP NOTE – We use AJAX in the page, to get high interactivity.

UI of the page is as follows –

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Debug="true" Inherits="_Default" %>

<%@ Register Src="~/CustomerListUserControl.ascx" TagName="ListCustomers" TagPrefix="UC" %>
<%@ Register Src="~/CustomerUserControl.ascx" TagName="Customer" TagPrefix="UC" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>

            <asp:UpdatePanel ID="UpdatePanel2" runat="server">
            <ContentTemplate>
        <asp:Panel ID="Panel1" runat="server" BorderColor="#000066" BorderStyle="Solid" Width="600px">
        <asp:Label ID="Label2" runat="server" Font-Italic="True" Font-Size="Large"
        Text="TestUserControl1" ForeColor="#000066"></asp:Label><br />
            <UC:ListCustomers runat="server" ID="ListCustomers1"></UC:ListCustomers>
        </asp:Panel>
            </ContentTemplate>
            </asp:UpdatePanel>

        <br />
                
            <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
        <asp:Panel ID="Panel2" runat="server" BorderColor="Red" BorderStyle="Solid" Width="600px">
        <asp:Label ID="Label1" runat="server" Text="TestUserControl2" Font-Italic="True"
        Font-Size="Large" ForeColor="Red"></asp:Label>
            <UC:Customer runat="server" ID="Customer1"></UC:Customer>
         </asp:Panel>         
            </ContentTemplate>
            </asp:UpdatePanel>
    </div>
    </form>
</body>
</html>

CodeBehind of Default.aspx is as follows –

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using MVPCode;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if(IsPostBack)
            this.Customer1.CustId = this.ListCustomers1.SelectedValueDDL;
    }
}

 

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

STEP # 8 – Run Default.aspx

This section narrates how to test Default.aspx.

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

To execute Default.aspx, we need to make sure our WCF service is running. Follow the below procedure to successfully test Default.aspx –

  1. Make ‘CustomersDBServiceHost’ console application as StartUp Project (right click on ‘CustomersDBServiceHost’ in the solution explorer ans select Set as StartUp project.
  2. As already the service client i.e., Program.cs in ‘CustomersDBServiceHost’ made as startup object (in STEP 4). Pressing CTRL + F5 should open up a console command prompt, mentioning Service is running.
  3. once the service running, we can right click Default.aspx (in Solution Explorer) and select View in Browser.
  4. Thats it, we can make DB calls from Default.aspx from now.

***For detailed Demo, look at the video at the bottom of this article.

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

Folder Structure

The Complete Folder Structure of the Solution.

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

MVPwithWCFSolution-FolderStructure

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

Demo

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

 

 

With this we end the complete tutorial.

For Other Parts –

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

 

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

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...

  • Somdev Mondal

    Excellent way of conseving MVP Pattern and it Web User Control interaction with AJAX.

  • Arunachalam

    Hi ,

    This is very good article , from this i have learned how to implement the MVP patter in ASP.net

    Regards
    R.Arunachalam

  • Brazzers password

    I do consider all of the ideas you’ve offered for your post. They’re very convincing and will certainly work. Nonetheless, the posts are too brief for novices. May just you please lengthen them a little from next time? Thanks for the post.