ASP.net MVC Web App on 3-Tier for Beginners | Web Application

May 4, 2017 | Author: Anonymous | Category: ASP.NET
Share Embed


Short Description

NET MVC web app when it is designed on 3-layers. Overview. Q. Do you want to see a live web app built on 3-Tier arch usi...

Description

https://www.codeproject.com/articles/841324/asp-net-mvc-web-app-on-tier-for-beginners-part-1

ASP.NET MVC Web App on 3-Tier for Beginners – Part 1 ASP.NET MVC Web App on 3-Tier for Beginners – Part 1  

Download script - 7.1 KB Now you can download the complete source code from codeplex

Objective The objective of this article series is to make the beginners understand how data moves from one layer to another layer in ASP.NET MVC web app when it is designed on 3-layers.

Overview Q. Do you want to see a live web app built on 3-Tier arch using ASP.NET MVC, jQuery, Bootstrap, C#.NET, Entity Framework and Microsoft SQL Server? A. Here it is http://linkhub.manzoorthetrainer.com/ http://linkhub.manzoorthetrainer.com/.. Q. Are you really excited to learn how to develop this 3-tier web app on ASP.NET MVC and Entity Framework? A. Then you are going to learn it here with me from scratch. In this article, we are going to learn how to break requirements into objects and find relation among them. We will then learn designing database out of these objects and relationships. Moving forward, we will also see how to design a basic 3-Tier architecture of the project and implement various layers. We are going to learn implementation of business object layer using Entity Framework and data access layer using repository design pattern and Entity Framework. For user interface, we will see ASP.NET MVC, jQuery and Bootstrap. We will learn how  bootstrap makes our application appl ication responsive. responsiv e. We will also see how to implement custom cus tom sorting and paging. Moving ahead, you will learn forms validations and business rules validations as well. We are going to secure our app using custom membership provider and role provider and publish it on the web. In Advance operations, we will try to understand how to implement transactions, bind multiple models to single view and Ajaxifiying our ASP.NET web app. Finally, we will also see few SSRS client side reporting.

Tools Requirements  

SQL Server 2008 Express or higher VS2013 Express or higher

Target Audience  

Should be good at OOPs through C#.NET Should have good understanding of ASP.NET MVC and Entity Framework

Disclaimer The sample code is solely based on my self-study, research results and based on any practical  project. The code is just for the th e purpose of explaining explain ing the overall architecture architec ture only. If you want to use the code in your project, you need to enrich and modify it to meet your own needs. In addition, the CRUD operations in the sample project are very primitive with basic features, you can enrich them with some advanced features.

Content 1: Introduction

Introduction 2: Analysis And Design

Requirements Gathering, Identifying Objects And Relationships, Designing Database, Database Implementation And Understanding Architecture, Creating Solution And Projects. 3: Implementing All the Layers

Creating Business Object Layer Using Entity Framework, UI Prototyping, Designing Controllers And Actions, Implementing Bootstrap 4: Implementing User And Admin Module

Creating Data Access Layer Using Repository Design Pattern, Creating Business Logic Layer And Implement BrowseUrLs, Filtering BrowseURLs, Implementing Custom Sorting in MVC on BrowseUrls table, Implementing Custom Paging in MVC on BrowseUrls table, Implementing ListUsers, ListCategory And DeleteCategory 5: Architectural Enhancements And Validations

Implementing CreateCategory With Forms Validation, Implementing SubmitUrl And Adding Base Class in BLL - AdminBsClass, Creating Base Classes For BLL And Controllers, Implementing Approve Urls And UserRegistration 6: Securing ASP.NET MVC Web App

Implementing Authentication-I, Implementing Authentication-II, Implementing Authorization

Target Audience  

Should be good at OOPs through C#.NET Should have good understanding of ASP.NET MVC and Entity Framework

Disclaimer The sample code is solely based on my self-study, research results and based on any practical  project. The code is just for the th e purpose of explaining explain ing the overall architecture architec ture only. If you want to use the code in your project, you need to enrich and modify it to meet your own needs. In addition, the CRUD operations in the sample project are very primitive with basic features, you can enrich them with some advanced features.

Content 1: Introduction

Introduction 2: Analysis And Design

Requirements Gathering, Identifying Objects And Relationships, Designing Database, Database Implementation And Understanding Architecture, Creating Solution And Projects. 3: Implementing All the Layers

Creating Business Object Layer Using Entity Framework, UI Prototyping, Designing Controllers And Actions, Implementing Bootstrap 4: Implementing User And Admin Module

Creating Data Access Layer Using Repository Design Pattern, Creating Business Logic Layer And Implement BrowseUrLs, Filtering BrowseURLs, Implementing Custom Sorting in MVC on BrowseUrls table, Implementing Custom Paging in MVC on BrowseUrls table, Implementing ListUsers, ListCategory And DeleteCategory 5: Architectural Enhancements And Validations

Implementing CreateCategory With Forms Validation, Implementing SubmitUrl And Adding Base Class in BLL - AdminBsClass, Creating Base Classes For BLL And Controllers, Implementing Approve Urls And UserRegistration 6: Securing ASP.NET MVC Web App

Implementing Authentication-I, Implementing Authentication-II, Implementing Authorization

7: Applying Bootstrap Theme

Applying New Bootstrap Theme And Implementing Slider-I, Applying New Bootstrap Theme And Implementing Slider-II 8: Implementing Transactions

Binding Multiple Models To A Single View, Working With Identity Field, Transactions 9: Ajaxifying An MVC App

Ajaxifying Demo, Making A JQuery Based Ajax Call, Implementing Approve And Reject ALL With Update Progress Bar, Partial Page Update In MVC 10: External Login

Login With Gmail, Login With Facebook 11: The Final Push

ProjectSetup - Source Code, Publishing Your Site Live 12: Reports In ASP.NET MVC

RDLC Reports In ASP.NET

1: Introduction Link hub is a web portal where a user can submit her/his portal URL under a specific category to be shared on link hub. Admin can approve or reject the URL submitted by the user and in each case an email is sent out to the user. Once the link is approved, it will be available on the link hub portal. This is what we are going to achieve:

Screen 1. User Registration

Screen 2. User Login

Screen 3. Submit URL After Login

Screen 4. URL approval by Admin

Screen 5. Browse All The Approved URL

Note: In future articles, we will also try to see some extra features whose screens are not described here.

2: Analysis And Design (Requirements Gathering, Identifying Objects And Relationships, Designing Database, Database Implementation) Let us say that the client has given us brief requirements or you can also call it as user story, i.e., they need to develop a portal called as LINKHUB… Link hub is a web portal where a user can submit his/her portal URL under a specific category to be shared on link hub. Admin can approve or reject the URL submitted by the user and in each case an email is sent out to the user. Once the link is approved, it will be available on the link hub portal. Step 1

From the above requirements, let us define the roles and responsibilities first. DefiningtheRoles&ResponsibilitiesRoles 



User o o o Admin o o

Can Browse URLs Can Register Can Submit A URL Can CRUD Category Can View All Users

o

Can ApproveOrReject URL

Step 2

 Now let us identify the object. obj ect. Objects   

User Category URL

Step 3

 Now we need to find the relationship relations hip among these objects obje cts Relationships  

Category: Url (1:M) (As a single category can have many URLs) User: Url (1:M) (As a single user can upload many URLs)

Step 4

Once we have objects and relationships with us, we can go designing the database with the 3 key rules of database design. 3KeyRulesForDatabaseDesign

1. One table for each object 2. For 1:M relationship. 1 will become master and M will become child, i.e., primary key of 1 will act as a foreign key for M.

E.g.: Department : Employees is 1 : M Department

3. M:M relationship. Both the objects will become master and there will be one more new table called as transaction table or child table with primary keys of masters as foreign Keys in it.

E.g.: Student : Course is M : M

With these above three rules, our database design would look something like this and role column in the tbl_User table will differentiate a normal user as ‘U’ and Admin as ‘A’.

LinkHubDb

Let us implement it:

Step 5

Once we have our database ready, we need to insert few meaningful and dummy records which will help us in further implementation process.

Understanding the Architecture

Data Access Layer

In the above architecture, our application’s back end is Microsoft SQL Server and to access the data from the database we are using ADO.NET Entity Framework and we call it as Data Access Layer (DAL).

Business Logic Layer

Before I store data into the database or after reading data from the database, I need to perform some business logic on the data. For example, I want to store the salary of an employee and it is $25 per hour and say he is worked for 50hrs. So, his salary would be calculated as 25X50=1250$ which is called as business logic and this logical code will go to business logic

layer and it will be developed using C#.NET programming language. So, here it is Business Logic Layer (BLL).

UI

 Now, how do I interact with the application? Yes, the interface from which I interact with the application is called as user interface of presentation logic layer where we see all the form controls like textboxes, buttons, grids, etc., and we are going to use ASP.NET MVC 5 to implement our Presentation Logic Layer (PLL).

Business Object Layer

And finally, how do I pass the data from one layer to another layer? We need a container to store the data so that we can pass that container to other layers and that container is called as  business object and they reside in Business Object Layer (BOL).

Therefore, we need to have a solution which should contain the following four projects: 1. 2. 3. 4.

UI (ASP.NET MVC Web App) BOL (C# Class Library to generate a DLL) BLL (C# Class Library to generate a DLL) DAL (C# Class Library to generate a DLL)

That’s it for the day. In our next article, we will see Creating Solution And Projects. Thanks for reading.

https://www.codeproject.com/articles/846054/asp-net-mvc-web-app-on-tier-for-beginners-part-2

ASP.NET MVC Web App on 3-Tier for Beginners – Part 2 ASP.NET MVC Web App on 3-tier for beginners

Introduction This article is the continuation of Part 1. In the first article, we saw understanding of requirements and then breaking them into objects, then finding out the relationships among them and finally designing and implementing the database. Now, let us see how to create a solution, then add multiple projects to it and then add desired references to the respective  projects.

2: Analysis and Design (Creating Solution and Projects) Create a new project in Visual Studio as LinkHubUI, choose desired path and click OK.

Select Empty project, check the MVC check box and click on OK.

 Now, we will add some list of tasks which will make us implement the project easily. We will add a text file, right click on project, add Add New Item and name it as ToDoList.txt .

This ToDoList contains the list of tasks that we need to perform.

This is a step-by-step process to implement the layered architecture in MVC. I’ve done a little hard work on it to give you these steps. So, I’m sure this is very much helpful for you when you are implementing a project for the first time.  Now our first task is creating a solution with all projects. Right click on solution and add new project. Choose from C# -> Class Library and name it as BOL (Business Object Layer).

Remove Class1.cs file from BOL project.

Add one more Class Library project and name it as BLL (Business Logic Layer) and delete Class1.cs from BLL project.

Finally, add one more new Class Library project and name it as DAL (Data Access Layer) and delete Class1.cs file from DAL.

Our Project Architecture

 Now, if we look at our architecture, you can see that UI is interacting with BLL and BOL. So, I need to add  BLL.dll  and  BOL.dll  in UI.

BLL is interacting with BOL and DAL. Add  BOL.dll  and  DAL.dll  references to BLL.

DAL is interacting with BOL. Add  BOL.dll  reference to DAL. If I try to add reference of BLL.dll  for DAL, there will be an error (Circular Dependency).

So, we should add the references moving from left to right as per our Arch (Start from Left layer and see with what layer it is interacting with in right and add the DLL along with common object layer which is on top). Save All and Rebuild Solution.

 Now, we are set with all projects and DLLs. We are done with the f irst step in ToDoList. In our next article, we will see creating BOL with the help of Entity Framework.

3: Implementing All the Layers Creating Business Object Layer (BOL)

What actually BOL is and how do we create Business Objects? Actually, BOL is nothing but almost a replica of your database tables in the form of Classes. So, for one table in database, we need to have one Class in our BOL or we will have an equivalent Class for each table. As, we know, that table is nothing but a relation and Class’s instance is an object. So, Object Relation Mapping (ORM or OR Mapping) is done in BOL. Now, let us take an example tbl_Department table (Relation) which has got Did (Department ID), DName (Department  Name) and Description as columns. So, I’m going to create an equivalent class for tbl_Department with properties as Did of type int, DName and Description of type string. So, we can say Relation, Object and Mapping  between them. I can call it as OR Mapping. Previously, we used to write these classes. But, with the help of Entity Framework, we will  be generating these classes automatically. Below slid is for single table. What about the tables with 1 to many Relationship?

 Now let us say we have tbl_Department and tbl_Employee table and one Department can contain n number of employees if I’ve this relation as shown below. How are we going to implement these as classes? It is very simple, we are going to create a class tbl_Department. As we know, department contains n number of employees. So, we will have list of tbl_Employee as a property in tbl_Department class. And tbl_Employee is another class for table tbl_Employee. And also we know that each and every Employee belongs to particular department. So, tbl_Employee class contains one extra property, i.e., object of tbl_Department. So for one-to-many relationship below is the class structure. Finally what about many-tomany relationship?

We know that last relationship is many-to-many.

Let us take an example of Student and Course. One student can opt for n number of courses and one course can be opted by n number of students. In this scenario, we need to have an extra class to show many to many relationship between tbl_Student and tbl_Course i.e., tbl_Student_Course . Now you can see that a student opted for a course is described by Sid and Cid in class tbl_Student_Course .

And also we are mapping tbl_student and tbl_Course in class tbl_Student_Course . One student can opt for n number of courses. So, tbl_Student class has List of tbl_Student_Course . And one course can be opted by n number of students.So, tbl_Course class has List of tbl_Student_Course . This is bit logical for many-to-many relationship. Anyway, we need not to worry much about writing all these code as our Entity Framework is going to generate these kind of classes automatically.

 Now let us implement BOL. Right click on BOL and select Add New Ite m -> Select ADO.NET Entity Model and name it as  LinkHubModel.edmx and click on Add.

Select Generate model from database and click on Next.

Click on New Connection. Set your connection and Select database and Click Next.

Select Entity Framework 6 and click Next.

 Now select all the tables and you can see that Model Namespace is LinkHubDbModel  -> Click Finish.

You may see this security warning twice. Say OK.

 Now, you can observe classes that it has generated for each table.

For tbl_Category, it has generated the properties CategoryId, CategoryName and CategoryDesc. As we know that one category contains list of Urls, I get List of tbl_Url. Hide Copy Code namespace BOL { using System; using System.Collections.Generic; public partial class tbl_Category { public tbl_Category() { this.tbl_Url = new HashSet(); } public int CategoryId { get; set; } public string CategoryName { get; set; } public string CategoryDesc { get; set; } public virtual ICollection tbl_Url { get; set; } } }

For tbl_Users, the properties UserId, UserEmail, Password and Role has been generated.

One user can upload n number of Urls. Again, I’ve a list of Urls. Hide Copy Code namespace BOL { using System; using System.Collections.Generic; public partial class tbl_User { public tbl_User() { this.tbl_Url = new HashSet(); } public public public public

int UserId { get; set; } string UserEmail { get; set; } string Password { get; set; } string Role { get; set; }

public virtual ICollection tbl_Url { get; set; } } }

Same logic it is following that we learned earlier and let us look into Url class. Class tbl_Url has properties UrlId, UrlTitle, Url, UrlDesc and so on. As we know that each Url belongs to a particular category and it is uploaded by a particular User. So, it is following the same rule. Hide Copy Code namespace BOL { using System; using System.Collections.Generic; public partial class tbl_Url { public int UrlId { get; set; } public string UrlTitle { get; set; } public string Url { get; set; } public string UrlDesc { get; set; } public Nullable CategoryId { get; set; } public Nullable UserId { get; set; } public string IsApproved { get; set; } public virtual tbl_Category tbl_Category { get; set; } public virtual tbl_User tbl_User { get; set; } } }

We’ll get these 3 classes. These are our Business objects. Now I’ll rebuild the BOL project. As we know, we are going to use these Business objects in UI (User Interface). I need connection string in UI which is available in BOL project -> App.config  file. Copy the connectionStrings  section and paste it in web.config  of UI (We will cover this in our next article) and Rebuild the solution. This is a very important step because my UI is going to interact with BOL and we’ve generated the BOL with the help of Entity Framework.

If we look into TODO list, we are done with Creating BOL and Adding connection string in UI.

Thanks for reading.

https://www.codeproject.com/articles/1006238/asp-net-mvc-web-app-on-tier-for-beginners-part-3

ASP.NET MVC Web App on 3-Tier for Beginners – Part 3

ASP.NET MVC Web App on 3-Tier for Beginners – Part 3

Introduction This article is the continuation of Part 1 & Part 2 . In the first article, we saw understanding of requirements and then breaking them into objects, then finding out the relationships among them and finally designing and implementing the database. And Good news is our first article won the best article of the Nov 2014 award. In second article we saw how to create a solution, then add multiple projects to it and then add desired references to the respective projects. So, finally we are done with our Business Object Layer. Now let’s have a quick overview of the things that we’ve developed till now i.e., we are done with our backend, Business Object Layer.

3: Implementing All the Layers (UI Prototyping)  Now in this article, it is the time for us to implement our UI (User Interface) with the help of ASP.NET MVC.

To implement this again we need to look back into the roles and responsibilities Roles 

User



o o o Admin o o o

Can Browse URLs Can Register Can Submit a URL Can CRUD (Create, Read, Update and Delete) Category Can view all the Users Can Approve or Reject URL

Keeping all this in mind, Say we’ve designed a prototype you can say UI prototype. Let’s have a look Homepage or you can say Dashboard some kind of calendar that I want to show. Normally, this homepage is accessible by all the users. Whether it is Admin/User/Anybody. This is a common page.

Category page

The page where I can create category. Normally, Only Admin should have access to this  page.

List Categories Page

This page is also accessed only by Admin. Admin can see what all the categories he has created.

Register page

Any user can register. Everyone will have access to this page.

Submit URL page

Once user is registered he can submit URL. Only registered users can access this page. You can say the only those users with role “U” can access.

Approve URLs page

Once the user submitted a URL this will get reflected to Admin. Admin can look for the URL that has been submitted then Admin can select some URLs and can Approve or Reject. Once it is approved. It’ll be available in BrowseURLs This page is accessed only by Admin or The users with role “A”

Browse URLs page

This is accessed by anyone. Anybody can come and browse for the URLs that are available

ListUsers page

This page is available only to Admin

Login page

Either an Admin or an existing user can login from here.

Let me now break this into Modules. Altogether I have nine pages. 1. 2. 3. 4. 5. 6. 7. 8. 9.

Home Category ListCategories Register SubmitURL ApproveURLs BrowseURLs ListUsers Login

Basically this is our process flow. I’ll go for breaking this into various modules UI Modules 

User o

Can Submit a URL

Before becoming a user he is a guest and after registration he can submit a URL 





Admin o Can create category o Can list categories o Can list users o Can Approve URLs Common (Without login) o Home o Browse URLs Security o Login o Register

So, basically I get four modules and all the pages get shifted to these modules. In our earlier ASP.NET web forms we used to create four different folders (User, Admin, Common and Security) and used to add related aspx pages to these folders. But, here we do not have the concept of folders. Instead we’ve the concept of Areas. I can add one Area for each module.  Now, what happens if we create Areas? The URL for SubmitURL page of User Module will look something like this BaseURL/User/ SubmitURL Example for Admin module In the same way we’ve Common and Security

Example for Common module Example for Security module In our MVC we talk in terms of Areas. I’m going to create 4 Areas. I’ll say 4 UI – Areas. Let us see how to create these Areas in MVC. To create an Area. Right click on LinkHubUI à Add à Area

Add Common Area

It has become damn easy to work with Areas in MVC5. Earlier we need to write configuration settings as shown. Hide Copy Code public override void RegisterArea(AreaRegistrationContext context) { context.MapRoute( "Common_default", "Common/{controller}/{action}/{id}", new { action = "Index", id = UrlParameter.Optional } ); }

Whereas now your MVC is doing all the URL routing settings for you. You can see that in Areas I’ve got Common. Common has got structure Controllers, Models and Views i.e., MVC. CommonAreaRegistration.cs is the URL routing file.Earlier we need to write URL routing code. But, in MVC5 it’ll be created automatically.

 Now, let me quickly add three more Areas for (User, Security and Admin) Rebuild project and then Rebuild Solution.

We’ve completed adding Areas in MVC

 Next I need to add all the Controllers for respective Areas. Let us see how to create controller. How do we know that how many Controllers we need to create? How to decide how many Actions that Controller should contain?

That is simple let’s have a look at page – SubmitURL How do I define Controller for this and Actions in that Controller.

Let us see that in our next Article.

Thanks for reading.

https://www.codeproject.com/Articles/1009212/ASP-NET-MVC-Web-App-on-Tier-for-BeginnersPart

ASP.NET MVC Web App on 3-Tier for Beginners – Part 4 In this article, let us try to understand and implement master layout and Bootstrap.

Introduction This article is the continuation of Part 1, Part 2 and Part 3. In the first article, we focused on understanding requirements and breaking them into objects, then finding out the relationships among them, and finally, designing and implementing the database. And (good news!) our first article won the best article of the Nov 2014 award . In the second article, we saw how to create a solution, add multiple projects to it, and add desired references to their respective projects. So, finally we are done with our Business Object Layer. In the third article, we saw how to implement our UI (User Interface). In this article, let us try to understand and implement master layout and bootstrap.

3: Implementing All the Layers (Master layout and Bootstrap) Our next work item or task is adding bootstrap feature.

Let us observe an option whenever I was trying to add View, i.e., It was asking to use a layout.

It means that it was creating a separate layout for each area.

Layout (in MVC) is nothing but a type of MasterPage (in ASPX webforms). It is creating separate Master Pages for each Area and I don’t want to have separate layout for each area. I want to have a common layout for all the Areas. Let us observe that first. If you look into Shared folder -> layout as shown:

This is the layout you have in Areas -> Admin -> Views -> Shared ->  _layout.cshtml . Hide Shrink

Copy Code

@ViewBag.Title - My ASP.NET Application

@Html.ActionLink("Application name", "Index", "Home", null, new { @class = "navbar-brand" }) @RenderBody() © @DateTime.Now.Year - My ASP.NET Application

It is set in ViewStart for each area.

In the same sense, in Common, if you observe, you’ll have the same exact layout and it is setting it in ViewStart.

In the same way, if you look into Security, you’ll have the same layout and setting it in ViewStart.

Also the same in User:

 Now I want to push layout to the Common view folder that I have outside the Area: Add a new folder in Views and name it "Shared".

I’ll drag one of the layouts and place it in Shared.

In ViewStart, I’ll just remove the " /Areas/User " i.e., it is going to use the share layout of your common Views folder.

Same way do for all the Areas (Admin, Common, and Security). So each view is now  pointing to this layout MasterPage. I can name my Application Name as "LinkHub". Hide Copy Code @Html.ActionLink("LinkHub", "Index", "Home", new { Area = "Common" }, new { @class = "navbar-brand" })

Whenever I click LinkHub, it should take me to Index Home as mentioned in the above statement. So I need to pass one more parameter for Area. Whenever I click on LinkHub, it will take me to Common Area and Home Controller and Action Index. Save all and execute and Browse for URL  /Common/Home. If I click on LinkHub, it will be redirecting to the same page.

As we know, the default controller is Home. Now, how do we set the default Area? I want the default to redirect me to controller Home of Common Area.

It is very simple to do that. I need to edit the route table and change the default Area.

Look for the area and change it to Common. Hide Copy Code public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new {controller = "Home", action = "Index", id = UrlParameter.Optional } ); (RouteTable.Routes[routes.Count - 1] as Route).DataTokens["area"] = "Common"; } }

Save and Execute. By default, it should redirect to Common -> Home Controller.

This is how you can set your default Area. Now let’s switch to layout. I want links to all the controller indexes or all the links. Notice that you have a div tag with unordered list and in this I’m adding list items. For example, Home, which is pointing to the Controller Home of Area Common. I’m adding all the links:

 Now, let me execute this. And I get my applicatio n name Home, Category, ListCategory.

Submit URL: We created this form in our earlier article.

I’ve linked all the pages, but how about UI? It’s not looking good. Here comes the power of your Bootstrap. I need to just right click on the LinkHubUI project in solution and say Manage NuGet Packages.

We need to look online so it requires an internet connection search for bootstrap. Then I’ll select Bootstrap for MVC 5.1 and Install. It will install Bootstrap. Read and accept the agreement and say close.

 Now if you execute, you should see the magic. It should turn into a beautiful UI.

For Submit URL, you should see an awesome form with good dropdown.

 Now, I’m going to show you one more power of Bootstrap -- it is responsive. For any kind of screen resolution, it is going to work or for any screen size. If I’m trying to access my page on my mobile, try checking adjusting the browser window size and see that it will adjust all the link items automatically. Finally, it has turned into a beautiful Menu.

View more...

Comments

Copyright © 2017 DATENPDF Inc.