Friday 9 September 2016

CRUD operations in ASP.NET Core 1.0 MVC Application Part 7

Let's discuss how to connect to databases. We have already implemented basic CRUD operations with mockup data, now we are going to extend our application from last discussion  CRUD operations in ASP.NET Core 1.0 MVC Application Part 6 to connect with SQL Server Database. And we will be using DataAccess Project from .NET Core 1.0 Connecting SQL Server Database.
A .NET Core application can connect to a database through Database Provider. We are going to use a SQL Server Database ContactDB, therefor we are going to use Microsoft SQL Server Database Provider.

Create Data Access Project

  • Open existing Solution in Visual Studio 2015.
  • Add new WebApplicationCore.NetCore.DataAccess and add reference to Microsoft.EntityFrameworkCore.SqlServer and BaseDataAccess class following steps in .NET Core 1.0 Connecting SQL Server Database.
  • We are going to use IConfigurationRoot to get web application configurations so add Reference to Microsoft.Extensions.Configuration.Abstractions as following:
    • Open NuGet Manager through WebApplicationCore.NetCore.DataAccess Reference context menu >> References >> Manage NuGet  Packages. in Browse tab search for "Microsoft.Extensions.Configuration.Abstractions" and install.
  • Add new Constructor with parameter of IConfigurationRoot type to get configurations.
 public BaseDataAccess(IConfigurationRoot configuration)
 {
    this.ConnectionString = configuration["ConnectionStrings:DefaultConnection"];
 }



Add ContactDataAccess to WebApplicationCore.NetCore.DataAccess

  • Add reference to “WebApplicationCore.NetCore.Model” because we are going to use Contact Model Class in project.
    • Open WebApplicationCore.NetCore. BusinessLogic References >> Add References >> Reference Manager Screen >> Projects >> Solution >> Select WebApplicationCore.NetCore.Model.
    • Click OK Button.
  • Add new Interface.
    • Open Add New Item Screen through Solution Context Menu >> Add >> New Item >> Installed >> .NET Core >> Code >> Interface.
    • Name it IContactDataAccess.cs.
    • Click OK Button.
  • It will add a new interface in project. 
  • Define CRUD operations in interface.
  • Add new Class.
    • Open Add New Item Screen through Solution Context Menu >> Add >> Class >> Installed >> .NET Core >> Code >> Class.
    • Name it ContactDataAccess.cs.
    • Click OK Button.
  • It will add a new class in project. 
  • Make ContactDataAccess child of BaseDataAccess and implement IContactDataAccess.
  • Implement code to perform CRUD operation from database.
 public interface IContactDataAccess  
 {  
     Contact GetContact(int contactId);  
     List<Contact> GetContacts();  
     Contact CreateContact(Contact contact);  
     bool UpdateContact(Contact contact);  
     bool DeleteContact(int contactId);  
 }  

 public class ContactDataAccess : BaseDataAccess, IContactDataAccess
 {
    public ContactDataAccess(IConfigurationRoot configuration) : base(configuration)
    {
    }

    public Contact GetContact(int contactId)
    {
        Contact contactItem = null;

        List<DbParameter> parameterList = new List<DbParameter>();

        parameterList.Add(base.GetParameter("ContactId", contactId));

        using (DbDataReader dataReader = base.ExecuteReader("Contact_Get", parameterList, CommandType.StoredProcedure))
        {
            if (dataReader != null && dataReader.HasRows)
            {
                if (dataReader.Read())
                {
                    contactItem = new Contact();
                    contactItem.ContactId = (int)dataReader["ContactId"];
                    contactItem.Name = (string)dataReader["Name"];
                    contactItem.Address1 = (string)dataReader["Address1"];
                    contactItem.Address2 = (string)dataReader["Address2"];
                    contactItem.City = (string)dataReader["City"];
                    contactItem.ProvinceState = (string)dataReader["ProvinceState"];
                    contactItem.ZipPostalCode = (string)dataReader["ZipPostalCode"];
                    contactItem.Country = (string)dataReader["Country"];
                    contactItem.ContactNumber = (string)dataReader["ContactNumber"];
                    contactItem.Email = (string)dataReader["Email"];
                    contactItem.WebSite = (string)dataReader["WebSite"];
                }
            }
        }
        return contactItem;
    }

    public List<Contact> GetContacts()
    {
        List<Contact> contacts = new List<Contact>();
        Contact contactItem = null;

        List<DbParameter> parameterList = new List<DbParameter>();

        using (DbDataReader dataReader = base.ExecuteReader("Contact_GetAll", parameterList, CommandType.StoredProcedure))
        {
            if (dataReader != null)
            {
                while (dataReader.Read())
                {
                    contactItem = new Contact();
                    contactItem.ContactId = (int)dataReader["ContactId"];
                    contactItem.Name = (string)dataReader["Name"];
                    contactItem.Email = (string)dataReader["Email"];
                    contactItem.WebSite = (string)dataReader["WebSite"];

                    contacts.Add(contactItem);
                }
            }
        }
        return contacts;
    }

    public Contact CreateContact(Contact contact)
    {
        List<DbParameter> parameterList = new List<DbParameter>();

        DbParameter contactIdParamter = base.GetParameterOut("ContactId", SqlDbType.Int, contact.ContactId);
        parameterList.Add(contactIdParamter);
        parameterList.Add(base.GetParameter("Name", contact.Name));
        parameterList.Add(base.GetParameter("Address1", contact.Address1));
        parameterList.Add(base.GetParameter("Address2", contact.Address2));
        parameterList.Add(base.GetParameter("City", contact.City));
        parameterList.Add(base.GetParameter("ProvinceState", contact.ProvinceState));
        parameterList.Add(base.GetParameter("ZipPostalCode", contact.ZipPostalCode));
        parameterList.Add(base.GetParameter("Country", contact.Country));
        parameterList.Add(base.GetParameter("ContactNumber", contact.ContactNumber));
        parameterList.Add(base.GetParameter("Email", contact.Email));
        parameterList.Add(base.GetParameter("WebSite", contact.WebSite));

        base.ExecuteNonQuery("Contact_Create", parameterList, CommandType.StoredProcedure);

        contact.ContactId = (int)contactIdParamter.Value;

        return contact;
    }

    public bool UpdateContact(Contact contact)
    {
        bool updated = true;
        List<DbParameter> parameterList = new List<DbParameter>();

        parameterList.Add(base.GetParameter("ContactId", contact.ContactId));
        parameterList.Add(base.GetParameter("Name", contact.Name));
        parameterList.Add(base.GetParameter("Address1", contact.Address1));
        parameterList.Add(base.GetParameter("Address2", contact.Address2));
        parameterList.Add(base.GetParameter("City", contact.City));
        parameterList.Add(base.GetParameter("ProvinceState", contact.ProvinceState));
        parameterList.Add(base.GetParameter("ZipPostalCode", contact.ZipPostalCode));
        parameterList.Add(base.GetParameter("Country", contact.Country));
        parameterList.Add(base.GetParameter("ContactNumber", contact.ContactNumber));
        parameterList.Add(base.GetParameter("Email", contact.Email));
        parameterList.Add(base.GetParameter("WebSite", contact.WebSite));

        int returnValue = base.ExecuteNonQuery("Contact_Update", parameterList, CommandType.StoredProcedure);

        updated = returnValue > 0;

        return updated;
    }

    public bool DeleteContact(int contactId)
    {
        bool deleted = false;

        List<DbParameter> parameterList = new List<DbParameter>();

        parameterList.Add(base.GetParameter("ContactId", contactId));

        int returnValue = base.ExecuteNonQuery("Contact_Delete", parameterList, CommandType.StoredProcedure);

        deleted = returnValue > 0;

        return deleted;
    }
 }

Change WebApplicationCore.NetCore.BusinessLogic

  • Add reference to “WebApplicationCore.NetCore.DataAccess” in WebApplicationCore.NetCore.BusinessLogic because we are going to use ContactDataAccess in this project.
    • Open WebApplicationCore.NetCore. BusinessLogic References >> Add References >> Reference Manager Screen >> Projects >> Solution >> Select WebApplicationCore.NetCore.DataAccess.
    • Click OK Button.
  • Although we are not going to use Configuration in BusinessLogic, yet we may need it in future. To use IConfigurationRoot to get web application configurations, add Reference to Microsoft.Extensions.Configuration.Abstractions as following:
    • Open NuGet Manager through WebApplicationCore.NetCore.BusinessLogic Reference context menu >> References >> Manage NuGet  Packages. in Browse tab search for "Microsoft.Extensions.Configuration.Abstractions" and install.
  • Add new Interface.
    • Open Add New Item Screen through Solution Context Menu >> Add >> New Item >> Installed >> .NET Core >> Code >> Interface.
    • Name it IContactBusinessLogic.cs.
    • Click OK Button.
  • It will add a new interface in project. 
  • Define CRUD operations in interface.
  • Change ContactBusinessLogic to use ContactDataAccess instead of mockup data.

 public interface IContactBusinessLogic
 {
    Contact GetContact(int contactId);
    List<Contact> GetContacts();
    Contact CreateContact(Contact contact);
    bool UpdateContact(Contact contact);
    bool DeleteContact(int contactId);
 }

 public class ContactBusinessLogic: IContactBusinessLogic
 {
    private IConfigurationRoot Configuration;
    private IContactDataAccess ContactDataAccess;

    public ContactBusinessLogic(IContactDataAccess contactDataAccess, IConfigurationRoot configuration)
    {
        this.ContactDataAccess = contactDataAccess;
        this.Configuration = configuration;
    }

    public Contact GetContact(int contactId)
    {
        return this.ContactDataAccess.GetContact(contactId);
    }

    public List<Contact> GetContacts()
    {
        return this.ContactDataAccess.GetContacts();
    }

    public Contact CreateContact(Contact contact)
    {
        return this.ContactDataAccess.CreateContact(contact);
    }

    public bool UpdateContact(Contact contact)
    {
        return this.ContactDataAccess.UpdateContact(contact);
    }

    public bool DeleteContact(int contactId)
    {
        return this.ContactDataAccess.DeleteContact(contactId);
    }
 }

Changes in WebApplicationCore.NetCore.Startup 

  • Open Startup.cs in WebApplicationCore.NetCore project.
  • open WebApplicationCore.NetCore.Startup and add service dependencies in ConfigureServices method for Configuration,  ContactDataAccess and ContactBusinessLogic.
  • Update ContractController class to use ContactBusinessLogic object available from constructor through dependency injection. 
 public void ConfigureServices(IServiceCollection services)
 {
    // Add framework services.
    services.AddMvc();
                        
    services.AddSingleton<IConfigurationRoot>(sp => { return this.Configuration; });
    services.AddScoped<IContactDataAccess, ContactDataAccess>();
    services.AddScoped<IContactBusinessLogic, ContactBusinessLogic>();
 }




 public class ContactController : Controller
 {
    private IContactBusinessLogic ContactBusinessLogic;
    private IConfigurationRoot Configuration;
    private IContactDataAccess ContactDataAccess;

    public ContactController(IContactBusinessLogic contactBusinessLogic, IContactDataAccess contactDataAccess, IConfigurationRoot configuration)
    {
        this.ContactBusinessLogic = contactBusinessLogic;
        this.ContactDataAccess = contactDataAccess;
        this.Configuration = configuration;
    }

    // GET: /<controller>/
    public IActionResult Index()
    {
        List<Contact> contacts = this.ContactBusinessLogic.GetContacts();
        List<ContactListVM> contactVMs = new List<ContactListVM>();
        ContactListVM contactVM;

        foreach (Contact contact in contacts)
        {
            contactVM = new ContactListVM
            {
                ContactId = contact.ContactId,
                ContactNumber = contact.ContactNumber,
                Email = contact.Email,
                Name = contact.Name,
                WebSite = contact.WebSite
            };
            contactVMs.Add(contactVM);
        }

        return View(contactVMs);
    }

    public IActionResult GetContact(int id)
    {
        Contact contact = this.ContactBusinessLogic.GetContact(id);

        ContactVM contactVM = new ContactVM
        {
            Address1 = contact.Address1,
            Address2 = contact.Address2,
            City = contact.City,
            ContactId = contact.ContactId,
            ContactNumber = contact.ContactNumber,
            Country = contact.Country,
            Email = contact.Email,
            Name = contact.Name,
            ProvinceState = contact.ProvinceState,
            WebSite = contact.WebSite,
            ZipPostalCode = contact.ZipPostalCode
        };

        return View(contactVM);
    }

    [HttpGet]
    public IActionResult CreateContact()
    {
        ContactVM contactVM = new ContactVM();

        return View(contactVM);
    }

    [HttpPost]
    public IActionResult CreateContact(ContactVM contactVM)
    {
        if (this.ModelState.IsValid)
        {
            Contact contact = new Contact
            {
                Address1 = contactVM.Address1,
                Address2 = contactVM.Address2,
                City = contactVM.City,
                ContactId = contactVM.ContactId,
                ContactNumber = contactVM.ContactNumber,
                Country = contactVM.Country,
                Email = contactVM.Email,
                Name = contactVM.Name,
                ProvinceState = contactVM.ProvinceState,
                WebSite = contactVM.WebSite,
                ZipPostalCode = contactVM.ZipPostalCode
            };

            contact = this.ContactBusinessLogic.CreateContact(contact);

            if (contact.ContactId > 0)
            {
                return RedirectToAction("Index");
            }
        }

        return View(contactVM);
    }

    [HttpGet]
    public IActionResult UpdateContact(int id)
    {
        Contact contact = this.ContactBusinessLogic.GetContact(id);

        ContactVM contactVM = new ContactVM
        {
            Address1 = contact.Address1,
            Address2 = contact.Address2,
            City = contact.City,
            ContactId = contact.ContactId,
            ContactNumber = contact.ContactNumber,
            Country = contact.Country,
            Email = contact.Email,
            Name = contact.Name,
            ProvinceState = contact.ProvinceState,
            WebSite = contact.WebSite,
            ZipPostalCode = contact.ZipPostalCode
        };

        return View(contactVM);
    }

    [HttpPost]
    public IActionResult UpdateContact(ContactVM contactVM)
    {
        if (this.ModelState.IsValid)
        {
            Contact contact = new Contact
            {
                Address1 = contactVM.Address1,
                Address2 = contactVM.Address2,
                City = contactVM.City,
                ContactId = contactVM.ContactId,
                ContactNumber = contactVM.ContactNumber,
                Country = contactVM.Country,
                Email = contactVM.Email,
                Name = contactVM.Name,
                ProvinceState = contactVM.ProvinceState,
                WebSite = contactVM.WebSite,
                ZipPostalCode = contactVM.ZipPostalCode
            };

            if (this.ContactBusinessLogic.UpdateContact(contact))
            {
                return RedirectToAction("Index");
            }
        }

        return View(contactVM);
    }

    [HttpGet]
    public IActionResult DeleteContact(int id)
    {
        ContactVM contactVM = new ContactVM
        {
            ContactId = id
        };

        return View(contactVM);
    }

    [HttpPost]
    public IActionResult DeleteContact(ContactVM contactVM)
    {
        this.ContactBusinessLogic.DeleteContact(contactVM.ContactId);

        return RedirectToAction("Index");
    }
 }


Run Application in Debug Mode


  • Press F5 or Debug Menu >> Start Debugging or Start IIS Express Button on Toolbar to start application in debugging mode.
  • It will show Home Page in browser.
  • Click Contact List Menu Open to open Contact List Page, so we have performed Get All operation.
  • Now perform all of following operations:
    • Create New Contact.
    • Open Details of a Contact.
    • Edit and Update a Contact.
    • Delete a Contact.
    • We can observe that changes are persistent as now values have been stored in database.

Sample Contact Database

We are using a test database named ContactDB having single table Contact and Stored Procedures Contact_GetAll, Contact_Get, Contact_Create, Contact_Update and Contact_Delete for  GetAll, Get, Create, Update and Delete operations respectively. We have Scripts available to create this database in Solution as "ContractDB.sql", and to insert test data as "ContactTestData.sql". We are using SQL Server 2014 Express, you can download it from MSDN.  We are not going to discuss SQL Server Database in this article.


Sample Source Code

We have placed sample code for this session in "CRUD operations in ASP.NET Core 1.0 MVC Application Part 7_Code.zip" in https://aspdotnetcore.codeplex.com/SourceControl/latest CodePlex repository.


CRUD Operations in AP.NET Core 1.0 All Parts

CRUD operations in ASP.NET Core 1.0 MVC Application Part 1
CRUD operations in ASP.NET Core 1.0 MVC Application Part 2
CRUD operations in ASP.NET Core 1.0 MVC Application Part 3
CRUD operations in ASP.NET Core 1.0 MVC Application Part 4
CRUD operations in ASP.NET Core 1.0 MVC Application Part 5
CRUD operations in ASP.NET Core 1.0 MVC Application Part 6
CRUD operations in ASP.NET Core 1.0 MVC Application Part 7 
CRUD operations in ASP.NET Core 1.0 MVC Application Part 8

1 comment:

  1. Thanks a lot Imran:), I was facing some issue while changing the architecture from .net to .net core.
    Now it resolved.. thanks for your blog..

    ReplyDelete