Search

Categories

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Send mail to the author(s) E-mail

# Saturday, 19 March 2011
( MVC | Razor )

ValidationSummary(false)

image

View (no javascript)

@model datePickerTemp2.Models.PersonEditModel

@Model.MessageToDisplay

@using (Html.BeginForm()) {
@Html.ValidationSummary(false)
<fieldset>
<legend>Person</legend>

<div class="editor-label">
@Html.LabelFor(m => m.Person.FirstName)
</div>
<div class="editor-field">
@Html.EditorFor(m => m.Person.FirstName)
@Html.ValidationMessageFor(m => m.Person.FirstName, "You must enter a First Name")
</div>

Model:

public class Person
{
[Required]
public string FirstName { get; set; }
[DataType(DataType.Date)]
public DateTime DateOfBirth { get; set; }
}

View (javascript)

@model datePickerTemp2.Models.PersonEditModel

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@Model.MessageToDisplay

@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Person</legend>

<div class="editor-label">
@Html.LabelFor(m => m.Person.FirstName)
</div>
<div class="editor-field">
@Html.EditorFor(m => m.Person.FirstName)
@Html.ValidationMessageFor(m => m.Person.FirstName, "You must enter a First Name")
</div>

<div class="editor-label">
@Html.LabelFor(m => m.Person.DateOfBirth)
</div>
<div class="editor-field">
@Html.EditorFor(m => m.Person.DateOfBirth)
@Html.ValidationMessageFor(m => m.Person.DateOfBirth)
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
 
ValidationSummary(true)

image

There will be no postback if a firstname is blank.  DateOfBirth uses postback, however you have to have FirstName passing before it will actually postback.

| | # 
( MVC | Razor )

From http://blogs.msdn.com/b/stuartleeks/archive/2011/01/25/asp-net-mvc-3-integrating-with-the-jquery-ui-date-picker-and-adding-a-jquery-validate-date-range-validator.aspx

When implementing remember to add custom attribute to the correct property in the model:

DateType(DateType.Date)

and add a reference to DataAnnotations - System.ComponentModel.DataAnnotations

View

<div class="editor-label">
@Html.LabelFor(m => m.Person.DateOfBirth)
</div>
<div class="editor-field">
@Html.EditorFor(m => m.Person.DateOfBirth)
@Html.ValidationMessageFor(m => m.Person.DateOfBirth)
</div>

Use templated helpers to automatically wire up the date picker whenever it renders an editor for a date (ie a property annotated with DataType.Date).

If you add this annotation MVC3 will look for a partial view

Partial View - \EditorTemplates\Date.cshtml

@model DateTime
@Html.TextBox("", Model.ToString("dd/MM/yyyy"), new { @class = "date" }) **TODO Wire up
 
So when we render now:
 
image
The error you are seeing is because javascript validation is turned on, and its is getting confused with UK/US datetimes.

_Layout.cshtml

<script src="@Url.Content("~/Scripts/jquery-ui.js")" type="text/javascript"></script>
<link href="@Url.Content("~/Content/themes/base/jquery-ui.css")" rel="stylesheet" type="text/css" />
 
<script src="@Url.Content("~/Scripts/EditorHookup.js")" type="text/javascript"></script>

Scripts/EditorHookup.js

/// <reference path="jquery-1.4.4.js" />
/// <reference path="jquery-ui.js" />

$(document).ready(function () {
$('.date').datepicker({dateFormat: "dd/mm/yy"});
});

image

DateRange

image

public class Person
{
[Required]
public string FirstName { get; set; }
[DataType(DataType.Date)]
[DateRange("2010/12/01", "2010/12/16")]
public DateTime DateOfBirth { get; set; }
}

DateRange is simply:

public class DateRangeAttribute : ValidationAttribute
{
private const string DateFormat = "yyyy/MM/dd";
private const string DefaultErrorMessage = "'{0}' must be a date between {1:d} and {2:d}.";

public DateTime MinDate { get; set; }
public DateTime MaxDate { get; set; }

public DateRangeAttribute(string minDate, string maxDate)
: base(DefaultErrorMessage)
{
MinDate = ParseDate(minDate);
MaxDate = ParseDate(maxDate);
}

public override bool IsValid(object value)
{
if (value == null || !(value is DateTime))
{
return true;
}
DateTime dateValue = (DateTime)value;
return MinDate <= dateValue && dateValue <= MaxDate;
}
public override string FormatErrorMessage(string name)
{
return String.Format(CultureInfo.CurrentCulture, ErrorMessageString,
name, MinDate, MaxDate);
}

private static DateTime ParseDate(string dateValue)
{
return DateTime.ParseExact(dateValue, DateFormat, CultureInfo.InvariantCulture);
}
}

| | # 
# Thursday, 10 March 2011
( MVC | Razor )
ViewBag

Convenient late-bound way to pass bits of information to a view.

// GET: /HelloWorld/Welcome
public ActionResult Welcome(string name, int numTimes = 1)
{
ViewBag.Message = "Hello " + name;
ViewBag.NumTimes = numTimes;
return View();
}
 
String Formatting in Razor
<td>
@String.Format("{0:d}", item.ReleaseDate)
</td>
<td>
@item.Genre
</td>
<td>
@String.Format("{0:c}", item.Price)
</td>

Date {0:g} to {0:d} (that is, from general date to short date).

Price property from {0:F} to {0:c} (from float to currency).

Keyboard Shortcuts

Don’t seem to work.. however Right Click keyboard next to space, then go to Controller is useful.

Ctrl M Ctrl C – Add Controller

Ctrl M Ctl V – Add View

 

HTML Helper Methods

Html.LabelFor – displays the name of the field

Html.EditorFor – displays an input element where the user can enter a value.

Html.ValidationMessageFor

<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.ReleaseDate)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.ReleaseDate)
@Html.ValidationMessageFor(model => model.ReleaseDate)
</div>

Posting

In the controller:

[HttpPost]
public ActionResult Create(string title, DateTime releaseDate, string genre, decimal price)
{

or

[HttpPost]
public ActionResult Create(Movie newMovie)
{
if (ModelState.IsValid)
{
db.Movies.Add(newMovie);
db.SaveChanges();
return RedirectToAction("Index");
}
else
{
return View(newMovie);
}
}

MovieInitializer

If the model changes in the code, this provides a way to recreate the db put in sample data.

public class MovieInitializer : DropCreateDatabaseIfModelChanges<MovieDBContext>
{
protected override void Seed(MovieDBContext context)
{
var movies = new List<Movie> {

new Movie { Title = "When Harry Met Sally",
ReleaseDate=DateTime.Parse("1989-1-11"),
Genre="Romantic Comedy",
Rating="R",
Price=7.00M},

new Movie { Title = "Ghostbusters 2",
ReleaseDate=DateTime.Parse("1986-2-23"),
Genre="Comedy",
Rating="R",
Price=9.00M},
};

movies.ForEach(d => context.Movies.Add(d));
}
}

then wire up:

protected void Application_Start()
{
DbDatabase.SetInitializer<MovieDBContext>(new MovieInitializer());

AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}

Setting Precision in DB
public class MovieDBContext : DbContext
{
public DbSet<Movie> Movies { get; set; }

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Movie>().Property(p => p.Price).HasPrecision(18, 2);
}
}
image

Validation

Add to the Model and then it is enforced everywhere in the app.

System.ComponentModel.Validation – can apply to any class or property

[Required(ErrorMessage = "Genre must be specified")]
public string Genre { get; set; }

[Required(ErrorMessage = "Price Required")]
[Range(1, 100, ErrorMessage = "Price must be between $1 and $100")]
public decimal Price { get; set; }

[StringLength(5)]
public string Rating { get; set; }

EF will enforce too as well as the front end – both Javascript,(jquery.validate?) and serverside.

image

Update
[HttpPost]
public ActionResult Edit(Movie model)
{
try
{
var movie = db.Movies.Find(model.ID);

UpdateModel(movie);
db.SaveChanges();
return RedirectToAction("Details", new { id = model.ID });
}
catch (Exception)
{
ModelState.AddModelError("", "Edit Failure, see inner exception");
}

return View(model);
}

UpdateModel(movie) copies the edited data in model into the movie in the db.

Cloudifying

image

The database had been created in SQLServerExpress.  I then added this user as an owner / admin for the whole system (dev only!)

| | #