public void Setup()
        {
            //Create Testing Data

            master = new ConcreteDataObject { Type = DEGREE, Name = "Master" + Guid.NewGuid().ToString().Substring(0, 5), CreatedDate = System.DateTime.Now };

            string serviceUri = @"/ConcreteDataService.svc/json/Save";

            string content = TestServicesHelper.GenerateJsonByType(master);
            try
            {
                string id = TestServicesHelper.GetResponse<HttpWebRequest>(serviceUri, userName, password, TestServicesHelper.PostDataByJsonWithContent, content, null);
                master.Id = new Guid(id.Replace("\"", ""));
            }
            catch (Exception) { throw; }
        }
        /// <summary>
        /// Find all concrete data objects includes soft deleted in the special type sorted by Name ascendingly.
        /// </summary>
        /// <param name="type">valid concrete data type</param>
        /// <returns></returns>
        public IEnumerable<ConcreteDataObject> FindAllByType(string type)
        {
            Kit.NotNull(type, "type");

            List<ConcreteDataObject> concreteDataObjects = new List<ConcreteDataObject>();
            using (MembershipDataContext ctx = DataContextFactory.Create<MembershipDataContext>())
            {
                IEnumerable<ConcreteData> entities = ctx.ConcreteDatas.Where(c => c.ApplicationId == authenticationContext.ApplicationId && c.Type == type);
                foreach (ConcreteData entity in entities)
                {
                    ConcreteDataObject concreteDataObject = new ConcreteDataObject
                    {
                        ConcreteDataId = entity.ConcreteDataId,
                        Type = entity.Type,
                        CreatedBy = entity.CreatedBy,
                        CreatedDate = LocalizationUtility.ConvertUtcTimeToClientTime(entity.CreatedDate),
                        DeleteStatus = entity.DeleteStatus,
                        Description = entity.Description,
                        ExtensionDataTypeId = entity.ExtensionDataTypeId,
                        LastUpdatedBy = entity.LastUpdatedBy,
                        LastUpdatedDate = LocalizationUtility.ConvertUtcTimeToClientTime(entity.LastUpdatedDate),
                        Name = entity.Name,
                        Value = entity.Value
                    };

                    concreteDataObject.ParseExtensionPropertiesFrom(entity);
                    concreteDataObjects.Add(concreteDataObject);
                }

                return concreteDataObjects;
            }
        }
        /// <summary>
        /// The method executed add/update depends on whether identity of object is empty or not.
        /// </summary>
        /// <param name="concreteDataObject">The name of concrete data should be unique in a concrete data type.</param>
        public void Save(ConcreteDataObject concreteDataObject)
        {
            Kit.NotNull(concreteDataObject, "concreteDataObject");
            Kit.NotNull(concreteDataObject.Name, "concreteDataObject.Name");
            Kit.NotNull(concreteDataObject.Type, "concreteDataObject.Type");

            using (MembershipDataContext ctx = DataContextFactory.Create<MembershipDataContext>())
            {
                ConcreteData concreteData = ctx.ConcreteDatas.FirstOrDefault(c => c.ApplicationId == authenticationContext.ApplicationId && c.Name == concreteDataObject.Name && c.Type == concreteDataObject.Type);

                // validate whether Name is unique in a concrete type.
                using (ValidationScope validationScope = new ValidationScope())
                {
                    if (concreteData != null && concreteData.ConcreteDataId != concreteDataObject.ConcreteDataId)
                    {
                        validationScope.Error(Resources.DuplicateConcreteDataName, concreteData.Name);
                        return;
                    }
                }

                if (concreteDataObject.ConcreteDataId == Guid.Empty)
                {
                    concreteData = ExtensionObjectFactory.Create<ConcreteData>(concreteDataObject);
                    concreteData.CreatedBy = authenticationContext.User.UserId;
                    concreteData.CreatedDate = DateTime.UtcNow;
                    concreteData.DeleteStatus = DeleteStatus.NotDeleted;

                    ctx.ConcreteDatas.InsertOnSubmit(concreteData);
                }
                else
                {
                    concreteData = ctx.ConcreteDatas.FirstOrDefault(c => c.ApplicationId == authenticationContext.ApplicationId && c.ConcreteDataId == concreteDataObject.ConcreteDataId);
                }

                concreteData.ApplicationId = authenticationContext.ApplicationId;
                concreteData.Type = concreteDataObject.Type;
                concreteData.DeleteStatus = concreteDataObject.DeleteStatus;
                concreteData.Description = concreteDataObject.Description;
                concreteData.Name = concreteDataObject.Name;
                concreteData.Value = concreteDataObject.Value;
                concreteData.LastUpdatedBy = authenticationContext.User.UserId;
                concreteData.LastUpdatedDate = DateTime.UtcNow;
                concreteData.ParseExtensionPropertiesFrom(concreteDataObject);

                ctx.SubmitChanges();

                // set server generated information back to the business object to return.
                concreteDataObject.ConcreteDataId = concreteData.ConcreteDataId;
                concreteDataObject.CreatedBy = concreteData.CreatedBy;
                concreteDataObject.CreatedDate = LocalizationUtility.ConvertUtcTimeToClientTime(concreteData.CreatedDate);
                concreteDataObject.LastUpdatedBy = concreteData.LastUpdatedBy;
                concreteDataObject.LastUpdatedDate = LocalizationUtility.ConvertUtcTimeToClientTime(concreteData.LastUpdatedDate);

                // remove the object from cache.
                base.RemoveCache(concreteDataObject.ConcreteDataId);
            }
        }
        /// <summary>
        /// Get concrete data by name.
        /// </summary>
        /// <param name="type"></param>
        /// <param name="name"></param>
        /// <returns></returns>
        public ConcreteDataObject GetByName(string type, string name)
        {
            Kit.NotNull(type, "type");
            Kit.NotNull(name, "name");

            using (MembershipDataContext ctx = DataContextFactory.Create<MembershipDataContext>())
            {
                ConcreteData entity = (from c in ctx.ConcreteDatas
                                       where c.ApplicationId == authenticationContext.ApplicationId
                                         && c.Type == type && c.Name == name
                                       select c).FirstOrDefault();

                if (entity == null) return null;

                ConcreteDataObject concreteDataObject = new ConcreteDataObject
                {
                    ConcreteDataId = entity.ConcreteDataId,
                    Type = entity.Type,
                    CreatedBy = entity.CreatedBy,
                    CreatedDate = LocalizationUtility.ConvertUtcTimeToClientTime(entity.CreatedDate),
                    DeleteStatus = entity.DeleteStatus,
                    Description = entity.Description,
                    ExtensionDataTypeId = entity.ExtensionDataTypeId,
                    LastUpdatedBy = entity.LastUpdatedBy,
                    LastUpdatedDate = LocalizationUtility.ConvertUtcTimeToClientTime(entity.LastUpdatedDate),
                    Name = entity.Name,
                    Value = entity.Value
                };

                concreteDataObject.ParseExtensionPropertiesFrom(entity);
                return concreteDataObject;
            }
        }
        /// <summary>
        /// Get concrete data by id.
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public ConcreteDataObject GetById(Guid id)
        {
            ConcreteDataObject concreteDataObject = base.GetCacheObject<ConcreteDataObject>(id);

            // cannot load concrete data from cache, then try to load it from database.
            if (concreteDataObject == null)
            {
                using (MembershipDataContext ctx = DataContextFactory.Create<MembershipDataContext>())
                {
                    ConcreteData entity = ctx.ConcreteDatas.FirstOrDefault(c => c.ApplicationId == authenticationContext.ApplicationId && c.ConcreteDataId == id);
                    if (entity == null) return null;

                    concreteDataObject = new ConcreteDataObject
                    {
                        ConcreteDataId = entity.ConcreteDataId,
                        Type = entity.Type,
                        CreatedBy = entity.CreatedBy,
                        CreatedDate = entity.CreatedDate,
                        DeleteStatus = entity.DeleteStatus,
                        Description = entity.Description,
                        ExtensionDataTypeId = entity.ExtensionDataTypeId,
                        LastUpdatedBy = entity.LastUpdatedBy,
                        LastUpdatedDate = entity.LastUpdatedDate,
                        Name = entity.Name,
                        Value = entity.Value
                    };

                    // parse dynamic properties.
                    concreteDataObject.ParseExtensionPropertiesFrom(entity);

                    // cache the business object with UTC datetime.
                    base.AddCache(concreteDataObject.ConcreteDataId, concreteDataObject);
                }
            }

            // get the copy for timezone convertion.
            concreteDataObject = concreteDataObject.Clone();

            // convert UTC datetime into client timezone before return.
            concreteDataObject.CreatedDate = LocalizationUtility.ConvertUtcTimeToClientTime(concreteDataObject.CreatedDate);
            concreteDataObject.LastUpdatedDate = LocalizationUtility.ConvertUtcTimeToClientTime(concreteDataObject.LastUpdatedDate);
            return concreteDataObject;
        }
        /// <summary>
        /// Find concrete data in all types by custom predicates.
        /// </summary>
        /// <param name="predicate"></param>
        /// <param name="orderby"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="recordCount"></param>
        /// <returns></returns>
        public IEnumerable<ConcreteDataObject> FindConcreteData(LinqPredicate predicate, string orderby, int pageIndex, int pageSize, out int recordCount)
        {
            try
            {
                using (MembershipDataContext ctx = DataContextFactory.Create<MembershipDataContext>())
                {
                    var q = from c in ctx.ConcreteDatas
                            where c.ApplicationId == authenticationContext.ApplicationId
                            select c;

                    if (predicate != null && !string.IsNullOrEmpty(predicate.Expression))
                        q = q.Where(predicate.Expression, predicate.Parameters);

                    if (!string.IsNullOrEmpty(orderby))
                        q = q.OrderBy(orderby);

                    recordCount = q.Count();

                    List<ConcreteDataObject> concreteDataObjects = new List<ConcreteDataObject>();
                    List<ConcreteData> concreteDataEntities = q.Skip(pageIndex * pageSize).Take(pageSize).ToList();
                    foreach (ConcreteData entity in concreteDataEntities)
                    {
                        ConcreteDataObject concreteDataObject = new ConcreteDataObject
                        {
                            ConcreteDataId = entity.ConcreteDataId,
                            Type = entity.Type,
                            CreatedBy = entity.CreatedBy,
                            CreatedDate = LocalizationUtility.ConvertUtcTimeToClientTime(entity.CreatedDate),
                            DeleteStatus = entity.DeleteStatus,
                            Description = entity.Description,
                            ExtensionDataTypeId = entity.ExtensionDataTypeId,
                            LastUpdatedBy = entity.LastUpdatedBy,
                            LastUpdatedDate = LocalizationUtility.ConvertUtcTimeToClientTime(entity.LastUpdatedDate),
                            Name = entity.Name,
                            Value = entity.Value
                        };

                        concreteDataObject.ParseExtensionPropertiesFrom(entity);
                        concreteDataObjects.Add(concreteDataObject);
                    }

                    return concreteDataObjects;
                }
            }
            catch (Exception exp)
            {
                Logger.Instance(this).Error(exp);
                throw;
            }
        }
 /// <summary>
 /// Add/update concrete data object depends on whether identity of object is empty or not.
 /// </summary>
 /// <param name="concreteDataObject">The name of concrete data should be unique in a concrete data type.</param>
 public string SaveXml(ConcreteDataObject concreteDataObject)
 {
     return SaveJson(concreteDataObject);
 }
 /// <summary>
 /// Add/update concrete data object depends on whether identity of object is empty or not.
 /// </summary>
 /// <param name="concreteDataObject">The name of concrete data should be unique in a concrete data type.</param>
 public string SaveJson(ConcreteDataObject concreteDataObject)
 {
     if (concreteDataObject == null)
         throw new BadRequestException(string.Format(CultureInfo.InvariantCulture, Resources.ConcreteDataObjectCannotBeNull));
     try
     {
         concreteDataApi.Save(concreteDataObject);
         return concreteDataObject.ConcreteDataId.ToString();
     }
     catch (ArgumentException ex)
     {
         throw new BadRequestException(string.Format(CultureInfo.InvariantCulture, ex.Message));
     }
     catch (BadRequestException bad)
     {
         throw new BadRequestException(string.Format(CultureInfo.InvariantCulture, bad.Message));
     }
     catch (FormatException formatEx)
     {
         throw new BadRequestException(string.Format(CultureInfo.InvariantCulture, formatEx.Message));
     }
     catch (Exception exp)
     {
         Logger.Instance(this).Error(exp);
         throw new InternalServerErrorException();
     }
 }
        /// <summary>
        /// Update an existed concrete data from detail panel.
        /// The method needs to load an existed entity by specified id and set control values to overwrite its original properties then persist it.
        /// </summary>
        /// <param name="entityId"></param>
        public override void Update(string entityId)
        {
            Guid concreteDataId = new Guid(entityId);
            this.ValidateInput(concreteDataId);
            ConcreteDataObject concreteDataObject = concreteDataApi.GetById(concreteDataId);
            if (concreteDataObject == null)
                throw new ValidationException(Resources.InvalidConcreteDataID);

            concreteDataObject = new ConcreteDataObject { ConcreteDataId = concreteDataId };
            concreteDataObject.ExtensionDataTypeId = this.ResolveExtensionDataTypeId();
            concreteDataObject.Type = authenticationContext.TempVariables["ConcreteDataType"] as string;

            if (this.TextBoxName != null)
                concreteDataObject.Name = this.TextBoxName.Text;

            if (this.TextBoxValue != null)
                concreteDataObject.Value = this.TextBoxValue.Text;

            if (this.RadioButtonListStatus != null)
                concreteDataObject.DeleteStatus = (DeleteStatus)Enum.Parse(typeof(DeleteStatus), this.RadioButtonListStatus.SelectedValue);

            if (this.TextBoxDescription != null)
                concreteDataObject.Description = this.TextBoxDescription.Text;

            if (this.ExtensionDataForm != null)
                this.ExtensionDataForm.SetObjectPropertiesFromControlValues(concreteDataObject);

            concreteDataApi.Save(concreteDataObject);
        }
        /// <summary>
        /// Create a new concrete data from detail panel and return its id.
        /// The method needs to create a new entity and set control values to its properties then persist it.
        /// </summary>
        /// <returns>returns the id of new created concrete data.</returns>
        public override string Create()
        {
            this.ValidateInput(Guid.Empty);

            ConcreteDataObject concreteDataObject = new ConcreteDataObject();
            concreteDataObject.ExtensionDataTypeId = this.ResolveExtensionDataTypeId();
            concreteDataObject.Type = authenticationContext.TempVariables["ConcreteDataType"] as string;

            if (this.TextBoxName != null)
                concreteDataObject.Name = this.TextBoxName.Text;

            if (this.TextBoxValue != null)
                concreteDataObject.Value = this.TextBoxValue.Text;

            if (this.TextBoxDescription != null)
                concreteDataObject.Description = this.TextBoxDescription.Text;

            if (this.RadioButtonListStatus != null)
                concreteDataObject.DeleteStatus = (DeleteStatus)Enum.Parse(typeof(DeleteStatus), this.RadioButtonListStatus.SelectedValue);

            if (this.ExtensionDataForm != null)
                this.ExtensionDataForm.SetObjectPropertiesFromControlValues(concreteDataObject);

            concreteDataApi.Save(concreteDataObject);
            return concreteDataObject.ConcreteDataId.ToString();
        }
        public void TestJsonSave()
        {
            this.CleanUp();
            master = new ConcreteDataObject { Type = DEGREE, Name = "Master" + Guid.NewGuid().ToString().Substring(0, 5), CreatedDate = System.DateTime.Now };

            string serviceUri = @"/ConcreteDataService.svc/json/Save";
            string content = TestServicesHelper.GenerateJsonByType(master);
            string id = TestServicesHelper.GetResponse<HttpWebRequest>(serviceUri, userName, password, TestServicesHelper.PostDataByJsonWithContent, content, null).Replace("\"", "");

            master.Id = new Guid(id);
        }
        public void SaveConcreteDataStories()
        {
            _story = new Story("Save the ConcreteDataObject ");

            _story.AsA("User")
              .IWant("to be able to save the ConcreteDataObject ")
              .SoThat("I can get  the ConcreteDataObject ");

            _story.WithScenario("Judge the application ")
                .Given("an unexisting application Name ", () =>
                {
                    _ConcreteDataObject = new ConcreteDataObject()
                                              {

                                                  Type = "Color",
                                                  Description = "Present",
                                                  Name = "Color",
                                                  Value = "Red;Yellow;Purple;"
                                              };

                    _ConcreteDataObject3 = new ConcreteDataObject()
                    {

                        Type = "Color",
                        Description = "Present",
                        Name = "Color1",
                        Value = "Red;Yellow;Purple;"
                    };
                })
                .When("I save this Application", () =>
                {
                    _ConcreteDataApi.Save(_ConcreteDataObject);

                    createdConcreteDataIds.Add(_ConcreteDataObject.Id);

                    _ConcreteDataApi.Save(_ConcreteDataObject3);

                    createdConcreteDataIds.Add(_ConcreteDataObject3.Id);

                })
                .Then(" I can get the object and judge if it exists ", () =>
                {
                    _ConcreteDataObject1 = _ConcreteDataApi.GetById(_ConcreteDataObject.Id);

                    _ConcreteDataObject2 = _ConcreteDataApi.GetByName("Color","Color");

                    _ConcreteDataObject1.Id.ShouldEqual(_ConcreteDataObject.Id);

                    _ConcreteDataObject2.Id.ShouldEqual(_ConcreteDataObject.Id);

                });

            this.CleanUp();
        }