Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prepare release of Azure.Core JSON helpers #17820

Merged
merged 3 commits into from
Jan 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions sdk/core/Microsoft.Azure.Core.NewtonsoftJson/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Release History

## 1.0.0-preview.2 (2020-11-10)
## 1.0.0 (2021-01-06)

### Added
- `Newtonsoft.Json.JsonConverter` implementation for the `ETag`

- `Newtonsoft.Json.JsonConverter` implementation for the `ETag`

## 1.0.0-preview.1 (2020-08-07)

Expand Down
101 changes: 88 additions & 13 deletions sdk/core/Microsoft.Azure.Core.NewtonsoftJson/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,107 @@ This library contains converters dependent on the [Newtonsoft.Json package][newt

## Getting started

TODO
Install this package if you want to use Newtonsoft.Json to serialize and deserialize model types with some Azure SDKs.

### Install the package

TODO
Install this package from [NuGet] using the .NET CLI:

### Prerequisites
```bash
dotnet add package Microsoft.Azure.Core.NewtonsoftJson
```

TODO
## Key concepts

### Authenticate the client
This support package contains the `NewtonsoftJsonObjectSerializer` class which can be passed to some Azure SDKs' client options classes, as shown in the examples below.

TODO
The following converters are added automatically to the `NewtonsoftJsonObjectSerializer` if you do not pass your own `JsonSerializerSettings`:

## Key concepts
- `NewtonsoftJsonETagConverter` to convert `Azure.ETag` properties.

TODO
See the example [Using default converters](#using-default-converters) below for getting an instance of `JsonSerializerSettings` with this default list you can then modify as needed.

## Examples

TODO
The [Azure.Search.Documents package][azure_search_documents_package] is used in examples to show how search results can be deserialized. For more information and examples using Azure.Search.Documents, see its [README][azure_search_documents_readme].

### Deserializing models

Consider a model class containing information about movies:

```C# Snippet:Microsoft_Azure_Core_NewtonsoftJson_Samples_Readme_Model
public class Movie
{
[JsonProperty("uuid")]
public string Id { get; private set; } = Guid.NewGuid().ToString();

public string Title { get; set; }

public string Description { get; set; }

public float Rating { get; set; }
}
```

Our Azure Cognitive Search index is defined using camelCase fields, and the `Id` field is actually defined as "uuid"; however, we can provide an idiomatic model without having to attribute all properties by setting the `JsonSerializerSettings.ContractResolver` property as shown below:

```C# Snippet:Microsoft_Azure_Core_NewtonsoftJson_Samples_Readme_SearchSample
// Get the Azure Cognitive Search endpoint and read-only API key.
Uri endpoint = new Uri(Environment.GetEnvironmentVariable("SEARCH_ENDPOINT"));
AzureKeyCredential credential = new AzureKeyCredential(Environment.GetEnvironmentVariable("SEARCH_API_KEY"));

// Create serializer options with default converters for Azure SDKs.
JsonSerializerSettings serializerSettings = NewtonsoftJsonObjectSerializer.CreateJsonSerializerSettings();

// Serialize property names using camelCase by default.
serializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

SearchClientOptions clientOptions = new SearchClientOptions
{
Serializer = new NewtonsoftJsonObjectSerializer(serializerSettings)
};

SearchClient client = new SearchClient(endpoint, "movies", credential, clientOptions);
Response<SearchResults<Movie>> results = client.Search<Movie>("Return of the King");

foreach (SearchResult<Movie> result in results.Value.GetResults())
{
Movie movie = result.Document;

Console.WriteLine(movie.Title);
Console.WriteLine(movie.Description);
Console.WriteLine($"Rating: {movie.Rating}\n");
}
```

If searching an index full of movies, the following may be printed:

```text
The Lord of the Rings: The Return of the King
Gandalf and Aragorn lead the World of Men against Sauron's army to draw his gaze from Frodo and Sam as they approach Mount Doom with the One Ring.
Rating: 9.1
```

### Using default converters

If you instantiate a `NewtonsoftJsonObjectSerializer` using the default constructor, some converters for common Azure SDKs are added automatically as listed above in [Key concepts](#key-concepts). To modify these default settings, you can create a new `JsonSerializerSettings` like in the following example:

```C# Snippet:Microsoft_Azure_Core_NewtonsoftJson_Samples_Readme_DefaultSerializerSettings
JsonSerializerSettings serializerSettings = NewtonsoftJsonObjectSerializer.CreateJsonSerializerSettings();

## Troubleshooting
// Serialize property names using camelCase by default.
serializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

TODO
// Add converters as needed, for example, to convert movie genres to an enum.
serializerSettings.Converters.Add(new StringEnumConverter());

## Next steps
SearchClientOptions clientOptions = new SearchClientOptions
{
Serializer = new NewtonsoftJsonObjectSerializer(serializerSettings)
};
```

TODO
You can add or remove converters, set the `ContractResolver`, or any other members of `JsonSerializerSettings` you need.

## Contributing

Expand All @@ -46,6 +118,9 @@ This project has adopted the [Microsoft Open Source Code of Conduct][code_of_con
![Impressions](https://azure-sdk-impressions.azurewebsites.net/api/impressions/azure-sdk-for-net%2Fsdk%2Fcore%2FMicrosoft.Azure.Core.NewtonsoftJson%2FREADME.png)

[azure_core_package]: https://www.nuget.org/packages/Azure.Core/
[azure_search_documents_package]: https://www.nuget.org/packages/Azure.Search.Documents/
[azure_search_documents_readme]: https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/search/Azure.Search.Documents/README.md
[code_of_conduct]: https://opensource.microsoft.com/codeofconduct
[code_of_conduct_faq]: https://opensource.microsoft.com/codeofconduct/faq/
[newtonsoft_json_package]: https://www.nuget.org/packages/Newtonsoft.Json/
[NuGet]: https://www.nuget.org
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<AssemblyTitle>Newtonsoft.Json support for Azure Core shared client library for .NET</AssemblyTitle>
<RootNamespace>Azure.Core.Serialization</RootNamespace>
<Version>1.0.0-preview.2</Version>
<Version>1.0.0</Version>
<Description>This library contains converters dependent on the Newtonsoft.Json package for use with Azure.Core.</Description>
<PackageTags>Microsoft Azure SDK Newtonsoft Json</PackageTags>
<Nullable>enable</Nullable>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@ public NewtonsoftJsonObjectSerializer() : this(CreateJsonSerializerSettings())
public static JsonSerializerSettings CreateJsonSerializerSettings()
{
var settings = new JsonSerializerSettings();

// NOTE: Update the README when converters are added by default.
settings.Converters.Add(new NewtonsoftJsonETagConverter());

return settings;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Azure.Search.Documents" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="Newtonsoft.Json" />
<PackageReference Include="NUnit" />
<PackageReference Include="NUnit3TestAdapter" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="$(AzureCoreTestFramework)" />
<ProjectReference Include="..\src\Microsoft.Azure.Core.NewtonsoftJson.csproj" />
</ItemGroup>
</Project>
115 changes: 115 additions & 0 deletions sdk/core/Microsoft.Azure.Core.NewtonsoftJson/tests/Samples/Readme.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Linq;
using Azure;
using Azure.Core.Serialization;
using Azure.Core.TestFramework;
using Azure.Search.Documents;
using Azure.Search.Documents.Indexes;
using Azure.Search.Documents.Indexes.Models;
using Azure.Search.Documents.Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
using NUnit.Framework;

namespace Microsoft.Azure.Core.NewtonsoftJson.Tests.Samples
{
public class Readme
{
[Test]
public void SearchSample()
{
MockResponse response = new MockResponse(200);
response.SetContent(@"{
""value"": [
{
""@search.score"": 1.0,
""uuid"": ""efe8857f-1d74-41e2-9ff1-4943a9ad69d5"",
""title"": ""The Lord of the Rings: The Return of the King"",
""description"": ""Gandalf and Aragorn lead the World of Men against Sauron's army to draw his gaze from Frodo and Sam as they approach Mount Doom with the One Ring."",
""rating"": 9.1
}
]
}");

Environment.SetEnvironmentVariable("SEARCH_ENDPOINT", "https://sample.search.windows.net");
Environment.SetEnvironmentVariable("SEARCH_API_KEY", "sample");

#region Snippet:Microsoft_Azure_Core_NewtonsoftJson_Samples_Readme_SearchSample
// Get the Azure Cognitive Search endpoint and read-only API key.
Uri endpoint = new Uri(Environment.GetEnvironmentVariable("SEARCH_ENDPOINT"));
AzureKeyCredential credential = new AzureKeyCredential(Environment.GetEnvironmentVariable("SEARCH_API_KEY"));

// Create serializer options with default converters for Azure SDKs.
JsonSerializerSettings serializerSettings = NewtonsoftJsonObjectSerializer.CreateJsonSerializerSettings();

// Serialize property names using camelCase by default.
serializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

SearchClientOptions clientOptions = new SearchClientOptions
{
/*@@*/ Transport = new MockTransport(response),
Serializer = new NewtonsoftJsonObjectSerializer(serializerSettings)
};

SearchClient client = new SearchClient(endpoint, "movies", credential, clientOptions);
Response<SearchResults<Movie>> results = client.Search<Movie>("Return of the King");

foreach (SearchResult<Movie> result in results.Value.GetResults())
{
Movie movie = result.Document;

Console.WriteLine(movie.Title);
Console.WriteLine(movie.Description);
Console.WriteLine($"Rating: {movie.Rating}\n");
}
#endregion Snippet:Microsoft_Azure_Core_NewtonsoftJson_Samples_Readme_SearchSample

Movie _movie = results.Value.GetResults().Single().Document;
Assert.AreEqual("efe8857f-1d74-41e2-9ff1-4943a9ad69d5", _movie.Id);
Assert.AreEqual("The Lord of the Rings: The Return of the King", _movie.Title);
Assert.AreEqual("Gandalf and Aragorn lead the World of Men against Sauron's army to draw his gaze from Frodo and Sam as they approach Mount Doom with the One Ring.", _movie.Description);
Assert.AreEqual(9.1, _movie.Rating, 0.01);
}

[Test]
public void DefaultSerializerSettings()
{
#region Snippet:Microsoft_Azure_Core_NewtonsoftJson_Samples_Readme_DefaultSerializerSettings
JsonSerializerSettings serializerSettings = NewtonsoftJsonObjectSerializer.CreateJsonSerializerSettings();

// Serialize property names using camelCase by default.
serializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

// Add converters as needed, for example, to convert movie genres to an enum.
serializerSettings.Converters.Add(new StringEnumConverter());

SearchClientOptions clientOptions = new SearchClientOptions
{
Serializer = new NewtonsoftJsonObjectSerializer(serializerSettings)
};
#endregion Snippet:Microsoft_Azure_Core_NewtonsoftJson_Samples_Readme_DefaultSerializerSettings

Assert.AreEqual(2, serializerSettings.Converters.Count);
Assert.That(serializerSettings.Converters, Has.Some.TypeOf(typeof(NewtonsoftJsonETagConverter)));
Assert.That(serializerSettings.Converters, Has.Some.TypeOf(typeof(StringEnumConverter)));
}

#region Snippet:Microsoft_Azure_Core_NewtonsoftJson_Samples_Readme_Model
public class Movie
{
[JsonProperty("uuid")]
public string Id { get; private set; } = Guid.NewGuid().ToString();

public string Title { get; set; }

public string Description { get; set; }

public float Rating { get; set; }
}
#endregion Snippet:Microsoft_Azure_Core_NewtonsoftJson_Samples_Readme_Model
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Release History

## 1.0.0-beta.2 (Unreleased)
## 1.0.0 (2021-01-06)

Released.

## 1.0.0-beta.1 (2020-10-08)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Install this package if you use the Microsoft.Spatial package in your applicatio
Install this package from [NuGet] using the .NET CLI:

```bash
dotnet add package Microsoft.Azure.Core.Spatial.NewtonsoftJson --version 1.0.0-beta.1
dotnet add package Microsoft.Azure.Core.Spatial.NewtonsoftJson
```

## Key concepts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<AssemblyTitle>Newtonsoft.Json support for the Microsoft.Spatial library</AssemblyTitle>
<Description>This library contains converters dependent on the Newtonsoft.Json package for use with Microsoft.Spatial when using the Azure SDK for .NET.</Description>
<RootNamespace>Azure.Core.Serialization</RootNamespace>
<Version>1.0.0-beta.2</Version>
<Version>1.0.0</Version>
<PackageTags>Microsoft Azure SDK Spatial Newtonsoft Json</PackageTags>
<TargetFrameworks>$(RequiredTargetFrameworks)</TargetFrameworks>
<EnableClientSdkAnalyzers>false</EnableClientSdkAnalyzers>
Expand Down
3 changes: 2 additions & 1 deletion sdk/core/Microsoft.Azure.Core.Spatial/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# Release History

## 1.0.0-beta.2 (Unreleased)
## 1.0.0 (2021-01-06)

Released.

## 1.0.0-beta.1 (2020-10-08)

Expand Down
2 changes: 1 addition & 1 deletion sdk/core/Microsoft.Azure.Core.Spatial/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Install this package if you use the Microsoft.Spatial package in your applicatio
Install this package from [NuGet] using the .NET CLI:

```bash
dotnet add package Microsoft.Azure.Core.Spatial --version 1.0.0-beta.1
dotnet add package Microsoft.Azure.Core.Spatial
```

## Key concepts
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<AssemblyTitle>System.Text.Json support for the Microsoft.Spatial library</AssemblyTitle>
<Description>This library contains converters for System.Text.Json for use with Microsoft.Spatial when using the Azure SDK for .NET.</Description>
<RootNamespace>Azure.Core</RootNamespace>
<Version>1.0.0-beta.2</Version>
<Version>1.0.0</Version>
<PackageTags>Microsoft Azure SDK Spatial System Text Json</PackageTags>
<TargetFrameworks>$(RequiredTargetFrameworks)</TargetFrameworks>
<EnableClientSdkAnalyzers>false</EnableClientSdkAnalyzers>
Expand Down