PageRenderTime 51ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/v2.0/src/CoolCode.ServiceModel/Mvc/SharedController.cs

http://net.codeplex.com
C# | 430 lines | 260 code | 99 blank | 71 comment | 38 complexity | 61a4d78a4358edb716cb5497e9406658 MD5 | raw file
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel.DataAnnotations;
  4. using System.Data;
  5. using System.Data.Entity;
  6. using System.Data.Entity.Infrastructure;
  7. using System.Data.Metadata.Edm;
  8. using System.Data.SqlClient;
  9. using System.Dynamic;
  10. using System.IO;
  11. using System.Linq;
  12. using System.Reflection;
  13. using System.Web.Mvc;
  14. using System.Xml.Linq;
  15. using CoolCode.Linq;
  16. using CoolCode.Linq.Dynamic;
  17. using CoolCode.Web.Mvc;
  18. using CoolCode.ServiceModel.Services;
  19. namespace CoolCode.ServiceModel.Mvc {
  20. public class SharedController<T> : SharedController where T : DbContext {
  21. protected new readonly T db = (T)CurrentResolver.GetService<DbContext>();
  22. }
  23. public class SharedController : ControllerBase {
  24. #region Services
  25. protected readonly DbContext db = CurrentResolver.GetService<DbContext>();
  26. protected readonly IEntityWatcher EntityWatcher = CurrentResolver.GetService<IEntityWatcher>();
  27. protected override void Dispose(bool disposing) {
  28. db.Dispose();
  29. base.Dispose(disposing);
  30. }
  31. #endregion
  32. #region ??CRUD
  33. public virtual ActionResult ItemList(string entity) {
  34. Type entityType = GetEntityType(entity);
  35. IQueryable model = QueryItems(db.Set(entityType));
  36. return View(model);
  37. }
  38. protected IQueryable QueryItems(IQueryable model) {
  39. foreach (var key in this.ControllerContext.HttpContext.Request.Form.Keys.Cast<string>()) {
  40. if (key.Contains("@0")) {
  41. var value = this.ControllerContext.HttpContext.Request.Form[key];
  42. if (!string.IsNullOrEmpty(value)) {
  43. var predicate = string.Format("{0}", key);
  44. model = model.Where(predicate, value);
  45. }
  46. }
  47. }
  48. /*
  49. if (model.ElementType.IsSubclassOf(typeof(TrackEntityBase))) {
  50. model = model.Where("it.CreateUserId = @0", this.UserID)
  51. .OrderBy("it.CreateTime desc");
  52. }*/
  53. return model;
  54. }
  55. protected IQueryable<T> QueryItems<T>(IQueryBuilder<T> queryBuilder) where T : class {
  56. IQueryable<T> model = db.Set<T>();
  57. if (queryBuilder != null) {
  58. model = model.Where(queryBuilder.Expression);
  59. }
  60. model = (IQueryable<T>)QueryItems(model);
  61. return model;
  62. }
  63. public virtual ActionResult New(string entity) {
  64. Type entityType = GetEntityType(entity);
  65. object model = GetInstanceByType(entityType);
  66. SetValue(model, "CreateUserId", this.UserID);
  67. SetValue(model, "CreateTime", DateTime.Now);
  68. ViewBag.FormMode = FormMode.New;
  69. return View("Edit", model);
  70. }
  71. [HttpPost]
  72. public virtual ActionResult New(string entity, FormCollection form) {
  73. Type entityType = GetEntityType(entity);
  74. object model = GetInstanceByType(entityType);
  75. var keyProperty = GetKeyProperties(entityType).FirstOrDefault();
  76. switch (keyProperty.PropertyType.FullName) {
  77. case "System.Guid":
  78. keyProperty.SetValue(model, Guid.NewGuid(), null);
  79. break;
  80. case "System.String":
  81. keyProperty.SetValue(model, Guid.NewGuid().ToString(), null);
  82. break;
  83. }
  84. TryUpdateModel(entityType, model);
  85. db.Set(model.GetType()).Add(model);
  86. db.SaveChanges();
  87. ViewBag.FormMode = FormMode.New;
  88. return this.Success();
  89. }
  90. public virtual ActionResult Edit(string entity, string id) {
  91. Type entityType = GetEntityType(entity);
  92. object[] keyValues;
  93. if (!string.IsNullOrEmpty(id)) {
  94. keyValues = GetKeyValues(entityType, id);
  95. }
  96. else {
  97. object entityInstance = GetInstanceByType(entityType);
  98. TryUpdateModel(entityType, entityInstance);
  99. keyValues = GetKeyValues(entityType, entityInstance);
  100. }
  101. object model = db.Set(entityType).Find(keyValues);
  102. ViewBag.FormMode = FormMode.Edit;
  103. return View(model);
  104. }
  105. [HttpPost]
  106. public virtual ActionResult Edit(string entity, string id, FormCollection form) {
  107. Type entityType = GetEntityType(entity);
  108. object model = GetInstanceByType(entityType);
  109. TryUpdateModel(entityType, model);
  110. SetValue(model, "UpdateTime", DateTime.Now);
  111. SetValue(model, "UpdateUserId", this.UserID);
  112. db.Entry(model).State = EntityState.Modified;
  113. db.SaveChanges();
  114. ViewBag.FormMode = FormMode.Edit;
  115. return this.Success();
  116. }
  117. /*
  118. public void SaveOnSubmit(string id, object model)
  119. {
  120. if (!string.IsNullOrEmpty(id))
  121. {
  122. }
  123. else
  124. {
  125. db.Set(model.GetType()).Add(model);
  126. }
  127. }
  128. protected object RetriveEntity(Type entityType, string id)
  129. {
  130. object model = GetInstanceByType(entityType);
  131. TryUpdateModel(entityType, model);
  132. if (!string.IsNullOrEmpty(id))
  133. {
  134. SetValue(model, "UpdateTime", DateTime.Now);
  135. SetValue(model, "UpdateUserId", this.UserID);
  136. }
  137. else
  138. {
  139. var keyProperty = GetKeyProperties(entityType).FirstOrDefault();
  140. switch (keyProperty.PropertyType.FullName)
  141. {
  142. case "System.Guid":
  143. keyProperty.SetValue(model, Guid.NewGuid(), null);
  144. break;
  145. case "System.String":
  146. keyProperty.SetValue(model, Guid.NewGuid().ToString(), null);
  147. break;
  148. }
  149. }
  150. return model;
  151. }
  152. */
  153. private bool TryUpdateModel(Type entityType, object model) {
  154. var method = typeof(Controller).GetMethods(BindingFlags.Instance | BindingFlags.NonPublic)
  155. .First(c => c.Name == "TryUpdateModel" && c.GetParameters().Length == 1);
  156. method = method.MakeGenericMethod(entityType);
  157. object r = method.Invoke(this, new object[] { model });
  158. return (bool)r;
  159. }
  160. public virtual ActionResult Delete(string entity, string id) {
  161. Type entityType = GetEntityType(entity);
  162. object model = GetInstanceByType(entityType);
  163. TryUpdateModel(entityType, model);
  164. db.Entry(model).State = EntityState.Deleted;
  165. //var keyValues = GetKeyValues(entityType, id);
  166. //var model = db.Set(entityType).Find(keyValues);
  167. //db.Set(entityType).Remove(model);
  168. db.SaveChanges();
  169. return this.Success();
  170. }
  171. public virtual ActionResult BatchDelete(string entity, string id) {
  172. Type entityType = GetEntityType(entity);
  173. var keyProperty = GetKeyProperties(entityType).FirstOrDefault();
  174. //var entitySet = db.Set(entityType);
  175. //var predicate = string.Format("@0.Contains(\",\"+it.{0}+\",\")", keyProperty.Name);
  176. //var models = entitySet.Where(predicate, "," + id + ",");
  177. //???????SQL??
  178. //id = EscapeText(id);
  179. var parameters = id.Split(',')
  180. .Select((c, i) => new SqlParameter("@p" + i, Convert.ChangeType(c, keyProperty.PropertyType)))
  181. .ToArray();
  182. var whereClause = parameters.Length.Select(i => "@p" + i).ToArray().Join(",");
  183. /*
  184. var array = keyProperty.PropertyType.In(typeof(int), typeof(byte), typeof(short), typeof(long), typeof(decimal), typeof(double))
  185. ? id
  186. : string.Join(",", id.Split(',').Select((c,i) => "'" + c + "'").ToArray());*/
  187. var context = ((IObjectContextAdapter)db).ObjectContext;
  188. var contextType = context.MetadataWorkspace.GetEntityContainer(context.DefaultContainerName, DataSpace.CSpace);
  189. var entitySetType = contextType.BaseEntitySets.Where(c => c.ElementType.Name == entityType.Name).FirstOrDefault();
  190. string tableName = entitySetType.Name;
  191. var sql = string.Format("delete from {1} where {0} in ({2})", keyProperty.Name, tableName, whereClause);
  192. db.Database.ExecuteSqlCommand(sql, parameters);
  193. db.SaveChanges();
  194. return this.Success();
  195. }
  196. #region ????
  197. private object[] GetKeyValues(Type entityType, object instance) {
  198. var keyProperties = GetKeyProperties(entityType);
  199. return keyProperties.Select(p => p.GetValue(instance, null)).ToArray();
  200. }
  201. private object[] GetKeyValues(Type entityType, string id) {
  202. var keyProperty = GetKeyProperties(entityType).FirstOrDefault();
  203. object key = id;
  204. if (id.GetType() != keyProperty.PropertyType) {
  205. key = Convert.ChangeType(id, keyProperty.PropertyType);
  206. }
  207. return new object[] { key };
  208. }
  209. private IEnumerable<PropertyInfo> GetKeyProperties(Type entityType) {
  210. var context = ((IObjectContextAdapter)db).ObjectContext;
  211. var tableType = context.MetadataWorkspace.GetItem<EntityType>(entityType.FullName, true, DataSpace.OSpace);
  212. var keyPropertyType = tableType.MetadataProperties.Where(c => c.Name == "KeyMembers").FirstOrDefault();
  213. if (keyPropertyType != null) {
  214. var keyProppertyNames = (IEnumerable<EdmMember>)keyPropertyType.Value;
  215. return keyProppertyNames.Select(p => entityType.GetProperty(p.Name));
  216. }
  217. /*
  218. var ps = entityType.GetProperties().Where(p => {
  219. var keyAttrs = p.GetCustomAttributes(typeof(KeyAttribute), true);
  220. return keyAttrs.Count() > 0;
  221. });
  222. if (ps.Count() == 0) {
  223. ps = entityType.GetProperties().Where(p => p.Name.Equals("ID", StringComparison.InvariantCultureIgnoreCase));
  224. }
  225. return ps;
  226. */
  227. return Enumerable.Empty<PropertyInfo>();
  228. }
  229. private Type GetEntityType(string name) {
  230. name.ThrowIfNullOrEmpty("name");
  231. Type entityType = EntityWatcher.GetEntityType(name);
  232. if (entityType == null) {
  233. throw new InvalidOperationException("Invalid entity type: " + name);
  234. }
  235. return entityType;
  236. }
  237. private static object GetInstanceByType(Type type) {
  238. return Activator.CreateInstance(type);
  239. }
  240. private static bool SetValue(object obj, string propertyName, object value) {
  241. obj.ThrowIfNull("obj");
  242. Type entityType = obj.GetType();
  243. var prop = entityType.GetProperty(propertyName);
  244. if (prop != null) {
  245. prop.SetValue(obj, value, null);
  246. return true;
  247. }
  248. return false;
  249. }
  250. private static string EscapeText(string text) {
  251. return null == text ? text : text.Replace("'", "''");
  252. }
  253. #endregion
  254. #endregion
  255. #region Menu
  256. public ActionResult Menu() {
  257. var root = XElement.Load(this.Request.MapPath("~/content/sitemap/Web.sitemap"));
  258. root = root.Elements().First();
  259. var retrieveUrl = Self.Fix<XElement>((f, n) => {
  260. string url = RetrieveUrl(n);
  261. n.SetAttributeValue("url", url);
  262. bool isCurrent = (string.Compare(url, this.Request.Path, true) == 0);
  263. n.SetAttributeValue("class", isCurrent ? "current" : string.Empty);
  264. if (n.HasElements) {
  265. foreach (var x in n.Elements()) {
  266. f(x);
  267. }
  268. //if(isCurrent = (string.Compare(url, this.Request.Path, true) == 0);
  269. //n.SetAttributeValue("class", isCurrent ? "current" : string.Empty);
  270. }
  271. });
  272. retrieveUrl(root);
  273. return View(root);
  274. }
  275. private string RetrieveUrl(XElement x) {
  276. if (x.Attribute("url") != null) {
  277. return Convert.ToString(x.Attribute("url").Value);
  278. }
  279. if (x.Attribute("action") != null && x.Attribute("controller") != null) {
  280. return Url.Action(x.Attribute("action").Value, x.Attribute("controller").Value);
  281. }
  282. return null;
  283. }
  284. private static bool FilterByRole(XElement x, string[] userRoles) {
  285. string role = x.Attribute("role").Value;
  286. if (string.IsNullOrEmpty(role)) {
  287. return true;
  288. }
  289. string[] roles = role.Split('|');
  290. string allowRole = roles[0];
  291. string forbidRole = string.Empty;
  292. if (roles.Length > 1) {
  293. forbidRole = roles[1];
  294. }
  295. if (forbidRole.Split(',').Where(r => userRoles.Contains(r)).Count() > 0) {
  296. return false;
  297. }
  298. if (allowRole == "*" || allowRole.Split(',').Where(r => userRoles.Contains(r)).Count() > 0) {
  299. return true;
  300. }
  301. return false;
  302. }
  303. #endregion
  304. }
  305. public class DynamicXml : DynamicObject {
  306. private XElement _root = null;
  307. public DynamicXml(XElement el) {
  308. _root = el;
  309. }
  310. public DynamicXml(string path) {
  311. if (!File.Exists(path))
  312. throw new FileNotFoundException();
  313. _root = XElement.Load(path);
  314. }
  315. public override bool TryGetMember(GetMemberBinder binder, out object result) {
  316. result = null;
  317. if (binder.Name == "Elements") {
  318. result = _root.Elements(binder.Name).Select(x => new DynamicXml(x));
  319. return true;
  320. }
  321. result = _root.Attribute(binder.Name);
  322. return true;
  323. }
  324. }
  325. }