MVC4 – Validation using Data Annotation Attribute

Auction.cs Model:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace MvcAuction.Models
{
    public class Auction
    {
        [Required]
        public long Id { get; set; }

        [Required]
        [DataType(DataType.Text)]
        public string Category { get; set; }

        [Required]
        [DataType(DataType.Text)]
        [StringLength(maximumLength: 200, MinimumLength = 5)]
        public string Title { get; set; }

        [DataType(DataType.MultilineText)]
        public string Description { get; set; }
       
        [DataType(DataType.ImageUrl)]
        [Display(Name = "Image URL")]
        public string ImageUrl { get; set; }

        [DataType(DataType.DateTime)]
        [Display(Name = "Start Time")]
        public DateTime StartTime { get; set; }

        [DataType(DataType.DateTime)]
        [Display(Name = "End Time")]
        public DateTime EndTime { get; set; }

        [DataType(DataType.Currency)]
        [Display(Name = "Starting Price")]
        public decimal StartPrice { get; set; }

        [DataType(DataType.Currency)]
        [Display(Name = "Current Bid Price")]
        public decimal? CurrentPrice { get; set; }
    }    
}

AuctionsController

        [HttpGet]
        public ActionResult Create()
        {
            var categoryList = new SelectList(new[] { "Automotive", "Electronics", "Games", "Home" });
            ViewBag.CategoryList = categoryList;
            return View();
        }

        [HttpPost]
        public ActionResult Create([Bind(Exclude="CurrentPrice")]Models.Auction auction)
        {
            if (ModelState.IsValid)
            {
                // Save to the database

                return RedirectToAction("Index");
            }
               
            return Create();
        }

MVC4 – Validation using HttpPost action

[HttpPost]
        public ActionResult Create([Bind(Exclude = "CurrentPrice")] MyAuction.Models.Auction auction)
        {
            if(string.IsNullOrWhiteSpace(auction.Title))
            {
                ModelState.AddModelError("Title", "Title is required");
            }
            else if(auction.Title.Length<5 || auction.Title.Length>200){
                ModelState.AddModelError("Title", "Title must be between 5 and 200");
            }

            if (ModelState.IsValid)
            {
                //save to the database
            }

            var categories = new SelectList(new[] { "Mobile phone", "Laptop", "Tablet" });
            ViewBag.categories = categories;

            return View();
        }

MVC4 – HttpGet & HttpPost actions

        [HttpGet]
        public ActionResult Create()
        {
            var categories = new SelectList(new[] { "Mobile phone", "Laptop", "Tablet" });
            ViewBag.categories = categories;
            return View();
        }

        [HttpPost]
        public ActionResult Create([Bind(Exclude = "CurrentPrice")] MyAuction.Models.Auction auction)
        {
            if(string.IsNullOrWhiteSpace(auction.Title))
            {
                ModelState.AddModelError("Title", "Title is required");
            }
            else if(auction.Title.Length<5 || auction.Title.Length>200){
                ModelState.AddModelError("Title", "Title must be between 5 and 200");
            }

            if (ModelState.IsValid)
            {
                //save to the database
            }

            var categories = new SelectList(new[] { "Mobile phone", "Laptop", "Tablet" });
            ViewBag.categories = categories;

            return View();
        }

MVC4 – Model binding sources

Source 1 – route data
For example user can enter following URL in his browser:
http://localhost:49882/auctions/auction/1
Here auctions – controller name, auction – action name, 1 – id

        public ActionResult Auction(long id)
        {
            var auctions = new[] {
                new Models.Auction(){
                    Title = "Macbook Air 2013",
                    Description = "Amazing ultrabook",
                    StartTime = DateTime.Now,
                    EndTime = DateTime.Now.AddDays(7),
                    StartPrice = 1.00m,
                    CurrentPrice = null ,
                },
                new Models.Auction(){
                    Title = "iPod Touch 5",
                    Description = "The best music player",
                    StartTime = DateTime.Now,
                    EndTime = DateTime.Now.AddDays(3),
                    StartPrice = 1.00m,
                    CurrentPrice = 3.00m ,
                },
                new Models.Auction(){
                    Title = "Drone",
                    Description = "You can use to take dronee",
                    StartTime = DateTime.Now,
                    EndTime = DateTime.Now.AddDays(30),
                    StartPrice = 10.00m,
                    CurrentPrice = 30.00m ,
                },
            };

            return View(auctions.GetValue(id));
           
        }

Created Auction Details view shows appropriate value by id.

Source 2 – QueryString params
Source 3 – Form post values
Source 4 – Cookies

MVC4 – Dropdown list example

Way 1 – this is not proper way to do this

        <div class="editor-field">
            @Html.DropDownListFor(model => model.Category, new SelectList(new [] {"Mobile phone", "Laptop", "Tablet"}))
            @Html.ValidationMessageFor(model => model.Category)
        </div>

Way 2 – We can implement this in more proper way:

        public ActionResult Create()
        {
            var categories = new SelectList(new[] { "Mobile phone", "Laptop", "Tablet" });
            ViewBag.categories = categories;
            return View();
        }

Create view:

        <div class="editor-field">
            @Html.DropDownListFor(model => model.Category, (SelectList)ViewBag.categories);
            @Html.ValidationMessageFor(model => model.Category)
        </div>

MVC4 – How to create form to input user data?

This is very easy. Just create one model, if you have not created yet. For example like this:

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

namespace MyAuction.Models
{
    public class Auction
    {

        public long Id { get; set; }

        public string Title { get; set; }
        public string Description { get; set; }
        public string ImageUrl { get; set; }

        public DateTime StartTime { get; set; }
        public DateTime EndTime { get; set; }

        public decimal StartPrice { get; set; }
        public decimal? CurrentPrice { get; set; }


    }
}

Create action for your controller:

        public ActionResult Create()
        {
            return View();
        }

Right click of your mouse inside of this action, from menu choose “Add View”
1.Check “Create strongly typed view”
2.Choose your model (if it is not visible yet, just run your application once, after that it will be visible)
3.Scaffold template: Create
4.Click “Add”

That’s it you created form to input data. It should look like this:

@model MyAuction.Models.Auction

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>Auction</legend>

        <div class="editor-label">
            @Html.LabelFor(model => model.Title)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Title)
            @Html.ValidationMessageFor(model => model.Title)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.Description)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Description)
            @Html.ValidationMessageFor(model => model.Description)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.ImageUrl)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.ImageUrl)
            @Html.ValidationMessageFor(model => model.ImageUrl)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.StartTime)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.StartTime)
            @Html.ValidationMessageFor(model => model.StartTime)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.EndTime)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.EndTime)
            @Html.ValidationMessageFor(model => model.EndTime)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.StartPrice)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.StartPrice)
            @Html.ValidationMessageFor(model => model.StartPrice)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.CurrentPrice)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.CurrentPrice)
            @Html.ValidationMessageFor(model => model.CurrentPrice)
        </div>

        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

MVC4 – Layout

Now I show how can we use those sections in our views:
_Layout.cshtml

        <div id="body">
            @RenderSection("featured", required: false)
            <section class="content-wrapper main-content clear-fix">
                @RenderBody()
            </section>
        </div>
        <footer>
            <div class="content-wrapper">
                <div class="float-left">
                    <p>&copy; @DateTime.Now.Year - My ASP.NET MVC Application</p>
                </div>
            </div>
        </footer>

        @Scripts.Render("~/bundles/jquery")
        @RenderSection("scripts", required: false)

Index.cshtml

    Layout = "~/Views/Shared/_Layout.cshtml";
    ViewBag.Title = "Index";
}

<h2>Index</h2>

@section featured{
    This is some feautured content
}

@section scripts{
    Some scripts
}

During web application development, we can use our custom layout which will include sections.
_LayoutWithSidebar.cshtml

@{
    ViewBag.Title = "_LayoutWithSidebar";
    Layout = "~/Views/Shared/_Layout.cshtml";
}

@section Featured {
    @RenderSection("Featured", required: false)
}
@section Scripts {
    @RenderSection("Scripts", required: false)
}

<div class="sidebar">
    @RenderSection("sidebar")
</div>

<div class="content">
    @RenderBody()
</div>

Index.cshtml

@{
    Layout = "~/Views/Shared/_LayoutWithSidebar.cshtml";
    ViewBag.Title = "Auctions";
}

@section Sidebar {
    <h3>This is my sidebar!</h3>
}

@section Featured {
    <section class="featured">
        <div class="content-wrapper">
            This is some featured content!
        </div>
    </section>
}

MVC 4 – Partial View

In order to create partial view, right click on Shared folder->Add->View
1.View name: It is common practice partial view’s name starts with “_” symbol for example “_AuctionPartial”
2.Create a strongly typed view: set checked
3.Model class: choose your model(Auction)
4.Create as a partial view: set checked

@model Auction.Models.Auction

<div class="one-auction">
    <h4 class="title">@Model.Title</h4>
    <p class="end-time">Auction ends at @Model.EndTime.ToString("g")</p>
    <p class="price">Price:@Model.CurrentPrice.GetValueOrDefault(Model.StartPrice).ToString("C")</p>
</div>

Now we created Auction partial view. So lets use it in our main view where we showing list of items.
First of all we send array of objects from our controller – AuctionsController:

        public ActionResult Index()
        {

            var auctions = new[] {
                new Models.Auction(){
                    Title = "Macbook Air 2013",
                    Description = "Amazing ultrabook",
                    StartTime = DateTime.Now,
                    EndTime = DateTime.Now.AddDays(7),
                    StartPrice = 1.00m,
                    CurrentPrice = null ,
                },
                new Models.Auction(){
                    Title = "iPod Touch 5",
                    Description = "The best music player",
                    StartTime = DateTime.Now,
                    EndTime = DateTime.Now.AddDays(3),
                    StartPrice = 1.00m,
                    CurrentPrice = 3.00m ,
                },
                new Models.Auction(){
                    Title = "Drone",
                    Description = "You can use to take dronee",
                    StartTime = DateTime.Now,
                    EndTime = DateTime.Now.AddDays(30),
                    StartPrice = 10.00m,
                    CurrentPrice = 30.00m ,
                },
            };

            return View(auctions);
        }

On Index view we will show it:

@model IEnumerable<Auction.Models.Auction>

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

<p>
    @Html.ActionLink("Create New", "Create")
</p>


@foreach (var item in Model) {
    @Html.Partial("_AuctionPartial", item)
}

MVC4 – Model example

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

namespace Auction.Models
{
    public class Auction
    {

        public long Id { get; set; }

        public string Title { get; set; }
        public string Description { get; set; }
        public string ImageUrl { get; set; }

        public DateTime StartTime { get; set; }
        public DateTime EndTime { get; set; }

        public decimal StartPrice { get; set; }
        public decimal? CurrentPrice { get; set; }


    }
}