using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Reflection; using System.Web.Mvc; using Castle.ActiveRecord; using NinjectMvc.Helpers; namespace ActiveRecordScaffolding.Controllers { public class ARController : Controller where ARModel : new() { /// /// Initializes a new instance of the ARController class. /// public ARController() { ARControllerModule module = new ARControllerModule(); ViewData["controllernames"] = module.CreateARControllers(typeof(ARModel).Assembly).Select(x => { return x.Key; }); } private Type GetPrimaryKeyType() { Type result = null; foreach (PropertyInfo property in typeof(ARModel).GetProperties()) { object[] attribs = property.GetCustomAttributes(typeof(PrimaryKeyAttribute), false); if (attribs != null && attribs.Length == 1) { result = property.PropertyType; break; } } return result; } private IEnumerable GetProperties(Type type) { foreach (PropertyInfo pi in type.GetProperties()) { if (!pi.PropertyType.IsValueType && pi.PropertyType != typeof(string)) continue; yield return pi; } } private Dictionary CreateDataRow(ARModel model) { Dictionary row = new Dictionary(); foreach (PropertyInfo property in GetProperties(typeof(ARModel))) { row.Add(property.Name, Convert.ToString(property.GetValue(model, null))); } return row; } public ActionResult Index() { List> data = new List>(); var modelData = ActiveRecordMediator.FindAll(typeof(ARModel)); foreach (ARModel model in modelData) { Dictionary row = CreateDataRow(model); data.Add(row); } ViewData["data"] = data; ViewData["propertyNames"] = data[0].Keys.Select(x => x); return View("ScaffoldingList"); } public ActionResult Edit(string id) { object model_id = ChangeType(id, GetPrimaryKeyType()); ARModel model = (ARModel)ActiveRecordMediator.FindByPrimaryKey(typeof(ARModel), model_id, false); if (model == null) model = new ARModel(); ViewData["data"] = CreateDataRow(model); return View("ScaffoldingEdit"); } public void Save() { object model_id = ChangeType(Request.Form["id"], GetPrimaryKeyType()); ARModel model = (ARModel)ActiveRecordMediator.FindByPrimaryKey(typeof(ARModel), model_id, false); if (model == null) model = new ARModel(); foreach (PropertyInfo pi in GetProperties(typeof(ARModel))) { object value = ChangeType(Request.Form[pi.Name], pi.PropertyType); pi.SetValue(model, value, null); } ActiveRecordMediator.Save(model); Response.Redirect(String.Format("/{0}", typeof(ARModel).Name)); } #region ChangeType public object ChangeType(object value, Type conversionType) { // Note: This if block was taken from Convert.ChangeType as is, and is needed here since we're // checking properties on conversionType below. if (conversionType == null) { throw new ArgumentNullException("conversionType"); } // end if // If it's not a nullable type, just pass through the parameters to Convert.ChangeType if (conversionType.IsGenericType && conversionType.GetGenericTypeDefinition().Equals(typeof(Nullable<>))) { // It's a nullable type, so instead of calling Convert.ChangeType directly which would throw a // InvalidCastException (per http://weblogs.asp.net/pjohnson/archive/2006/02/07/437631.aspx), // determine what the underlying type is // If it's null, it won't convert to the underlying type, but that's fine since nulls don't really // have a type--so just return null // Note: We only do this check if we're converting to a nullable type, since doing it outside // would diverge from Convert.ChangeType's behavior, which throws an InvalidCastException if // value is null and conversionType is a value type. if (value == null) { return null; } // end if // It's a nullable type, and not null, so that means it can be converted to its underlying type, // so overwrite the passed-in conversion type with this underlying type NullableConverter nullableConverter = new NullableConverter(conversionType); conversionType = nullableConverter.UnderlyingType; } // end if // Now that we've guaranteed conversionType is something Convert.ChangeType can handle (i.e. not a // nullable type), pass the call on to Convert.ChangeType return Convert.ChangeType(value, conversionType); } #endregion } }