I am fairly new to the MVC Framework and have spent the last few days/nights working through the tutorials. I have a loosely coupled design with Services and Providers and am using the Entity Framework. I am using all the latest software, Visual Studio 2008, .Net 3.5 Framework, MVC, Entity Framework.
I'm trying to create a view Artist/Create where the user has to input all the Artist and all the Contact fields. Here's what I have:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using System.Text.RegularExpressions;
using Website.Models;
using Website.Models.Validation;
using Website.Models.Services;
namespace Website.Controllers
{
public class ArtistController : Controller
{
private IArtistService _service;
private ModelStateWrapper _msw;
public ArtistController()
{
_msw = new ModelStateWrapper(this.ModelState);
_service = new ArtistService(_msw);
}
public ArtistController(IArtistService service)
{
_service = service;
}
//
// GET: /Artist/
public ActionResult Index()
{
return View(_service.ListArtists());
}
public ActionResult Create()
{
ViewData["Countries"] = new SelectList(new CountryService(_msw).ListCountries().OrderBy(c => c.Name),"ID","Name");
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Exclude = "Id")] Artist artist)
{
ViewData["Countries"] = new SelectList(new CountryService(_msw).ListCountries().OrderBy(c => c.Name), "ID", "Name");
if (_service.CreateArtist(artist))
return RedirectToAction("Index");
return View("Create");
}
public ActionResult Edit(string name)
{
return View(_service.GetArtist(name));
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(Artist artistToEdit)
{
if (_service.EditArtist(artistToEdit))
return RedirectToAction("Index");
return View();
}
public ActionResult Delete(string name)
{
return View(_service.GetArtist(name));
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Delete(Artist artistToDelete)
{
if (_service.DeleteArtist(artistToDelete))
return RedirectToAction("Index");
return View();
}
}
}
And this is the View Artist/Create.aspx
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<asp:Content ID="Content3" ContentPlaceHolderID="HeadContent" runat="server">
<title>Artist</title>
<link href="../../Content/ui-lightness/jquery-ui-1.7.1.custom.css" rel="stylesheet" type="text/css" media="screen" />
<script src="../../Scripts/jquery-1.3.2.js" type="text/javascript"></script>
<script src="../../Scripts/ui.core.js" type="text/javascript"></script>
<script src="../../Scripts/ui.datepicker.js" type="text/javascript"></script>
<script src="../../Scripts/jquery-ui-1.7.1.custom.min.js" type="text/javascript"></script>
<script src="../../Scripts/ui.qtips.js" type="text/javascript"></script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Create Artist</h2>
<%= Html.ValidationSummary() %>
<% using (Html.BeginForm()) {%>
<fieldset class="fields">
<legend>Create New Artist</legend>
<p>
<label for="Name">Name:</label>
<%= Html.TextBox("Name", "", new { watermark = "Name", title = "Please enter your Artist name." })%>
<%= Html.ValidationMessage("Name", "*") %>
</p>
<fieldset class="fields">
<legend>Contact Information</legend>
<p>
<label for="FirstName">First Name:</label>
<%= Html.TextBox("FirstName", "", new { watermark = "FirstName", title = "Please enter your first name." }) %>
<%= Html.ValidationMessage("FirstName", "*") %>
</p>
<p>
<label for="LastName">Last Name:</label>
<%= Html.TextBox("LastName", "", new { watermark = "Lastname", title = "Please enter your last name." })%>
<%= Html.ValidationMessage("LastName", "*") %>
</p>
<p>
<label for="Phone">Phone:</label>
<%= Html.TextBox("Phone", "", new { watermark = "+12 123 123456", title = "Please enter your phone number." })%>
<%= Html.ValidationMessage("Phone", "*") %>
</p>
<p>
<label for="Email">Email:</label>
<%= Html.TextBox("Email", "", new { watermark = "[email protected]", title = "Please enter your email address." })%>
<%= Html.ValidationMessage("Email", "*") %>
</p>
<p>
<label for="BirthDate">Date of Birth:</label>
<%= Html.TextBox("Birthdate", "", new { Class = "date-pick", watermark = "mm/dd/yyyy", title = "Please select your date of birth." })%>
<%= Html.ValidationMessage("Birthdate", "*") %>
</p>
<p>
<label for="AddressLine1">Address:</label>
<%= Html.TextBox("AddressLine1", "", new { watermark = "", title = "Please enter your address." })%>
<%= Html.ValidationMessage("AddressLine1", "*") %>
</p>
<p>
<label for="AddressLine2"></label>
<%= Html.TextBox("AddressLine2", "", new { watermark = "First", title = "Optional additional addressline." })%>
<%= Html.ValidationMessage("AddressLine2", "*") %>
</p>
<p>
<label for="Country">Country:</label>
<%= Html.DropDownList("City", (IEnumerable<SelectListItem>)ViewData["Countries"],string.Empty, new { watermark = "First", title = "Please enter your email address." })%>
<%= Html.ValidationMessage("City", "*") %>
</p>
<p>
<label for="City">City:</label>
<%= Html.TextBox("City", "", new { watermark = "", title = "Please specify your City.", @class="tooltip" })%>
<%= Html.ValidationMessage("City", "*") %>
</p>
<p>
<label for="ZipCode">ZipCode:</label>
<%= Html.TextBox("ZipCode", "", new { watermark = "", title = "Please specify your Zipcode." })%>
<%= Html.ValidationMessage("ZipCode", "*") %>
</p>
<fieldset class="fields">
<legend>Sex/Gender</legend>
<label for="SexMale">Male</label>
<%= Html.RadioButton("Sex", "Male", new { @id = "Sex.Male" })%>
<label for="SexFemale">Female</label>
<%= Html.RadioButton("Sex", "Female", new { @id = "Sex.Female" })%>
<%= Html.ValidationMessage("Sex", "*") %>
</fieldset>
</fieldset>
<p class="submit">
<input type="submit" value="Create" />
</p>
</fieldset>
<% } %>
<!-- jquery plugins -->
<script type="text/javascript">
$(function() {
$('.date-pick').datepicker({
changeMonth: true,
changeYear: true,
yearRange: '1900:' + (new Date()).getFullYear()
});
$('.tooltip').qtip({ content: 'this is a nice tooltip', position: 'center' });
});
</script>
<!-- /jquery plugins -->
</asp:Content>
I can open this page fine and enter all the data. Here's is where I try to save the Artist using the ArtistService (this is where it goed wrong) :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text.RegularExpressions;
using Website.Models.Repositories;
using Website.Models.Validation;
namespace Website.Models.Services
{
public class ArtistService : IArtistService
{
private IValidationDictionary _validationDictionary;
private IArtistRepository _repository;
public ArtistService(IValidationDictionary validationDictionary)
: this(validationDictionary, new EntityArtistRepository()){}
public ArtistService(IValidationDictionary validationDictionary, IArtistRepository repository)
{
_validationDictionary = validationDictionary;
_repository = repository;
}
public bool ValidateArtist(Artist artist)
{
ContactService contactService = new ContactService(_validationDictionary);
if (contactService.ValidateContact(artist.Contact))
_validationDictionary.AddError("Contact", "Invalid Contact information.");
if (_validationDictionary.IsValid)
{
CountryService countryService = new CountryService(_validationDictionary);
if (artist.Contact.Country != null && countryService.ValidateCountry(artist.Contact.Country))
_validationDictionary.AddError("Country", "Country is required.");
}
if (artist.Name == null || artist.Name.Trim().Length == 0) {
_validationDictionary.AddError("Name", "Artist name is required.");
}
return _validationDictionary.IsValid;
}
#region IArtistService Members
public bool CreateArtist(Artist artist)
{
// Validation logic
if (!ValidateArtist(artist))
return false;
// Database logic
try
{
_repository.CreateArtist(artist);
}
catch
{
return false;
}
return true;
}
public bool EditArtist(Artist artist)
{
// Validation logic
if (!ValidateArtist(artist))
return false;
// Database logic
try
{
_repository.EditArtist(artist);
}
catch
{
return false;
}
return true;
}
public Artist GetArtist(int Id)
{
return _repository.GetArtist(Id);
}
public bool DeleteArtist(Artist artist)
{
try
{
_repository.DeleteArtist(artist);
}
catch
{
return false;
}
return true;
}
public IEnumerable<Artist> ListArtists()
{
return _repository.ListArtists();
}
public Artist GetArtist(string name)
{
return _repository.GetArtist(name);
}
#endregion
}
}
Can anyone tell me why everytime, in ValidateArtist, the Contact property of the Artist Entity appears to be empty? How do I tell MVC that it should link the contact input fields to the Contact property of the Artist Entity?
I hope it is ok that I've pasted all the code here, seems like a lot...
Thanks, Peter