Skip to content

Commit e3e959d

Browse files
authored
Fixed public properties to have same JSON attributes (#1112)
* Fixed public properties to all have the same JSON attributes for the system types. PermissionProperties is now modified to be nullable to match the rest of the resource types. * Updated changelog * reverted type change to avoid breaking change * Updated unit tests * Updated contract change * Set formatting in test * Set formatting on another serializer
1 parent 36307e8 commit e3e959d

12 files changed

Lines changed: 108 additions & 40 deletions

Microsoft.Azure.Cosmos/src/Resource/Settings/AccountProperties.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ internal AccountProperties()
7575
/// <remarks>
7676
/// ETags are used for concurrency checking when updating resources.
7777
/// </remarks>
78-
[JsonProperty(PropertyName = Constants.Properties.ETag)]
78+
[JsonProperty(PropertyName = Constants.Properties.ETag, NullValueHandling = NullValueHandling.Ignore)]
7979
public string ETag { get; internal set; }
8080

8181
/// <summary>
@@ -89,7 +89,7 @@ internal AccountProperties()
8989
/// resource whether that is a database, a collection or a document.
9090
/// These resource ids are used when building up SelfLinks, a static addressable Uri for each resource within a database account.
9191
/// </remarks>
92-
[JsonProperty(PropertyName = Constants.Properties.RId)]
92+
[JsonProperty(PropertyName = Constants.Properties.RId, NullValueHandling = NullValueHandling.Ignore)]
9393
internal string ResourceId { get; set; }
9494

9595
[JsonProperty(PropertyName = Constants.Properties.WritableLocations)]

Microsoft.Azure.Cosmos/src/Resource/Settings/DatabaseProperties.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,15 +112,15 @@ public string Id
112112
/// <remarks>
113113
/// ETags are used for concurrency checking when updating resources.
114114
/// </remarks>
115-
[JsonProperty(PropertyName = Constants.Properties.ETag)]
115+
[JsonProperty(PropertyName = Constants.Properties.ETag, NullValueHandling = NullValueHandling.Ignore)]
116116
public string ETag { get; private set; }
117117

118118
/// <summary>
119119
/// Gets the last modified time stamp associated with <see cref="DatabaseProperties" /> from the Azure Cosmos DB service.
120120
/// </summary>
121121
/// <value>The last modified time stamp associated with the resource.</value>
122122
[JsonConverter(typeof(UnixDateTimeConverter))]
123-
[JsonProperty(PropertyName = Constants.Properties.LastModified)]
123+
[JsonProperty(PropertyName = Constants.Properties.LastModified, NullValueHandling = NullValueHandling.Ignore)]
124124
public DateTime? LastModified { get; private set; }
125125

126126
/// <summary>
@@ -145,7 +145,7 @@ public string Id
145145
/// resource whether that is a database, a collection or a document.
146146
/// These resource ids are used when building up SelfLinks, a static addressable Uri for each resource within a database account.
147147
/// </remarks>
148-
[JsonProperty(PropertyName = Constants.Properties.RId)]
148+
[JsonProperty(PropertyName = Constants.Properties.RId, NullValueHandling = NullValueHandling.Ignore)]
149149
internal string ResourceId { get; private set; }
150150
}
151151
}

Microsoft.Azure.Cosmos/src/Resource/Settings/PermissionProperties.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace Microsoft.Azure.Cosmos
1515
public class PermissionProperties
1616
{
1717
/// <summary>
18-
/// Initialize a new instance of the <see cref="PermissionProperties"/> with permssion to <see cref="Container"/>.
18+
/// Initialize a new instance of the <see cref="PermissionProperties"/> with permission to <see cref="Container"/>.
1919
/// </summary>
2020
/// <param name="id">The permission id.</param>
2121
/// <param name="permissionMode">The <see cref="PermissionMode"/>.</param>
@@ -40,7 +40,7 @@ public PermissionProperties(string id,
4040
}
4141

4242
/// <summary>
43-
/// Initialize a new instance of the <see cref="PermissionProperties"/> with permssion to cosnmos item.
43+
/// Initialize a new instance of the <see cref="PermissionProperties"/> with permission to Cosmos item.
4444
/// </summary>
4545
/// <param name="id">The permission id.</param>
4646
/// <param name="permissionMode">The <see cref="PermissionMode"/>.</param>

Microsoft.Azure.Cosmos/src/Resource/Settings/StoredProcedureProperties.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,15 @@ public string Id
8181
/// <remarks>
8282
/// ETags are used for concurrency checking when updating resources.
8383
/// </remarks>
84-
[JsonProperty(PropertyName = Constants.Properties.ETag)]
84+
[JsonProperty(PropertyName = Constants.Properties.ETag, NullValueHandling = NullValueHandling.Ignore)]
8585
public string ETag { get; private set; }
8686

8787
/// <summary>
8888
/// Gets the last modified timestamp associated with <see cref="StoredProcedureProperties" /> from the Azure Cosmos DB service.
8989
/// </summary>
9090
/// <value>The last modified timestamp associated with the resource.</value>
9191
[JsonConverter(typeof(UnixDateTimeConverter))]
92-
[JsonProperty(PropertyName = Constants.Properties.LastModified)]
92+
[JsonProperty(PropertyName = Constants.Properties.LastModified, NullValueHandling = NullValueHandling.Ignore)]
9393
public DateTime? LastModified { get; private set; }
9494

9595
/// <summary>
@@ -114,7 +114,7 @@ public string Id
114114
/// resource whether that is a database, a collection or a document.
115115
/// These resource ids are used when building up SelfLinks, a static addressable Uri for each resource within a database account.
116116
/// </remarks>
117-
[JsonProperty(PropertyName = Constants.Properties.RId)]
117+
[JsonProperty(PropertyName = Constants.Properties.RId, NullValueHandling = NullValueHandling.Ignore)]
118118
internal string ResourceId { get; private set; }
119119
}
120120
}

Microsoft.Azure.Cosmos/src/Resource/Settings/ThroughputProperties.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,16 +35,16 @@ public class ThroughputProperties
3535
/// <remarks>
3636
/// ETags are used for concurrency checking when updating resources.
3737
/// </remarks>
38-
[JsonProperty(PropertyName = Constants.Properties.ETag)]
38+
[JsonProperty(PropertyName = Constants.Properties.ETag, NullValueHandling = NullValueHandling.Ignore)]
3939
public string ETag { get; private set; }
4040

4141
/// <summary>
4242
/// Gets the last modified time stamp associated with <see cref="DatabaseProperties" /> from the Azure Cosmos DB service.
4343
/// </summary>
4444
/// <value>The last modified time stamp associated with the resource.</value>
4545
[JsonConverter(typeof(UnixDateTimeConverter))]
46-
[JsonProperty(PropertyName = Constants.Properties.LastModified)]
47-
public DateTime LastModified { get; private set; }
46+
[JsonProperty(PropertyName = Constants.Properties.LastModified, NullValueHandling = NullValueHandling.Ignore)]
47+
public DateTime? LastModified { get; private set; }
4848

4949
/// <summary>
5050
/// Gets the provisioned throughput for a resource in measurement of request units per second in the Azure Cosmos service.
@@ -69,13 +69,13 @@ public int? Throughput
6969
/// <summary>
7070
/// Gets the offer rid.
7171
/// </summary>
72-
[JsonProperty(PropertyName = Constants.Properties.RId)]
72+
[JsonProperty(PropertyName = Constants.Properties.RId, NullValueHandling = NullValueHandling.Ignore)]
7373
internal string OfferRID { get; private set; }
7474

7575
/// <summary>
7676
/// Gets the resource rid.
7777
/// </summary>
78-
[JsonProperty(PropertyName = Constants.Properties.OfferResourceId)]
78+
[JsonProperty(PropertyName = Constants.Properties.OfferResourceId, NullValueHandling = NullValueHandling.Ignore)]
7979
internal string ResourceRID { get; private set; }
8080

8181
[JsonProperty(PropertyName = "content", DefaultValueHandling = DefaultValueHandling.Ignore)]

Microsoft.Azure.Cosmos/src/Resource/Settings/TriggerProperties.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ public class TriggerProperties
7575
/// <remarks>
7676
/// ETags are used for concurrency checking when updating resources.
7777
/// </remarks>
78-
[JsonProperty(PropertyName = Constants.Properties.ETag)]
78+
[JsonProperty(PropertyName = Constants.Properties.ETag, NullValueHandling = NullValueHandling.Ignore)]
7979
public string ETag { get; private set; }
8080

8181
/// <summary>

Microsoft.Azure.Cosmos/src/Resource/Settings/UserDefinedFunctionProperties.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public class UserDefinedFunctionProperties
8888
/// <remarks>
8989
/// ETags are used for concurrency checking when updating resources.
9090
/// </remarks>
91-
[JsonProperty(PropertyName = Constants.Properties.ETag)]
91+
[JsonProperty(PropertyName = Constants.Properties.ETag, NullValueHandling = NullValueHandling.Ignore)]
9292
public string ETag { get; private set; }
9393

9494
/// <summary>

Microsoft.Azure.Cosmos/src/Resource/Settings/UserProperties.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,15 @@ public string Id
6565
/// <remarks>
6666
/// ETags are used for concurrency checking when updating resources.
6767
/// </remarks>
68-
[JsonProperty(PropertyName = Constants.Properties.ETag)]
68+
[JsonProperty(PropertyName = Constants.Properties.ETag, NullValueHandling = NullValueHandling.Ignore)]
6969
public string ETag { get; private set; }
7070

7171
/// <summary>
7272
/// Gets the last modified time stamp associated with <see cref="DatabaseProperties" /> from the Azure Cosmos DB service.
7373
/// </summary>
7474
/// <value>The last modified time stamp associated with the resource.</value>
7575
[JsonConverter(typeof(UnixDateTimeConverter))]
76-
[JsonProperty(PropertyName = Constants.Properties.LastModified)]
76+
[JsonProperty(PropertyName = Constants.Properties.LastModified, NullValueHandling = NullValueHandling.Ignore)]
7777
public DateTime? LastModified { get; private set; }
7878

7979
/// <summary>
@@ -98,7 +98,7 @@ public string Id
9898
/// resource whether that is a database, a collection or a document.
9999
/// These resource ids are used when building up SelfLinks, a static addressable Uri for each resource within a database account.
100100
/// </remarks>
101-
[JsonProperty(PropertyName = Constants.Properties.RId)]
101+
[JsonProperty(PropertyName = Constants.Properties.RId, NullValueHandling = NullValueHandling.Ignore)]
102102
internal string ResourceId { get; set; }
103103

104104
/// <summary>

Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSeriliazerUnitTests.cs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,73 @@ public void ValidateSerializer()
5151
}
5252
}
5353

54+
[TestMethod]
55+
public void ValidatePropertySerialization()
56+
{
57+
string id = "testId";
58+
this.TestProperty<AccountProperties>(
59+
id,
60+
$@"{{""id"":""{id}"",""writableLocations"":[],""readableLocations"":[],""userConsistencyPolicy"":null,""addresses"":null,""userReplicationPolicy"":null,""systemReplicationPolicy"":null,""readPolicy"":null,""queryEngineConfiguration"":null,""enableMultipleWriteLocations"":false}}");
61+
62+
this.TestProperty<DatabaseProperties>(
63+
id,
64+
$@"{{""id"":""{id}""}}");
65+
66+
this.TestProperty<ContainerProperties>(
67+
id,
68+
$@"{{""id"":""{id}"",""partitionKey"":{{""paths"":[],""kind"":""Hash""}}}}");
69+
70+
this.TestProperty<StoredProcedureProperties>(
71+
id,
72+
$@"{{""body"":""bodyCantBeNull"",""id"":""testId""}}");
73+
74+
this.TestProperty<TriggerProperties>(
75+
id,
76+
$@"{{""body"":null,""triggerType"":""Pre"",""triggerOperation"":""All"",""id"":""{id}""}}");
77+
78+
this.TestProperty<UserDefinedFunctionProperties>(
79+
id,
80+
$@"{{""body"":null,""id"":""{id}""}}");
81+
82+
this.TestProperty<UserProperties>
83+
(id,
84+
$@"{{""id"":""{id}"",""_permissions"":null}}");
85+
86+
this.TestProperty<PermissionProperties>(
87+
id,
88+
$@"{{""id"":""{id}"",""resource"":null,""permissionMode"":0}}");
89+
90+
this.TestProperty<ConflictProperties>(
91+
id,
92+
$@"{{""id"":""{id}"",""operationType"":""Invalid"",""resourceType"":null,""resourceId"":null,""content"":null,""conflict_lsn"":0}}");
93+
94+
// Throughput doesn't have an id.
95+
string defaultThroughputJson = @"{""Throughput"":null}";
96+
ThroughputProperties property = JsonConvert.DeserializeObject<ThroughputProperties>(defaultThroughputJson);
97+
Assert.IsNull(property.Throughput);
98+
string propertyJson = JsonConvert.SerializeObject(property, new JsonSerializerSettings()
99+
{
100+
Formatting = Formatting.None
101+
});
102+
Assert.AreEqual(defaultThroughputJson, propertyJson);
103+
}
104+
105+
private void TestProperty<T>(string id, string defaultJson)
106+
{
107+
dynamic property = JsonConvert.DeserializeObject<T>(defaultJson);
108+
Assert.AreEqual(id, property.Id);
109+
string propertyJson = JsonConvert.SerializeObject(property, new JsonSerializerSettings() {
110+
Formatting = Formatting.None
111+
});
112+
113+
Assert.AreEqual(defaultJson, propertyJson);
114+
// System properties should be ignored if null
115+
Assert.IsFalse(propertyJson.Contains("_etag"));
116+
Assert.IsFalse(propertyJson.Contains("_rid"));
117+
Assert.IsFalse(propertyJson.Contains("_ts"));
118+
Assert.IsFalse(propertyJson.Contains("_self"));
119+
}
120+
54121
[TestMethod]
55122
public void ValidateJson()
56123
{

Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosSerializerCoreTests.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,12 @@ public void ValidateCustomSerializerNotUsedForInternalTypes()
103103
this.TestProperty<AccountProperties>(
104104
serializerCore,
105105
id,
106-
$@"{{""id"":""{id}"",""_etag"":null,""_rid"":null,""writableLocations"":[],""readableLocations"":[],""userConsistencyPolicy"":null,""addresses"":null,""userReplicationPolicy"":null,""systemReplicationPolicy"":null,""readPolicy"":null,""queryEngineConfiguration"":null,""enableMultipleWriteLocations"":false}}");
106+
$@"{{""id"":""{id}"",""writableLocations"":[],""readableLocations"":[],""userConsistencyPolicy"":null,""addresses"":null,""userReplicationPolicy"":null,""systemReplicationPolicy"":null,""readPolicy"":null,""queryEngineConfiguration"":null,""enableMultipleWriteLocations"":false}}");
107107

108108
this.TestProperty<DatabaseProperties>(
109109
serializerCore,
110110
id,
111-
$@"{{""id"":""{id}"",""_etag"":null,""_ts"":1576767176,""_rid"":null}}");
111+
$@"{{""id"":""{id}""}}");
112112

113113
this.TestProperty<ContainerProperties>(
114114
serializerCore,
@@ -118,22 +118,22 @@ public void ValidateCustomSerializerNotUsedForInternalTypes()
118118
this.TestProperty<StoredProcedureProperties>(
119119
serializerCore,
120120
id,
121-
$@"{{""body"":""bodyCantBeNull"",""id"":""{id}"",""_etag"":null,""_ts"":1576767176,""_rid"":null}}");
121+
$@"{{""body"":""bodyCantBeNull"",""id"":""{id}""}}");
122122

123123
this.TestProperty<TriggerProperties>(
124124
serializerCore,
125125
id,
126-
$@"{{""body"":null,""triggerType"":""Pre"",""triggerOperation"":""All"",""id"":""{id}"",""_etag"":null}}");
126+
$@"{{""body"":null,""triggerType"":""Pre"",""triggerOperation"":""All"",""id"":""{id}""}}");
127127

128128
this.TestProperty<UserDefinedFunctionProperties>(
129129
serializerCore,
130130
id,
131-
$@"{{""body"":null,""id"":""{id}"",""_etag"":null}}");
131+
$@"{{""body"":null,""id"":""{id}""}}");
132132

133133
this.TestProperty<UserProperties>(
134134
serializerCore,
135135
id,
136-
$@"{{""id"":""{id}"",""_etag"":null,""_ts"":1576767176,""_rid"":null,""_permissions"":null}}");
136+
$@"{{""id"":""{id}"",""_permissions"":null}}");
137137

138138
this.TestProperty<PermissionProperties>(
139139
serializerCore,
@@ -146,7 +146,7 @@ public void ValidateCustomSerializerNotUsedForInternalTypes()
146146
$@"{{""id"":""{id}"",""operationType"":""Invalid"",""resourceType"":null,""resourceId"":null,""content"":null,""conflict_lsn"":0}}");
147147

148148
// Throughput doesn't have an id.
149-
string defaultThroughputJson = @"{""_etag"":null,""_ts"":1576767176,""Throughput"":null,""_rid"":null,""offerResourceId"":null}";
149+
string defaultThroughputJson = @"{""Throughput"":null}";
150150
ThroughputProperties property = JsonConvert.DeserializeObject<ThroughputProperties>(defaultThroughputJson);
151151
Assert.IsNull(property.Throughput);
152152
string propertyJson = JsonConvert.SerializeObject(property);

0 commit comments

Comments
 (0)