ASP.NET MVC validation problem
- by ile
ArticleRepostitory.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using CMS.Model;
using System.Web.Mvc;
namespace CMS.Models
{
public class ArticleDisplay
{
public ArticleDisplay() { }
public int CategoryID { set; get; }
public string CategoryTitle { set; get; }
public int ArticleID { set; get; }
public string ArticleTitle { set; get; }
public DateTime ArticleDate;
public string ArticleContent { set; get; }
}
public class ArticleRepository
{
private DB db = new DB();
//
// Query Methods
public IQueryable<ArticleDisplay> FindAllArticles()
{
var result = from category in db.ArticleCategories
join article in db.Articles on category.CategoryID equals article.CategoryID
select new ArticleDisplay
{
CategoryID = category.CategoryID,
CategoryTitle = category.Title,
ArticleID = article.ArticleID,
ArticleTitle = article.Title,
ArticleDate = article.Date,
ArticleContent = article.Content
};
return result;
}
public IQueryable<ArticleDisplay> FindTodayArticles()
{
var result = from category in db.ArticleCategories
join article in db.Articles on category.CategoryID equals article.CategoryID
where article.Date == DateTime.Today
select new ArticleDisplay
{
CategoryID = category.CategoryID,
CategoryTitle = category.Title,
ArticleID = article.ArticleID,
ArticleTitle = article.Title,
ArticleDate = article.Date,
ArticleContent = article.Content
};
return result;
}
public Article GetArticle(int id)
{
return db.Articles.SingleOrDefault(d => d.ArticleID == id);
}
public IQueryable<ArticleDisplay> DetailsArticle(int id)
{
var result = from category in db.ArticleCategories
join article in db.Articles on category.CategoryID equals article.CategoryID
where id == article.ArticleID
select new ArticleDisplay
{
CategoryID = category.CategoryID,
CategoryTitle = category.Title,
ArticleID = article.ArticleID,
ArticleTitle = article.Title,
ArticleDate = article.Date,
ArticleContent = article.Content
};
return result;
}
//
// Insert/Delete Methods
public void Add(Article article)
{
db.Articles.InsertOnSubmit(article);
}
public void Delete(Article article)
{
db.Articles.DeleteOnSubmit(article);
}
//
// Persistence
public void Save()
{
db.SubmitChanges();
}
}
}
ArticleController.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using CMS.Models;
using CMS.Model;
namespace CMS.Controllers
{
public class ArticleController : Controller
{
ArticleRepository articleRepository = new ArticleRepository();
ArticleCategoryRepository articleCategoryRepository = new ArticleCategoryRepository();
//
// GET: /Article/
public ActionResult Index()
{
var allArticles = articleRepository.FindAllArticles().ToList();
return View(allArticles);
}
//
// GET: /Article/Details/5
public ActionResult Details(int id)
{
var article = articleRepository.DetailsArticle(id).Single();
if (article == null)
return View("NotFound");
return View(article);
}
//
// GET: /Article/Create
public ActionResult Create()
{
ViewData["categories"] = new SelectList
(
articleCategoryRepository.FindAllCategories().ToList(), "CategoryId", "Title"
);
Article article = new Article()
{
Date = DateTime.Now,
CategoryID = 1
};
return View(article);
}
//
// POST: /Article/Create
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Article article)
{
if (ModelState.IsValid)
{
try
{
// TODO: Add insert logic here
articleRepository.Add(article);
articleRepository.Save();
return RedirectToAction("Index");
}
catch
{
return View(article);
}
}
else
{
return View(article);
}
}
//
// GET: /Article/Edit/5
public ActionResult Edit(int id)
{
ViewData["categories"] = new SelectList
(
articleCategoryRepository.FindAllCategories().ToList(), "CategoryId", "Title"
);
var article = articleRepository.GetArticle(id);
return View(article);
}
//
// POST: /Article/Edit/5
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(int id, FormCollection collection)
{
Article article = articleRepository.GetArticle(id);
try
{
// TODO: Add update logic here
UpdateModel(article, collection.ToValueProvider());
articleRepository.Save();
return RedirectToAction("Details", new { id = article.ArticleID });
}
catch
{
return View(article);
}
}
//
// HTTP GET: /Article/Delete/1
public ActionResult Delete(int id)
{
Article article = articleRepository.GetArticle(id);
if (article == null)
return View("NotFound");
else
return View(article);
}
//
// HTTP POST: /Article/Delete/1
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Delete(int id, string confirmButton)
{
Article article = articleRepository.GetArticle(id);
if (article == null)
return View("NotFound");
articleRepository.Delete(article);
articleRepository.Save();
return View("Deleted");
}
}
}
View/Article/Create.aspx:
<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<CMS.Model.Article>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Create
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>Create</h2>
<%= Html.ValidationSummary("Create was unsuccessful. Please correct the errors and try again.") %>
<% using (Html.BeginForm()) {%>
<fieldset>
<legend>Fields</legend>
<p>
<label for="Title">Title:</label>
<%= Html.TextBox("Title") %>
<%= Html.ValidationMessage("Title", "*") %>
</p>
<p>
<label for="Content">Content:</label>
<%= Html.TextArea("Content", new { id = "Content" })%>
<%= Html.ValidationMessage("Content", "*")%>
</p>
<p>
<label for="Date">Date:</label>
<%= Html.TextBox("Date") %>
<%= Html.ValidationMessage("Date", "*") %>
</p>
<p>
<label for="CategoryID">Category:</label>
<%= Html.DropDownList("CategoryId", (IEnumerable<SelectListItem>)ViewData["categories"])%>
</p>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<% } %>
<div>
<%=Html.ActionLink("Back to List", "Index") %>
</div>
</asp:Content>
If I remove DropDownList from .aspx file then validation (on date only because no other validation exists) works, but of course I can't create new article because one value is missing.
If I leave dropdownlist and try to insert wrong date I get following error:
System.InvalidOperationException: The
ViewData item with the key
'CategoryId' is of type 'System.Int32'
but needs to be of type
'IEnumerable'.
If I enter correct date than the article is properly inserted. There's one other thing that's confusing me... For example, if I try manually add the categoyID:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Article article)
{
if (ModelState.IsValid)
{
try
{
// TODO: Add insert logic here
// Manually add category value
article.CategoryID = 1;
articleRepository.Add(article);
articleRepository.Save();
return RedirectToAction("Index");
}
catch
{
return View(article);
}
}
else
{
return View(article);
}
}
..I also get the above error.
There's one other thing I noticed. If I add partial class Article, when returning to articleRepository.cs I get error that 'Article' is an ambiguous reference between 'CMS.Models.Article' and 'CMS.Model.Article'
Any thoughts on this one?