/// <summary> /// Removes system properties from the passed in item /// </summary> /// <param name="item"> /// The item returned from the server /// </param> /// <param name="parameters"> /// A dictionary of user-defined parameters and values to include in /// the request URI query string. /// </param> /// <param name="version"> /// Set to the value of the version system property before it is removed. /// </param> /// <returns> /// An item that only contains normal fields and the requested system properties /// </returns> private JToken RemoveUnrequestedSystemProperties(JToken item, IDictionary <string, string> parameters, string version) { object id = null; if (item == null) { return(null); } MobileServiceSerializer.TryGetId(item as JObject, true, out id); if (id == null || MobileServiceSerializer.IsIntegerId(id)) { return(item); } var actualSystemProperties = GetRequestedSystemProperties(parameters); if (actualSystemProperties == MobileServiceSystemProperties.All) { return(item); } string ignoredVersion = null; var cleanedItem = MobileServiceSerializer.RemoveSystemProperties(item as JObject, out ignoredVersion, actualSystemProperties); if (version != null) { cleanedItem[MobileServiceSerializer.VersionSystemPropertyString] = GetValueFromEtag(version); } return(cleanedItem); }
/// <summary> /// Initializes a new instance of the MobileServiceTables class. /// </summary> /// <param name="tableName"> /// The name of the table. /// </param> /// <param name="client"> /// The <see cref="MobileServiceClient"/> associated with this table. /// </param> public MobileServiceTable(string tableName, MobileServiceClient client) : base(tableName, client) { this.queryProvider = new MobileServiceTableQueryProvider(); this.SystemProperties = client.Serializer.GetSystemProperties(typeof(T)); Type idType = client.Serializer.GetIdPropertyType <T>(throwIfNotFound: false); this.hasIntegerId = idType == null || MobileServiceSerializer.IsIntegerId(idType); }
/// <summary> /// if id is of type string then it strips the system properties and adds version header. /// </summary> /// <returns>The header collection with if-match header.</returns> private Dictionary <string, string> StripSystemPropertiesAndAddVersionHeader(ref JObject instance, ref IDictionary <string, string> parameters, object id) { string version = null; if (!MobileServiceSerializer.IsIntegerId(id)) { instance = MobileServiceSerializer.RemoveSystemProperties(instance, out version); } parameters = AddSystemProperties(this.SystemProperties, parameters); Dictionary <string, string> headers = AddIfMatchHeader(version); return(headers); }
/// <summary> /// Updates an <paramref name="instance"/> in the table. /// </summary> /// <param name="instance"> /// The instance to update in the table. /// </param> /// <param name="parameters"> /// A dictionary of user-defined parameters and values to include in /// the request URI query string. /// </param> /// <returns> /// A task that will complete when the update finishes. /// </returns> public async Task <JToken> UpdateAsync(JObject instance, IDictionary <string, string> parameters) { if (instance == null) { throw new ArgumentNullException("instance"); } MobileServiceInvalidOperationException error = null; object id = MobileServiceSerializer.GetId(instance); string version = null; if (!MobileServiceSerializer.IsIntegerId(id)) { instance = RemoveSystemProperties(instance, out version); } parameters = AddSystemProperties(this.SystemProperties, parameters); try { Dictionary <string, string> headers = null; string content = instance.ToString(Formatting.None); string uriString = GetUri(this.TableName, id, parameters); if (version != null) { headers = new Dictionary <string, string>(); headers.Add("If-Match", GetEtagFromValue(version)); } MobileServiceHttpResponse response = await this.MobileServiceClient.HttpClient.RequestAsync(patchHttpMethod, uriString, this.MobileServiceClient.CurrentUser, content, true, headers); return(GetJTokenFromResponse(response)); } catch (MobileServiceInvalidOperationException ex) { if (ex.Response != null && ex.Response.StatusCode != HttpStatusCode.PreconditionFailed) { throw; } error = ex; } JToken value = await this.ParseContent(error.Response); throw new MobileServicePreconditionFailedException(error, value); }
/// <summary> /// Creates a collection of <see cref="JsonProperty"/> instances for the members of a given /// type. /// </summary> /// <remarks> /// This method is overridden in order to handle the id property of the type. Because multiple /// property names ("id" with different casings) are all treated as the id property, we must /// ensure that there is one and only one id property for the type. Also, the id property /// should be ignored when it is the default or null value and it should always serialize to JSON /// with a lowercase 'id' name. /// /// This method also checks for and applies and system property attributes. /// </remarks> /// <param name="type"> /// The type for which to create the collection of <see cref="JsonProperty"/> instances. /// </param> /// <param name="memberSerialization"> /// Specifies the member serialization options for the type. /// </param> /// <returns> /// A collection of <see cref="JsonProperty"/> instances for the members of a given /// type. /// </returns> protected override IList <JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization) { IList <JsonProperty> properties = base.CreateProperties(type, memberSerialization); // If this type is for a known table, ensure that it has an id. TypeInfo typeInfo = type.GetTypeInfo(); if (this.tableNameCache.ContainsKey(type) || this.tableNameCache.Keys.Any(t => t.GetTypeInfo().IsAssignableFrom(typeInfo))) { // Filter out properties that are not read/write properties = properties.Where(p => p.Writable).ToList(); // Find the id property JsonProperty idProperty = DetermineIdProperty(type, properties); bool isIntegerIdType = MobileServiceSerializer.IsIntegerId(idProperty); // Create a reverse cache of property to memberInfo to be used locally for validating the type Dictionary <JsonProperty, MemberInfo> memberInfoCache = new Dictionary <JsonProperty, MemberInfo>(); foreach (KeyValuePair <MemberInfo, JsonProperty> pair in jsonPropertyCache) { if (pair.Key.DeclaringType.GetTypeInfo().IsAssignableFrom(typeInfo)) { memberInfoCache.Add(pair.Value, pair.Key); } } // Set any needed converters and look for system property attributes foreach (JsonProperty property in properties) { SetMemberConverters(property); ApplySystemPropertyAttributes(property, memberInfoCache[property], isIntegerIdType); } // Determine the system properties from the property names // and add the system properties to the cache if (!isIntegerIdType) { AddSystemPropertyCacheEntry(type, properties); } } return(properties); }