/// <summary> /// Returns a table name for a type and accounts for table renaming /// via the DataContractAttribute, DataTableAttribute and/or the JsonObjectAttribute. /// </summary> /// <param name="type"> /// The type for which to return the table name. /// </param> /// <returns> /// The table name. /// </returns> public virtual string ResolveTableName(Type type) { // Lookup the Mobile Services name of the Type and use that string name = null; lock (tableNameCache) { if (!this.tableNameCache.TryGetValue(type, out name)) { // By default, use the type name itself name = type.Name; DataContractAttribute dataContractAttribute = type.GetTypeInfo().GetCustomAttributes(typeof(DataContractAttribute), true) .FirstOrDefault() as DataContractAttribute; if (dataContractAttribute != null) { if (!string.IsNullOrWhiteSpace(dataContractAttribute.Name)) { name = dataContractAttribute.Name; } } JsonContainerAttribute jsonContainerAttribute = type.GetTypeInfo().GetCustomAttributes(typeof(JsonContainerAttribute), true) .FirstOrDefault() as JsonContainerAttribute; if (jsonContainerAttribute != null) { if (!string.IsNullOrWhiteSpace(jsonContainerAttribute.Title)) { name = jsonContainerAttribute.Title; } } DataTableAttribute dataTableAttribute = type.GetTypeInfo().GetCustomAttributes(typeof(DataTableAttribute), true) .FirstOrDefault() as DataTableAttribute; if (dataTableAttribute != null) { if (!string.IsNullOrEmpty(dataTableAttribute.Name)) { name = dataTableAttribute.Name; } } this.tableNameCache[type] = name; // Build the JsonContract now to catch any contract errors early this.CreateContract(type); } } return(name); }
/// <summary> /// Returns a table name for a type and accounts for table renaming /// via the DataContractAttribute, DataTableAttribute and/or the JsonObjectAttribute. /// </summary> /// <param name="type"> /// The type for which to return the table name. /// </param> /// <returns> /// The table name. /// </returns> public virtual string ResolveTableName(Type type) { // Lookup the Mobile Services name of the Type and use that string name = null; if (!tableNameCache.TryGetValue(type, out name)) { // By default, use the type name itself name = type.Name; DataContractAttribute dataContractAttribute = type.GetCustomAttributes(typeof(DataContractAttribute), true) .FirstOrDefault() as DataContractAttribute; if (dataContractAttribute != null) { if (!string.IsNullOrWhiteSpace(dataContractAttribute.Name)) { name = dataContractAttribute.Name; } } JsonContainerAttribute jsonContainerAttribute = type.GetCustomAttributes(typeof(JsonContainerAttribute), true) .FirstOrDefault() as JsonContainerAttribute; if (jsonContainerAttribute != null) { if (!string.IsNullOrWhiteSpace(jsonContainerAttribute.Title)) { name = jsonContainerAttribute.Title; } } DataTableAttribute dataTableAttribute = type.GetCustomAttributes(typeof(DataTableAttribute), true) .FirstOrDefault() as DataTableAttribute; if (dataTableAttribute != null) { if (!string.IsNullOrWhiteSpace(dataTableAttribute.Name)) { name = dataTableAttribute.Name; } } tableNameCache[type] = name; } return(name); }
private SerializableType(Type type) { this.Type = type; this.Members = new Dictionary <string, SerializableMember>(); // The table name mapped by this type is the same as the type // by default unless a DataTable attribute is supplied or a DataContract // is being used in which the name is being set. DataTableAttribute dataTableAttribute = type.GetCustomAttribute <DataTableAttribute>(true); DataContractAttribute dataContractAttribute = type.GetCustomAttribute <DataContractAttribute>(true); if (dataTableAttribute != null && !string.IsNullOrWhiteSpace(dataTableAttribute.Name)) { this.TableName = dataTableAttribute.Name; } else if (dataContractAttribute != null && !string.IsNullOrWhiteSpace(dataContractAttribute.Name)) { this.TableName = dataContractAttribute.Name; } else { this.TableName = type.Name; } // Add all of the Mobile Services properties and fields to Members // (TODO: We're using Members.Add(n, m) instead of Members[n] = m // so that any duplicates will throw an exception. We can consider // whether we should throw a friendlier exception at some point in // the future, but this will prevent duplicate names) bool hasContract = dataContractAttribute != null; foreach (PropertyInfo property in GetSerializableMembers(hasContract, type.GetProperties)) { SerializableMember member = new SerializableMember(property); this.AddMemberWithDuplicateCheck(member); } foreach (FieldInfo field in GetSerializableMembers(hasContract, type.GetFields)) { SerializableMember member = new SerializableMember(field); this.AddMemberWithDuplicateCheck(member); } // Ensure we have a valid ID field (and check a couple of variants // to enable POCOs). SerializableMember id = null; if (!this.Members.TryGetValue(MobileServiceTableUrlBuilder.IdPropertyName, out id) && !this.Members.TryGetValue(IdPropertyName, out id) && !this.Members.TryGetValue(IdPropertyName.ToUpperInvariant(), out id) && !this.Members.TryGetValue(IdPropertyName.ToLowerInvariant(), out id)) { throw new InvalidOperationException( string.Format( CultureInfo.InvariantCulture, Resources.SerializableType_Ctor_MemberNotFound, MobileServiceTableUrlBuilder.IdPropertyName, type.FullName)); } // Coerce the name of the ID property to the required format if // we've got a POCO with a slightly different name. if (id.Name != MobileServiceTableUrlBuilder.IdPropertyName) { this.Members.Remove(id.Name); id.Name = MobileServiceTableUrlBuilder.IdPropertyName; this.AddMemberWithDuplicateCheck(id); } this.IdMember = id; }