Showing posts with label Asp.Net Mvc. Show all posts
Showing posts with label Asp.Net Mvc. Show all posts

August 20, 2014

Models in an MVC application are just classes and therefore it is easy to add data annotations in the class itself. When MVC generates the views, the different field names and validation messages and datatypes are automatically generated. For example, the following can be a data model in an application.

The above LoginModel is copied from the auto generated template in an MVC application. Note that the data annotations like "Required", "DataType" are applied. However, if the model is generated from Entity Framework, these data annotations will not appear and how would we add the necessary data annotations.

So, to add annotations to an Entity model, we can take advantage of the System.ComponentModel.DataAnnotations.MetadataTypeAttribute class that allows to specify the metadata class to use with the data model class. So, we need to create a new class specify the metadata attribute which will link the data model class to another class which will contain all the data annotations for the necessary fields.

Here is an example of how this would work.

[MetadataType(typeof(AccountMetaData))]
public partial class Account
{
    //empty class just to apply class level attribute
    //imagine this as data annotations for Account
    //is in AccountMetaData class
}

public class AccountMetaData
{
    //same property name & type as in the Entity model
    [Display(Name = "Date of Birth of date")]
    public DateTime DateOfBirth;

    [Required]
    [MinLength(6, ErrorMessage = "Too short")]
    public string AnnountName;
}

March 3, 2014

I recently updated an MVC project from version 4 to version 5 and though almost the code complied, it failed with the runtime exception  

image

Basically, for some reason, Razor still points to the old version rather than the new version. To fix this error, open web.config file (the one for the application and not the Views one), and add the new version of Razor to the dependent assembly section as shown below.

  1. <runtime>
  2.   <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
  3.     <dependentAssembly>
  4.       <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
  5.       <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
  6.     </dependentAssembly>

I will build from the previous post on code first approach and in this one use MVC framework to add data in the database. To do so, I will start by adding a new Controller to the project. Here are the steps to add a new Controller.

  • In Solution Explorer, right click on Controllers and click Add > Controller
  • Set Controller name as EmployeeController
  • Set scaffolding option to – MVC controller with read/write actions and views, using Entity Framework
  • Set Model class as Employee
  • Set DataContext class as EmployeeModelContext

Here is a screen shot of the above

image

image

Similarly, add the Department Controller. Both Employee and Department Controllers and associated Views are now added to the application. The application can now be run and data can be added from the Views.

image

Code First Approach

Previously,  showed on how to use the Model First approach in Entity Framework, In this post, I will show how to use the Code First approach to create the data model. Code First model helps developers generate models when access to database is not possible – for example, the database team has not created the database yet. In this scenario, the developers could use the Code First approach and create a model using the entity classes. I will use the same data model in this post and generate entities.  

Code-First approach allows an entity container to be created around domain classes (POCO) available in code. This entity container behave just like Database- or Model-First approach and supports CRUD operations on a database.

To generate the entities and to test it, I will use an empty MVC application. After the empty application is created, I will add the two classes – Department and Employee – in the Models folder.

Here is the source code for the two classes.

  1. namespace MvcEntity.Models
  2. {
  3.     public class Department
  4.     {
  5.         public int DepartmentId { get; set;}
  6.         public string DepartmentName { get; set; }
  7.         public DateTime StartDate { get; set; }
  8.         public DateTime EndDate { get; set; }
  9.         public List<Employee> Employees { get; set; }
  10.     }
  11. }

 

  1. namespace MvcEntity.Models
  2. {
  3.     public class Employee
  4.     {
  5.         public int EmployeeId { get; set; }
  6.         public string FirstName { get; set; }
  7.         public string LastName { get; set; }
  8.         public string EmailAddress { get; set; }
  9.         public DateTime DateJoined { get; set; }
  10.         public double Salary { get; set; }
  11.         public bool IsActive { get; set; }
  12.         public int DepartmentId { get; set; }
  13.     }
  14. }

 

Note that I have a property DepartmentId in Department class and EmployeeId in Employee class which automatically will be mapped as primary keys.

Also note that the DepartmentId in Employee class allows the formation of foreign key relationship.

Next, I will create a EmployeeModelContext class that inherits System.Data.Entity.DbContext class and add Employee and Department classes as DBSet instances.

Data Context
  1. namespace MvcEntity.Models
  2. {
  3.     public class EmployeeModelContext : DbContext
  4.     {
  5.         public EmployeeModelContext()
  6.             : base("name = EmployeeModelContext")
  7.         {
  8.         }
  9.         public DbSet<Department> Departments { get; set; }
  10.         public DbSet<Employee> Employees { get; set; }
  11.     }
  12. }

Finally, the web.config file needs to be updated to contain a data connection. The connection name needs to be the same as the DataContext name.

<connectionStrings>
    <add name = "EmployeeModelContext" connectionString = "Data Source =
(localdb)\v11.0; Initial Catalog = EmployeeModelContext-201402262103602;
Integrated Security = True; MultipleActiveResultSets = True;
AttachDbFilename = |DataDirectory|EmployeeModelContext-201402262103602.mdf"
    providerName = "System.Data.SqlClient" />
  </connectionStrings>

At this stage,, the entities have been mapped to a Sql Server LocalDB database.  In the next posts, I will show how to use this database and how to connect to it via Entity Framework.

November 17, 2012

Examining the Views

As mentioned in the previous article on accessing Model from Controller, Views for Index, Create, Edit, Delete and Details are automatically created. In this post, I will examine of Index View. The generated code for Index View is below.

November 16, 2012

As you might already know from my previous post on accessing Model from Controller, Visual Studio can automatically generate Controller class simply by right-clicking and adding Controller on the Controller's directory in Solution Explorer. The generated Controller code contains the following snippet.

November 15, 2012

Access Model from Controller

In one of my previous posts, I showed on how to add a Model to a Mvc project. Once we have a Model, it's important to access this Model from a Controller. In this post, I will show how to add a Controller that can access data from a Model and automatically create Views for CRUD operations. Asp.Net Mvc allows using Code First development. Using Code First, the database is automatically created based on the Model class and connection string within the web.config file.
From previous post, I created a CartoonCharacter class as the Model and added the following connection string.

November 10, 2012

Adding a Model

Model classes holds the business logic and can perform data access and updates. Asp.Net Mvc can use Entity Framework for accessing data which supports Code First. In Code First, classes can be written which can then be used to create database on the fly.

To add a Model, right click on Models folder in Solution Explorer/Navigator, choose Add>Class. I have created the class CartoonCharacter for this.

1

Model - CartoonCharacter class
  1. public class CartoonCharacter
  2. {
  3.     public int Uid { get; set; }
  4.     public string FirstName { get; set; }
  5.     public string LastName { get; set; }
  6.     public int Year { get; set; }
  7.     public double Rating { get; set; }
  8. }

This ChartoonCharacter class will be used to represent ChartoonCharacters in a database. Each of the properties would be individual columns within a row. To use this class to perform data access/updates, a DataContext class needs to be added. This class is derived from Entity Framework and can handle CRUD operations. So, the final class looks like below.

Model
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using System.Data.Entity;
  6.  
  7. namespace MvcDemo.Models
  8. {
  9.     public class CartoonCharacter
  10.     {
  11.         public int Uid { get; set; }
  12.         public string FirstName { get; set; }
  13.         public string LastName { get; set; }
  14.         public int Year { get; set; }
  15.         public double Rating { get; set; }
  16.     }
  17.  
  18.     public class CartoonCharacterDBContext : DbContext
  19.     {
  20.         public DbSet<CartoonCharacter> CartoonCharacters { get; set; }
  21.     }
  22. }

The CartoonCharacterDBContext class can now handle data operations. But, how does it know which database to connect to? The connection string needs to be setup within the web.config file so the DataContext class can connect to the database.

Connection String
  1. <connectionStrings>
  2.   <add name="DefaultConnection" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=aspnet-MvcDemo-20121031221221;Integrated Security=SSPI" providerName="System.Data.SqlClient" />
  3.       <add name="CartoonCharacterDBContext" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=CartoonCharacter;Integrated Security=SSPI" providerName="System.Data.SqlClient" />
  4. </connectionStrings>

November 9, 2012

Pass Data from Controller to View

As mentioned in previous post on how Mvc work, Controller class handles browser request, gets data from database or other data source and selects the View to the user. Controller can therefore, retrieve data and pass data to the View. The View should not directly interact with the data source or handle any business logic but generate the HTML output based on the data provided from the Controller.

To show how we can pass data from Controller to View, I have added a new method Show() to the DemoController.cs file.

Show Method
  1. public ActionResult Show()
  2. {
  3.     List<string> list = new List<string>();
  4.     list.Add("Australia");
  5.     list.Add("Japan");
  6.     list.Add("USA");
  7.     list.Add("India");
  8.     ViewBag.List = list;
  9.  
  10.     return View();
  11. }

The method creates a new List collection that holds string. This collection is then added to ViewBag.

Now, to create the View, right click on method name and choose Add View. Keep default settings and the file will be created.

1

2

In the file created, I have added a foreach loop to display the strings.

foeeach loop
  1. <ul>
  2.     @foreach (string a in ViewBag.List) {
  3.         <li>@a</li>    
  4.     }
  5. </ul>

When the page is run, the list of string displayed in the browser in the same order.

So, this example was quite simple that only strings was passed from Controller to View. I will now add a new method that will create some objects of type CartoonCharacter and pass back to View. So, first, here is the code for CartoonCharacter class. It is a simple class in that it only has first name and last name.

CartoonCharacter class
  1. public class CartoonCharacter
  2. {
  3.     public string FirstName { get; set; }
  4.     public string LastName { get; set; }
  5. }

Then, I will add the new method like below.

ShowCharacter method
  1. public ActionResult ShowCharacter()
  2. {
  3.     List<CartoonCharacter> list = new List<CartoonCharacter>();
  4.     list.Add(new CartoonCharacter { FirstName = "Yogi", LastName = "Bear" });
  5.     list.Add(new CartoonCharacter { FirstName = "Bugs", LastName = "Bunny" });
  6.     list.Add(new CartoonCharacter { FirstName = "Daffy", LastName = "Duck" });
  7.     list.Add(new CartoonCharacter { FirstName = "Scooby", LastName = "Doo" });
  8.     ViewBag.List = list;
  9.  
  10.     return View();
  11. }

After the method added, right click on the method to add a View and keep default settings. Then, in the View, I have written another foreach loop that loops through the CartoonCharacter List and displays its first and last name.

foreach loop
  1. <ul>
  2. @foreach(MvcDemo.Controllers.CartoonCharacter cc in ViewBag.List){
  3.     <li>@cc.FirstName @cc.LastName</li>
  4. }
  5. </ul>

November 8, 2012

Default Layout in Asp.Net Mvc

In the previous post, I showed how to add a View to an Mvc project. The resultant page looked like below.

Mvc - Layout file
  1. <!DOCTYPE html>
  2. <html lang="en">
  3.     <head>
  4.         <meta charset="utf-8" />
  5.         <title>@ViewBag.Title - My ASP.NET MVC Application</title>
  6.         <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
  7.         <meta name="viewport" content="width=device-width" />
  8.         @Styles.Render("~/Content/css")
  9.         @Scripts.Render("~/bundles/modernizr")
  10.     </head>
  11.     <body>
  12.         <header>
  13.             <div class="content-wrapper">
  14.                 <div class="float-left">
  15.                     <p class="site-title">@Html.ActionLink("your logo here", "Index", "Home")</p>
  16.                 </div>
  17.                 <div class="float-right">
  18.                     <section id="login">
  19.                         @Html.Partial("_LoginPartial")
  20.                     </section>
  21.                     <nav>
  22.                         <ul id="menu">
  23.                             <li>@Html.ActionLink("Home", "Index", "Home")</li>
  24.                             <li>@Html.ActionLink("About", "About", "Home")</li>
  25.                             <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
  26.                         </ul>
  27.                     </nav>
  28.                 </div>
  29.             </div>
  30.         </header>
  31.         <div id="body">
  32.             @RenderSection("featured", required: false)
  33.             <section class="content-wrapper main-content clear-fix">
  34.                 @RenderBody()
  35.             </section>
  36.         </div>
  37.         <footer>
  38.             <div class="content-wrapper">
  39.                 <div class="float-left">
  40.                     <p>&copy; @DateTime.Now.Year - My ASP.NET MVC Application</p>
  41.                 </div>
  42.             </div>
  43.         </footer>
  44.  
  45.         @Scripts.Render("~/bundles/jquery")
  46.         @RenderSection("scripts", required: false)
  47.     </body>
  48. </html>

As can be seen, the content section is the section that was rendered by the Welcome View created. The question is how did the page got the header logo and links section. The page go this section from _Layout.cshtml file in Views/Shared folder. This Layout file is being rendered on all pages generated by this Mvc application. This is more like the master page in an aspx application where the aspx page gets content from master pages when set via the master property. Here is the source code for the default Layout file.

The title is set as

So, the page gets the title from ViewBag and appends some text " - My ASP.NET MVC"...

  1. <title>@ViewBag.Title - My ASP.NET MVC Application</title>

Couple of lines below, there are some Styles.Render and Scripts.Render tags.

  1. @Styles.Render("~/Content/css")
  2. @Scripts.Render("~/bundles/modernizr")

These tags loads the default styles and scripts as specified in App_Start/BundleConfig.cs file. This file looks bundling all necessary scripts and stylesheets into one. The BundleConfig file looks like below.

BundleConfig
  1. using System.Web;
  2. using System.Web.Optimization;
  3.  
  4. namespace MvcDemo
  5. {
  6.     public class BundleConfig
  7.     {
  8.         // For more information on Bundling, visit http://go.microsoft.com/fwlink/?LinkId=254725
  9.         public static void RegisterBundles(BundleCollection bundles)
  10.         {
  11.             bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
  12.                         "~/Scripts/jquery-{version}.js"));
  13.  
  14.             bundles.Add(new ScriptBundle("~/bundles/jqueryui").Include(
  15.                         "~/Scripts/jquery-ui-{version}.js"));
  16.  
  17.             bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
  18.                         "~/Scripts/jquery.unobtrusive*",
  19.                         "~/Scripts/jquery.validate*"));
  20.  
  21.             // Use the development version of Modernizr to develop with and learn from. Then, when you're
  22.             // ready for production, use the build tool at http://modernizr.com to pick only the tests you need.
  23.             bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
  24.                         "~/Scripts/modernizr-*"));
  25.  
  26.             bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css"));
  27.  
  28.             bundles.Add(new StyleBundle("~/Content/themes/base/css").Include(
  29.                         "~/Content/themes/base/jquery.ui.core.css",
  30.                         "~/Content/themes/base/jquery.ui.resizable.css",
  31.                         "~/Content/themes/base/jquery.ui.selectable.css",
  32.                         "~/Content/themes/base/jquery.ui.accordion.css",
  33.                         "~/Content/themes/base/jquery.ui.autocomplete.css",
  34.                         "~/Content/themes/base/jquery.ui.button.css",
  35.                         "~/Content/themes/base/jquery.ui.dialog.css",
  36.                         "~/Content/themes/base/jquery.ui.slider.css",
  37.                         "~/Content/themes/base/jquery.ui.tabs.css",
  38.                         "~/Content/themes/base/jquery.ui.datepicker.css",
  39.                         "~/Content/themes/base/jquery.ui.progressbar.css",
  40.                         "~/Content/themes/base/jquery.ui.theme.css"));
  41.         }
  42.     }
  43. }

The header menu is specified by @Html.ActionLink method. as follows.

Navigation menu
  1. <nav>
  2.     <ul id="menu">
  3.         <li>@Html.ActionLink("Home", "Index", "Home")</li>
  4.         <li>@Html.ActionLink("About", "About", "Home")</li>
  5.         <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
  6.     </ul>
  7. </nav>

The other important bit to note is the @RenderBody() method. This is the placeholder where the content from other Views will appear. For example, from previous post, the Welcome View would be rendered where @RenderBody() is specified.

Now, to modify the layout file, basic html knowledge sufficient to update the layout of the site. New styles or scripts can be written and called from the Layout file either directly or by using the BundleConfig file.

November 7, 2012

Add a View to Asp.Net Mvc

In the previous post, I showed how to add a Controller to an Mvc project. As you could see, html rendered in the page was done by Controller. In this post, I will show how to add a View to an Mvc project. The View is more like a template that can generate html output to the user. For this example, I have used Razor as the View engine.

The Demo Controller class created in the previous post looks like below.

Controller
  1. public class DemoController : Controller
  2. {
  3.     public string Index()
  4.     {
  5.         return "You are viewing Index method of DemoController";
  6.     }
  7.  
  8.     public string Home(string name, int age)
  9.     {
  10.         return "Hello " + name + ". You are " + age.ToString() + " years old";
  11.     }
  12. }

Now, I will add a new method – Welcome that will return the View.

View
  1. public ActionResult Welcome()
  2. {
  3.     return View();
  4. }

To create a View, right click on method name and Add View.

1

2

Note that, I have left the default settings and names. The default View has the following code.

Welcome View
  1. @{
  2.     ViewBag.Title = "Welcome";
  3. }
  4.  
  5. <h2>Welcome</h2>

I have added some message, so the code will look like below.

Welcome View
  1. @{
  2.     ViewBag.Title = "Welcome";
  3. }
  4.  
  5. <h2>Welcome</h2>
  6. <p>This is a demo welcome page</p>

When the page is run, it looks like below.

Welcome - My ASP.NET MVC Application 2012-11-06 17-24-18

November 1, 2012

In Asp.Net Mvc, Controllers are classes that query or update model data, load a specific View template and handle user inputs. Controllers can be added in an Mvc project by right clicking the Controllers directory and choosing Add > Controller.

1

I have named the Controller - DemoController - note the naming convention.

2

Visual Studio generates the following code by default.

Default Controller Code
  1. namespace MvcDemo.Controllers
  2. {
  3.     public class DemoController : Controller
  4.     {
  5.         //
  6.         // GET: /Demo/
  7.  
  8.         public ActionResult Index()
  9.         {
  10.             return View();
  11.         }
  12.  
  13.     }
  14. }

I will update the Index() method to return some string.

Index Method
  1. public string Index()
  2. {
  3.     return "You are viewing Index method od DemoController";
  4. }

Note that, I have changed the return type from ActionResult to string. Then, run the page in debug mode and the url http://localhost:50376/demo produce the result shown below. As you can see, its the same string that was part of the Index method.

3

The important thing to note is the url ends with /demo which is also the Controller’s name. In Mvc, the url controls the Controller, Method and parameters passed to the application. It has the format /Controller/Method/{Parameters} . Index is the default method name and therefore not needed to be specified.

I will now add another method - Home – that will display the name and age based on parameters.

Home Method
  1. public string Home(string name, int age)
  2. {
  3.     return "Hello " + name + ". You are " + age.ToString() + " years old";
  4. }

It’s a simple method that return a string based on the parameters. When the page is run, the following is displayed.

4

Note that, MVC automatically binds the query strings to the relevant parameters in the method.

What is MVC?

In my previous post, I should how to create a MVC project using Visual Studio but what is MVC? MVC, acronym for Model-View-Controller, is a software design pattern that separates the presentation (View), data model (Model) and user input based actions (Controller). In other words, it separates user interface logic from business logic.

View - The View manages the user interface, layout, etc. It can request information from Model about its state.

Controller - The Controller gets input from the View to update data and pass the message back to Model or to change the View.

Model - The Model controls the logic and behaviour of data. It pass data back to Controller when Controller asks for it and / or updates data when it receives message from Controller.

It's important to note that Model does not rely on Controller or View meaning that the Model can be created and tested separately from the user interface.

To relate this back to the MVC project created previously, there were separate folders for Model, Views and Controllers that manages how user with teh View, how View interacts with Model and responds to Controller and Controller talks to Model and View.

This should become more clear as I post more on this topic.

October 31, 2012

In this post, I will show how to create an asp.net MVC 4.0 project using Visual Studio 10 SP1. The built in templates in Visual Studio makes it easy to start creating the application. In the screenshot below, I have opened Visual Studio, and creating a new MVC 4.0 project using .NET 4.0 . I have called the solution MvcDemo.

1

After clicking OK, I will choose Internet Application as the template and Razor as the view engine and also create unit test project.

2

Visual Studio creates a working application once the OK button is hit. Folders and files have been created by default for Controllers, Models, Views, Filters, Scripts, Contents, etc. The screen shot below shows the full structure.

3

The application can now be started in Debug mode by hitting F5.

4

The application, by default, shows some informative messages. It’s important to note that the data for this page is obtained from Index.cshtml View which is under the Home sub-folder of View folder. The View contains mostly static content and dynamically obtains some information referred ViewBag.Message and ViewBag.Title property as shown below.

5

The value of ViewBag.Title property is set in the first couple of lines within the View. The ViewBag.Message property is set within the Index() method of HomeController class which is located within the Controller directory.

HomeController
  1. namespace MvcDemo.Controllers
  2. {
  3.     public class HomeController : Controller
  4.     {
  5.         public ActionResult Index()
  6.         {
  7.             ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application.";
  8.  
  9.             return View();
  10.         }
Reference: Shahed Kazi at AspNetify.com