public virtual ActionResult EditObject(ObjectAndControlData controlData, FormCollection form) { Decrypt(form); controlData.Form = form; var nakedObject = controlData.GetNakedObject(Facade); SetExistingCollectionFormats(form); if (nakedObject.IsNotPersistent) { RefreshTransient(nakedObject, form); } switch (controlData.SubAction) { case (ObjectAndControlData.SubActionType.Action): SetNewCollectionFormats(controlData); return ActionOnNotPersistentObject(controlData); case (ObjectAndControlData.SubActionType.None): AddAttemptedValuesNew(nakedObject, controlData); return View("ObjectEdit", nakedObject.GetDomainObject()); case (ObjectAndControlData.SubActionType.Pager): SetNewCollectionFormats(controlData); return AppropriateView(controlData, nakedObject); case (ObjectAndControlData.SubActionType.Redisplay): return Redisplay(controlData); } Log.ErrorFormat("SubAction handling not implemented in EditObject for {0}", controlData.SubAction.ToString()); throw new NotImplementedException(controlData.SubAction.ToString()); }
public virtual ActionResult Details(ObjectAndControlData controlData) { Assert.AssertTrue(controlData.SubAction == ObjectAndControlData.SubActionType.Details || controlData.SubAction == ObjectAndControlData.SubActionType.None); INakedObject nakedObject = FilterCollection(controlData.GetNakedObject(), controlData); SetNewCollectionFormats(controlData); return AppropriateView(controlData, nakedObject); }
public virtual ActionResult ClearHistoryOthers(string id, ObjectAndControlData controlData) { var nakedObject = GetNakedObjectFromId(id); Session.RemoveOthersFromCache(Facade, nakedObject.GetDomainObject(), ObjectCache.ObjectFlag.BreadCrumb); SetNewCollectionFormats(controlData); SetControllerName(nakedObject.GetDomainObject()); return AppropriateView(controlData, nakedObject); }
public virtual ActionResult Details(ObjectAndControlData controlData) { Debug.Assert(controlData.SubAction == ObjectAndControlData.SubActionType.Details || controlData.SubAction == ObjectAndControlData.SubActionType.None); var nakedObject = controlData.GetNakedObject(Facade); nakedObject = FilterCollection(nakedObject, controlData); SetNewCollectionFormats(controlData); return AppropriateView(controlData, nakedObject); }
public virtual ActionResult Cancel(string nextId, ObjectAndControlData controlData) { var nextNakedObject = string.IsNullOrEmpty(nextId) ? null : GetNakedObjectFromId(nextId); if (nextNakedObject == null) { return RedirectToAction(IdConstants.IndexAction, IdConstants.HomeName); } SetNewCollectionFormats(controlData); SetControllerName(nextNakedObject.GetDomainObject()); return AppropriateView(controlData, nextNakedObject); }
internal ActionResult AppropriateView(ObjectAndControlData controlData, INakedObject nakedObject, INakedObjectAction action = null, string propertyName = null) { if (nakedObject == null) { // no object to go to // if action on object go to that object. // if action on collection go to collection // if action on service go to last object nakedObject = controlData.GetNakedObject(); if (nakedObject.Specification.IsService) { object lastObject = Session.LastObject(ObjectCache.ObjectFlag.BreadCrumb); if (lastObject == null) { TempData[IdHelper.NofMessages] = NakedObjectsContext.MessageBroker.Messages; TempData[IdHelper.NofWarnings] = NakedObjectsContext.MessageBroker.Warnings; return RedirectToAction(IdHelper.IndexAction, IdHelper.HomeName); } nakedObject = FrameworkHelper.GetNakedObject(lastObject); } } if (nakedObject.Specification.IsCollection && !nakedObject.Specification.IsParseable) { var collection = nakedObject.GetAsQueryable(); int collectionSize = collection.Count(); if (collectionSize == 1) { // remove any paging data - to catch case where custom page has embedded standalone collection as paging data will confuse rendering ViewData.Remove(IdHelper.PagingData); return View("ObjectView", collection.First()); } nakedObject = Page(nakedObject, collectionSize, controlData, nakedObject.IsNotQueryable()); action = action ?? ((CollectionMemento)nakedObject.Oid).Action; int page, pageSize; CurrentlyPaging(controlData, collectionSize, out page, out pageSize); var format = ViewData["NofCollectionFormat"] as string; return View("StandaloneTable", ActionResultModel.Create(action, nakedObject, page, pageSize, format)); } // remove any paging data - to catch case where custom page has embedded standalone collection as paging data will confuse rendering ViewData.Remove(IdHelper.PagingData); if (controlData.DataDict.Values.Contains("max")) { // maximizing an inline object - do not update history ViewData.Add("updateHistory", false); } return propertyName == null ? View(nakedObject.IsNotPersistent() ? "ObjectView" : "ViewNameSetAfterTransaction", nakedObject.Object) : View(nakedObject.IsNotPersistent() ? "PropertyView" : "ViewNameSetAfterTransaction", new PropertyViewModel(nakedObject.Object, propertyName)); }
public virtual ActionResult Details(ObjectAndControlData controlData, FormCollection form) { Decrypt(form); controlData.Form = form; Debug.Assert(controlData.SubAction == ObjectAndControlData.SubActionType.Redisplay || controlData.SubAction == ObjectAndControlData.SubActionType.Details || controlData.SubAction == ObjectAndControlData.SubActionType.Cancel || controlData.SubAction == ObjectAndControlData.SubActionType.None); var nakedObject = FilterCollection(controlData.GetNakedObject(Facade), controlData); SetExistingCollectionFormats(form); SetNewCollectionFormats(controlData); nakedObject.SetIsNotQueryableState(true); if (controlData.SubAction == ObjectAndControlData.SubActionType.Cancel && nakedObject.IsTransient && nakedObject.IsUserPersistable) { // remove from cache and return to last object Session.RemoveFromCache(Facade, nakedObject, ObjectCache.ObjectFlag.BreadCrumb); return AppropriateView(controlData, null); } string property = DisplaySingleProperty(controlData, controlData.DataDict); return AppropriateView(controlData, nakedObject, null, property); }
public virtual ActionResult Details(ObjectAndControlData controlData, FormCollection form) { Decrypt(form); controlData.Form = form; Assert.AssertTrue(controlData.SubAction == ObjectAndControlData.SubActionType.Redisplay || controlData.SubAction == ObjectAndControlData.SubActionType.Details || controlData.SubAction == ObjectAndControlData.SubActionType.Cancel || controlData.SubAction == ObjectAndControlData.SubActionType.None); INakedObject nakedObject = FilterCollection(controlData.GetNakedObject(), controlData); SetExistingCollectionFormats(nakedObject, form); SetNewCollectionFormats(controlData); nakedObject.SetNotQueryable(true); if (controlData.SubAction == ObjectAndControlData.SubActionType.Cancel && nakedObject.ResolveState.IsTransient() && nakedObject.Specification.Persistable == Persistable.USER_PERSISTABLE) { // remove from cache and return to last object Session.RemoveFromCache(nakedObject, ObjectCache.ObjectFlag.BreadCrumb); return AppropriateView(controlData, null); } string property = DisplaySingleProperty(controlData, controlData.DataDict); return AppropriateView(controlData, nakedObject, null, property); }
public override ActionResult Cancel(string nextId, ObjectAndControlData controlData) { return base.Cancel(nextId, controlData); }
internal INakedObject FilterCollection(INakedObject nakedObject, ObjectAndControlData controlData) { var form = controlData.Form; if (form != null && nakedObject != null && nakedObject.Specification.IsCollection && nakedObject.Oid is CollectionMemento) { nakedObject = Page(nakedObject, nakedObject.GetAsQueryable().Count(), controlData, false); var map = nakedObject.GetAsEnumerable().ToDictionary(FrameworkHelper.GetObjectId, y => y.Object); var selected = map.Where(kvp => form.Keys.Cast<string>().Contains(kvp.Key) && form[kvp.Key].Contains("true")).Select(kvp => kvp.Value).ToArray(); return CloneAndPopulateCollection(nakedObject, selected, false); } return nakedObject; }
public override ActionResult ClearHistoryItem(string id, string nextId, ObjectAndControlData controlData) { return base.ClearHistoryItem(id, nextId, controlData); }
internal static int GetPageSize(ObjectAndControlData controlData) { if (controlData.DataDict.ContainsKey(IdHelper.PageSizeKey)) { return int.Parse(controlData.DataDict[IdHelper.PageSizeKey]); } if (!string.IsNullOrEmpty(controlData.PageSize)) { return int.Parse(controlData.PageSize); } INakedObjectAction action = controlData.GetAction(); return action != null ? action.GetFacet<IPageSizeFacet>().Value : 0; }
internal INakedObject Page(INakedObject nakedObject, int collectionSize, ObjectAndControlData controlData, bool forceEnumerable) { int page, pageSize; var collectionfacet = nakedObject.GetCollectionFacetFromSpec(); if (CurrentlyPaging(controlData, collectionSize, out page, out pageSize) && !nakedObject.IsPaged()) { return DoPaging(nakedObject, collectionfacet, page, pageSize, forceEnumerable); } // one page of full collection return DoPaging(nakedObject, collectionfacet, 1, collectionSize, forceEnumerable); }
public override ActionResult EditObject(ObjectAndControlData controlData) { return base.EditObject(controlData); }
internal void CheckConcurrency(INakedObject nakedObject, INakedObjectAssociation parent, ObjectAndControlData controlData, Func<INakedObjectAssociation, INakedObject, INakedObjectAssociation, string> idFunc) { var concurrencyFields = nakedObject.Specification.Properties.Where(p => p.ContainsFacet<IConcurrencyCheckFacet>()).ToList(); if (!nakedObject.ResolveState.IsTransient() && concurrencyFields.Any() ) { IEnumerable<Tuple<INakedObjectAssociation, object>> fieldsAndMatchingValues = GetFieldsAndMatchingValues(nakedObject, parent, concurrencyFields, controlData, idFunc); foreach (var pair in fieldsAndMatchingValues) { if (pair.Item1.Specification.IsParseable) { INakedObject currentValue = pair.Item1.GetNakedObject(nakedObject); INakedObject concurrencyValue = pair.Item1.Specification.GetFacet<IParseableFacet>().ParseInvariant(pair.Item2 as string); if (concurrencyValue != null && currentValue != null) { if (concurrencyValue.TitleString() != currentValue.TitleString()) { throw new ConcurrencyException(nakedObject, null); } } else if (concurrencyValue == null && currentValue == null) { // OK } else { throw new ConcurrencyException(nakedObject, null); } } } } }
public override ActionResult ClearHistoryOthers(string id, ObjectAndControlData controlData) { return base.ClearHistoryOthers(id, controlData); }
public override ActionResult Details(ObjectAndControlData controlData) { return base.Details(controlData); }
private static object GetValueFromForm(ObjectAndControlData controlData, string name) { var form = controlData.Form; if (form.GetValue(name) != null) { return ((string[]) form.GetValue(name).RawValue).First(); } return controlData.Files.ContainsKey(name) ? controlData.Files[name] : null; }
internal void AddAttemptedValues(INakedObject nakedObject, ObjectAndControlData controlData, INakedObjectAssociation parent = null) { foreach (INakedObjectAssociation assoc in nakedObject.Specification.Properties.Where(p => (IsUsable(p, nakedObject) && IsVisible(p, nakedObject)) || IsConcurrency(p))) { string name = GetFieldInputId(parent, nakedObject, assoc); string value = GetValueFromForm(controlData, name) as string; if (value != null) { AddAttemptedValue(name, value); } } foreach (INakedObjectAssociation assoc in nakedObject.Specification.Properties.Where(IsConcurrency)) { string name = GetConcurrencyFieldInputId(parent, nakedObject, assoc); string value = GetValueFromForm(controlData, name) as string; if (value != null) { AddAttemptedValue(name, value); } } foreach (INakedObjectAssociation assoc in nakedObject.Specification.Properties.Where(p => p.IsInline)) { var inlineNakedObject = assoc.GetNakedObject(nakedObject); AddAttemptedValues(inlineNakedObject, controlData, assoc); } }
private static IEnumerable<Tuple<INakedObjectAssociation, object>> GetFieldsAndMatchingValues(INakedObject nakedObject, INakedObjectAssociation parent, IEnumerable<INakedObjectAssociation> associations, ObjectAndControlData controlData, Func<INakedObjectAssociation, INakedObject, INakedObjectAssociation, string> idFunc) { foreach (INakedObjectAssociation assoc in associations.Where(a => !a.IsInline)) { string name = idFunc(parent, nakedObject, assoc); object newValue = GetValueFromForm(controlData, name); yield return new Tuple<INakedObjectAssociation, object>(assoc, newValue); } }
internal bool ApplyChanges(INakedObject nakedObject, ObjectAndControlData controlData, INakedObjectAssociation parent = null) { List<INakedObjectAssociation> usableAndVisibleFields; List<Tuple<INakedObjectAssociation, object>> fieldsAndMatchingValues; GetUsableAndVisibleFields(nakedObject, controlData, parent, out usableAndVisibleFields, out fieldsAndMatchingValues); foreach (var pair in fieldsAndMatchingValues) { INakedObject value = GetNakedObjectValue(pair.Item1, nakedObject, pair.Item2); if (!pair.Item1.IsCollection) { SetAssociation(nakedObject, (IOneToOneAssociation)pair.Item1, value, pair.Item2); } } ValidateOrApplyInlineChanges(nakedObject, controlData, nakedObject.Specification.Properties, ApplyChanges); if (nakedObject.ResolveState.IsTransient()) { CanPersist(nakedObject, usableAndVisibleFields); if (ModelState.IsValid) { if (nakedObject.Specification.Persistable == Persistable.USER_PERSISTABLE) { NakedObjectsContext.ObjectPersistor.MakePersistent(nakedObject); } else { NakedObjectsContext.ObjectPersistor.ObjectChanged(nakedObject); } } } return ModelState.IsValid; }
private static void GetUsableAndVisibleFields(INakedObject nakedObject, ObjectAndControlData controlData, INakedObjectAssociation parent, out List<INakedObjectAssociation> usableAndVisibleFields, out List<Tuple<INakedObjectAssociation, object>> fieldsAndMatchingValues) { usableAndVisibleFields = nakedObject.Specification.Properties.Where(p => IsUsable(p, nakedObject) && IsVisible(p, nakedObject)).ToList(); fieldsAndMatchingValues = GetFieldsAndMatchingValues(nakedObject, parent, usableAndVisibleFields, controlData, GetFieldInputId).ToList(); }
private void ValidateOrApplyInlineChanges(INakedObject nakedObject, ObjectAndControlData controlData, IEnumerable<INakedObjectAssociation> assocs, Func<INakedObject, ObjectAndControlData, INakedObjectAssociation, bool> validateOrApply) { var form = controlData.Form; // inline or one or more keys in form starts with the property id which indicates we have nested values for the subobject foreach (INakedObjectAssociation assoc in assocs.Where(a => a.IsInline || form.AllKeys.Any(k => k.KeyPrefixIs(a.Id)))) { INakedObject inlineNakedObject = assoc.GetNakedObject(nakedObject); if (inlineNakedObject != null) { validateOrApply(inlineNakedObject, controlData, assoc); } } }
internal bool ValidateChanges(INakedObject nakedObject, ObjectAndControlData controlData, INakedObjectAssociation parent = null) { List<INakedObjectAssociation> usableAndVisibleFields; List<Tuple<INakedObjectAssociation, object>> fieldsAndMatchingValues; GetUsableAndVisibleFields(nakedObject, controlData, parent, out usableAndVisibleFields, out fieldsAndMatchingValues); CheckConcurrency(nakedObject, parent, controlData, GetConcurrencyFieldInputId); fieldsAndMatchingValues.ForEach(pair => AddAttemptedValue(GetFieldInputId(parent, nakedObject, pair.Item1), pair.Item2)); // check mandatory fields first to emulate WPF UI behaviour where no validation takes place until // all mandatory fields are set. foreach (var pair in fieldsAndMatchingValues) { var result = pair.Item2; var stringResult = result as string; if (pair.Item1.IsMandatory && (result == null || (result is string && string.IsNullOrEmpty(stringResult)))) { AddErrorAndAttemptedValue(nakedObject, stringResult, pair.Item1, MvcUi.Mandatory, parent); } } if (ModelState.IsValid) { ValidateOrApplyInlineChanges(nakedObject, controlData, usableAndVisibleFields, ValidateChanges); } if (ModelState.IsValid) { foreach (var pair in fieldsAndMatchingValues) { if (!pair.Item1.IsCollection) { ValidateAssociation(nakedObject, (IOneToOneAssociation) pair.Item1, pair.Item2, parent); } } } if (ModelState.IsValid) { INakedObjectValidation[] validators = nakedObject.Specification.ValidateMethods(); foreach (INakedObjectValidation validator in validators) { string[] parmNames = validator.ParameterNames; var matchingparms = parmNames.Select(pn => fieldsAndMatchingValues.Single(t => t.Item1.Id.ToLower() == pn)).ToList(); if (matchingparms.Count() == parmNames.Count()) { string result = validator.Execute(nakedObject, matchingparms.Select(t => GetNakedObjectValue(t.Item1, nakedObject, t.Item2)).ToArray()); if (!string.IsNullOrEmpty(result)) { ModelState.AddModelError(string.Empty, result); } } } } if (ModelState.IsValid) { if (nakedObject.Specification.ContainsFacet<IValidateProgrammaticUpdatesFacet>()) { string state = nakedObject.ValidToPersist(); if (state != null) { ModelState.AddModelError(string.Empty, state); } } } return ModelState.IsValid; }
public override ActionResult Action(ObjectAndControlData controlData) { return base.Action(controlData); }
internal void SetPagingValues(ObjectAndControlData controlData, INakedObject nakedObject) { if (nakedObject.Specification.IsCollection) { int sink1, sink2; CurrentlyPaging(controlData, nakedObject.GetAsEnumerable().Count(), out sink1, out sink2); } }
public override ActionResult Details(ObjectAndControlData controlData, FormCollection form) { return base.Details(controlData, form); }
internal bool CurrentlyPaging(ObjectAndControlData controlData, int collectionSize, out int page, out int pageSize) { pageSize = GetPageSize(controlData); page = 1; if (pageSize > 0) { page = GetPage(controlData); var pagingData = new Dictionary<string, int> { {IdHelper.PagingCurrentPage, page}, {IdHelper.PagingPageSize, pageSize}, {IdHelper.PagingTotal, collectionSize} }; ViewData[IdHelper.PagingData] = pagingData; return true; } return false; }
public override ActionResult EditObject(ObjectAndControlData controlData, FormCollection form) { return base.EditObject(controlData, form); }
private static int GetPage(ObjectAndControlData controlData) { if (controlData.DataDict.ContainsKey(IdHelper.PageKey)) { return int.Parse(controlData.DataDict[IdHelper.PageKey]); } return !string.IsNullOrEmpty(controlData.Page) ? int.Parse(controlData.Page) : 1; }