Merge branch 'master' into wrapPanel.verticalAlignment

This commit is contained in:
Vincent 2020-09-22 10:02:15 +02:00 коммит произвёл GitHub
Родитель 14fc90849c a7f897616b
Коммит 5ecf80687d
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
105 изменённых файлов: 1727 добавлений и 788 удалений

Просмотреть файл

@ -7,7 +7,7 @@
This .NET standard library enables access to different data sources such as Microsoft Graph, OneDrive, Twitter, Microsoft Translator, and LinkedIn. It is part of the Windows Community Toolkit.
</Description>
<PackageTags>UWP Community Toolkit Windows Microsoft Graph OneDrive Twitter Translator LinkedIn service login OAuth</PackageTags>
<LangVersion>8.0</LangVersion>
<NoWarn>CS8002;CS0618</NoWarn>
<DeterministicSourcePaths Condition="'$(EnableSourceLink)' == ''">false</DeterministicSourcePaths>
</PropertyGroup>
@ -27,7 +27,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="System.Text.Json" Version="4.7.2" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
</ItemGroup>
@ -50,4 +50,4 @@
<ItemGroup Condition="!('$(TargetFramework)'=='uap10.0.16299')">
<Compile Remove="PlatformSpecific\Uwp\**\*" />
</ItemGroup>
</Project>
</Project>

Просмотреть файл

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Library Name="Microsoft.Toolkit.Services">
<Namespace Name="System.Text.Json.Serialization.Converters" Dynamic="Required All"/>
</Library>
</Directives>

Просмотреть файл

@ -7,9 +7,9 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Toolkit.Services.Core;
using Newtonsoft.Json.Linq;
#if WINRT
using Microsoft.Toolkit.Services.PlatformSpecific.Uwp;
@ -81,7 +81,8 @@ namespace Microsoft.Toolkit.Services.LinkedIn
throw new ArgumentException("Missing callback uri");
}
if (!Enum.IsDefined(typeof(LinkedInPermissions), requiredPermissions))
// Check if its a valid combination of LinkedInPermissions
if ((~(int)LinkedInPermissionsHelpers.AllPermissions & (int)requiredPermissions) != 0)
{
throw new ArgumentException("Error retrieving required permissions");
}
@ -186,22 +187,18 @@ namespace Microsoft.Toolkit.Services.LinkedIn
var url = $"{_baseUrl}{config.Query}/~:({fields})?oauth2_access_token={Tokens.AccessToken}&format=json&count={maxRecords}&start={startRecord}";
using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, new Uri(url)))
using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, new Uri(url));
request.Headers.Connection.TryParseAdd("Keep-Alive");
using var response = await client.SendAsync(request).ConfigureAwait(false);
var data = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
if (response.IsSuccessStatusCode && !string.IsNullOrEmpty(data))
{
request.Headers.Connection.TryParseAdd("Keep-Alive");
using (var response = await client.SendAsync(request).ConfigureAwait(false))
{
var data = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
if (response.IsSuccessStatusCode && !string.IsNullOrEmpty(data))
{
return parser.Parse(data);
}
throw new RequestFailedException((System.Net.HttpStatusCode)response.StatusCode, data);
}
return parser.Parse(data);
}
throw new RequestFailedException((System.Net.HttpStatusCode)response.StatusCode, data);
}
/// <summary>
@ -222,22 +219,18 @@ namespace Microsoft.Toolkit.Services.LinkedIn
var url = $"{_baseUrl}/people/~/shares?oauth2_access_token={Tokens.AccessToken}&format=json";
using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, new Uri(url)))
{
request.Headers.Add("x-li-format", "json");
var stringContent = requestParser.Parse(shareRequest);
request.Content = new StringContent(stringContent, Encoding.UTF8, "application/json");
using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, new Uri(url));
request.Headers.Add("x-li-format", "json");
var stringContent = requestParser.Parse(shareRequest);
request.Content = new StringContent(stringContent, Encoding.UTF8, "application/json");
using (var response = await client.SendAsync(request).ConfigureAwait(false))
{
var data = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
using var response = await client.SendAsync(request).ConfigureAwait(false);
var data = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
var responseParser = new LinkedInParser<U>();
var responseParser = new LinkedInParser<U>();
var listResults = responseParser.Parse(data) as List<U>;
return listResults[0];
}
}
var listResults = responseParser.Parse(data) as List<U>;
return listResults[0];
}
return default(U);
@ -263,15 +256,13 @@ namespace Microsoft.Toolkit.Services.LinkedIn
+ "&client_id=" + tokens.ClientId
+ "&client_secret=" + tokens.ClientSecret;
using (var request = new HttpRequestMessage(HttpMethod.Post, new Uri(url)))
{
using (var response = await client.SendAsync(request).ConfigureAwait(false))
{
var jsonString = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
var json = JObject.Parse(jsonString);
return json.GetValue("access_token").Value<string>();
}
}
using var request = new HttpRequestMessage(HttpMethod.Post, new Uri(url));
using var response = await client.SendAsync(request).ConfigureAwait(false);
using var jsonStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
using var jsonDoc = await JsonDocument.ParseAsync(jsonStream).ConfigureAwait(false);
var value = jsonDoc.RootElement.GetProperty("access_token");
return value.GetString();
}
private async Task<string> GetAuthorizeCodeAsync(LinkedInOAuthTokens tokens, LinkedInPermissions permissions)

Просмотреть файл

@ -3,7 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using Newtonsoft.Json;
using System.Text.Json;
namespace Microsoft.Toolkit.Services.LinkedIn
{
@ -24,11 +24,11 @@ namespace Microsoft.Toolkit.Services.LinkedIn
try
{
results = JsonConvert.DeserializeObject<List<T>>(data);
results = JsonSerializer.Deserialize<List<T>>(data);
}
catch (JsonSerializationException)
catch (JsonException)
{
T linkedInResult = JsonConvert.DeserializeObject<T>(data);
T linkedInResult = JsonSerializer.Deserialize<T>(data);
results = new List<T> { linkedInResult };
}
@ -42,7 +42,7 @@ namespace Microsoft.Toolkit.Services.LinkedIn
/// <returns>Returns string data.</returns>
public string Parse(T dataToShare)
{
return JsonConvert.SerializeObject(dataToShare, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
return JsonSerializer.Serialize(dataToShare, typeof(T), new JsonSerializerOptions { IgnoreNullValues = true });
}
}
}

Просмотреть файл

@ -37,4 +37,18 @@ namespace Microsoft.Toolkit.Services.LinkedIn
/// </summary>
WriteShare = 8
}
#pragma warning disable SA1649 // File name should match first type name
internal static class LinkedInPermissionsHelpers
{
/// <summary>
/// Internal AllPermissions for LinkedInPermissions, so we don't expose it. Keep it in sync with <see cref="LinkedInPermissions"/>
/// </summary>
internal const LinkedInPermissions AllPermissions =
LinkedInPermissions.ReadBasicProfile |
LinkedInPermissions.ReadEmailAddress |
LinkedInPermissions.ReadWriteCompanyAdmin |
LinkedInPermissions.WriteShare;
}
#pragma warning restore SA1649 // File name should match first type name
}

Просмотреть файл

@ -4,8 +4,8 @@
using System;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace Microsoft.Toolkit.Services.MicrosoftTranslator
{
@ -24,6 +24,9 @@ namespace Microsoft.Toolkit.Services.MicrosoftTranslator
/// </summary>
private static readonly Uri ServiceUrl = new Uri("https://api.cognitive.microsoft.com/sts/v1.0/issueToken");
// TODO
// private static readonly Uri ServiceUrl = new Uri(THIS SHOULD BE A PARAMETER NOW);
/// <summary>
/// After obtaining a valid token, this class will cache it for this duration.
/// Use a duration of 8 minutes, which is less than the actual token lifetime of 10 minutes.
@ -90,24 +93,22 @@ namespace Microsoft.Toolkit.Services.MicrosoftTranslator
return _storedTokenValue;
}
using (var request = new HttpRequestMessage(HttpMethod.Post, ServiceUrl))
using var request = new HttpRequestMessage(HttpMethod.Post, ServiceUrl);
request.Headers.Add(OcpApimSubscriptionKeyHeader, SubscriptionKey);
var response = await client.SendAsync(request).ConfigureAwait(false);
var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
if (!response.IsSuccessStatusCode)
{
request.Headers.Add(OcpApimSubscriptionKeyHeader, SubscriptionKey);
var response = await client.SendAsync(request).ConfigureAwait(false);
var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
if (!response.IsSuccessStatusCode)
{
var error = JsonConvert.DeserializeObject<ErrorResponse>(content);
throw new TranslatorServiceException(error.Message);
}
_storedTokenTime = DateTime.Now;
_storedTokenValue = $"Bearer {content}";
return _storedTokenValue;
var error = JsonSerializer.Deserialize<ErrorResponse>(content);
throw new TranslatorServiceException(error?.Error?.Message);
}
_storedTokenTime = DateTime.Now;
_storedTokenValue = $"Bearer {content}";
return _storedTokenValue;
}
}
}

Просмотреть файл

@ -2,21 +2,27 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.MicrosoftTranslator
{
#pragma warning disable SA1402 // File may only contain a single type
/// <summary>
/// Holds information about an error occurred while accessing Microsoft Translator Service.
/// </summary>
internal class ErrorResponse
{
[JsonPropertyName("error")]
public Error Error { get; set; }
}
internal class Error
{
/// <summary>
/// Gets or sets the error message.
/// </summary>
[JsonPropertyName("message")]
public string Message { get; set; }
/// <summary>
/// Gets or sets the HTTP status code.
/// </summary>
public int StatusCode { get; set; }
}
#pragma warning restore SA1402 // File may only contain a single type
}

Просмотреть файл

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.MicrosoftTranslator
{
@ -30,7 +30,7 @@ namespace Microsoft.Toolkit.Services.MicrosoftTranslator
/// <summary>
/// Gets the directionality, which is rtl for right-to-left languages or ltr for left-to-right languages.
/// </summary>
[JsonProperty("dir")]
[JsonPropertyName("dir")]
public string Directionality { get; }
/// <summary>

Просмотреть файл

@ -8,9 +8,8 @@ using System.Globalization;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Microsoft.Toolkit.Services.MicrosoftTranslator
{
@ -108,14 +107,13 @@ namespace Microsoft.Toolkit.Services.MicrosoftTranslator
await CheckUpdateTokenAsync().ConfigureAwait(false);
var uriString = $"{BaseUrl}detect?{ApiVersion}";
using (var request = CreateHttpRequest(uriString, HttpMethod.Post, input.Select(t => new { Text = t.Substring(0, Math.Min(t.Length, _MaxTextLengthForDetection)) })))
{
var response = await client.SendAsync(request).ConfigureAwait(false);
var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
using var request = CreateHttpRequest(uriString, HttpMethod.Post, input.Select(t => new { Text = t.Substring(0, Math.Min(t.Length, _MaxTextLengthForDetection)) }));
var responseContent = JsonConvert.DeserializeObject<IEnumerable<DetectedLanguageResponse>>(content);
return responseContent;
}
var response = await client.SendAsync(request).ConfigureAwait(false);
var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
var responseContent = JsonSerializer.Deserialize<IEnumerable<DetectedLanguageResponse>>(content);
return responseContent;
}
/// <inheritdoc/>
@ -132,24 +130,23 @@ namespace Microsoft.Toolkit.Services.MicrosoftTranslator
await CheckUpdateTokenAsync().ConfigureAwait(false);
var uriString = $"{BaseUrl}languages?scope=translation&{ApiVersion}";
using (var request = CreateHttpRequest(uriString))
using var request = CreateHttpRequest(uriString);
language = language ?? Language;
if (!string.IsNullOrWhiteSpace(language))
{
language = language ?? Language;
if (!string.IsNullOrWhiteSpace(language))
{
// If necessary, adds the Accept-Language header in order to get localized language names.
request.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue(language));
}
var response = await client.SendAsync(request).ConfigureAwait(false);
var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
var jsonContent = JToken.Parse(content)["translation"];
var responseContent = JsonConvert.DeserializeObject<Dictionary<string, ServiceLanguage>>(jsonContent.ToString()).ToList();
responseContent.ForEach(r => r.Value.Code = r.Key);
return responseContent.Select(r => r.Value).OrderBy(r => r.Name).ToList();
// If necessary, adds the Accept-Language header in order to get localized language names.
request.Headers.AcceptLanguage.Add(new StringWithQualityHeaderValue(language));
}
var response = await client.SendAsync(request).ConfigureAwait(false);
var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
var jsonContent = JsonDocument.Parse(content).RootElement.GetProperty("translation");
var responseContent = JsonSerializer.Deserialize<Dictionary<string, ServiceLanguage>>(jsonContent.ToString()).ToList();
responseContent.ForEach(r => r.Value.Code = r.Key);
return responseContent.Select(r => r.Value).OrderBy(r => r.Name).ToList();
}
/// <inheritdoc/>
@ -216,14 +213,13 @@ namespace Microsoft.Toolkit.Services.MicrosoftTranslator
var toQueryString = string.Join("&", to.Select(t => $"to={t}"));
var uriString = (string.IsNullOrWhiteSpace(from) ? $"{BaseUrl}translate?{toQueryString}" : $"{BaseUrl}translate?from={from}&{toQueryString}") + $"&{ApiVersion}";
using (var request = CreateHttpRequest(uriString, HttpMethod.Post, input.Select(t => new { Text = t })))
{
var response = await client.SendAsync(request).ConfigureAwait(false);
var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
using var request = CreateHttpRequest(uriString, HttpMethod.Post, input.Select(t => new { Text = t }));
var responseContent = JsonConvert.DeserializeObject<IEnumerable<TranslationResponse>>(content);
return responseContent;
}
var response = await client.SendAsync(request).ConfigureAwait(false);
var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
var responseContent = JsonSerializer.Deserialize<IEnumerable<TranslationResponse>>(content);
return responseContent;
}
/// <inheritdoc/>
@ -254,7 +250,7 @@ namespace Microsoft.Toolkit.Services.MicrosoftTranslator
if (content != null)
{
var jsonRequest = JsonConvert.SerializeObject(content);
var jsonRequest = JsonSerializer.Serialize(content);
var requestContent = new StringContent(jsonRequest, System.Text.Encoding.UTF8, JsonMediaType);
request.Content = requestContent;
}

Просмотреть файл

@ -4,7 +4,7 @@
using System;
using System.Globalization;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -18,19 +18,19 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <summary>
/// Gets or sets time item was created.
/// </summary>
[JsonProperty("created_at")]
[JsonPropertyName("created_at")]
public string CreatedAt { get; set; }
/// <summary>
/// Gets or sets item Id.
/// </summary>
[JsonProperty("id_str")]
[JsonPropertyName("id_str")]
public string Id { get; set; }
/// <summary>
/// Gets or sets text of the tweet (handles both 140 and 280 characters)
/// </summary>
[JsonProperty("text")]
[JsonPropertyName("text")]
public string Text
{
get { return _text ?? FullText; }
@ -40,13 +40,13 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <summary>
/// Gets or sets text of the tweet (280 characters).
/// </summary>
[JsonProperty("full_text")]
[JsonPropertyName("full_text")]
private string FullText { get; set; }
/// <summary>
/// Gets or sets display text range (indexes of tweet text without RT and leading user mentions)
/// </summary>
[JsonProperty("display_text_range")]
[JsonPropertyName("display_text_range")]
public int[] DisplayTextRange { get; set; }
/// <summary>
@ -54,68 +54,68 @@ namespace Microsoft.Toolkit.Services.Twitter
/// (true when tweet is longer than 140 characters)
/// This entity may be deprecated - it never seems to be set to true.
/// </summary>
[JsonProperty("truncated")]
[JsonPropertyName("truncated")]
public bool IsTruncated { get; set; }
/// <summary>
/// Gets or sets attached content of the tweet
/// </summary>
[JsonProperty("entities")]
[JsonPropertyName("entities")]
public TwitterEntities Entities { get; set; }
/// <summary>
/// Gets or sets extended attached content of the tweet
/// </summary>
[JsonProperty("extended_entities")]
[JsonPropertyName("extended_entities")]
public TwitterExtendedEntities ExtendedEntities { get; set; }
/// <summary>
/// Gets or sets tweet source (client or website used)
/// </summary>
[JsonProperty("source")]
[JsonPropertyName("source")]
public string Source { get; set; }
/// <summary>
/// Gets or sets in_reply_to_screen_name
/// </summary>
[JsonProperty("in_reply_to_screen_name")]
[JsonPropertyName("in_reply_to_screen_name")]
public string InReplyToScreenName { get; set; }
/// <summary>
/// Gets or sets in_reply_to_status_id_str
/// </summary>
[JsonProperty("in_reply_to_status_id_str")]
[JsonPropertyName("in_reply_to_status_id_str")]
public string InReplyToStatusId { get; set; }
/// <summary>
/// Gets or sets in_reply_to_user_id_str
/// </summary>
[JsonProperty("in_reply_to_user_id_str")]
[JsonPropertyName("in_reply_to_user_id_str")]
public string InReplyToUserId { get; set; }
/// <summary>
/// Gets or sets user who posted the status.
/// </summary>
[JsonProperty("user")]
[JsonPropertyName("user")]
public TwitterUser User { get; set; }
/// <summary>
/// Gets or sets geo coordinates (latitude and longitude) returned by Twitter for some locations
/// </summary>
[JsonProperty("coordinates")]
[JsonPropertyName("coordinates")]
[JsonConverter(typeof(TwitterCoordinatesConverter))]
public TwitterCoordinates Coordinates { get; set; }
/// <summary>
/// Gets or sets the Place object returned by Twitter for some locations
/// </summary>
[JsonProperty("place")]
[JsonPropertyName("place")]
public TwitterPlace Place { get; set; }
/// <summary>
/// Gets or sets the Retweeted Tweet
/// </summary>
[JsonProperty("retweeted_status")]
[JsonPropertyName("retweeted_status")]
public Tweet RetweetedStatus { get; set; }
/// <summary>
@ -138,25 +138,25 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <summary>
/// Gets or sets quoted_status
/// </summary>
[JsonProperty("quoted_status")]
[JsonPropertyName("quoted_status")]
public Tweet QuotedStatus { get; set; }
/// <summary>
/// Gets or sets quoted_status_id_str
/// </summary>
[JsonProperty("quoted_status_id_str")]
[JsonPropertyName("quoted_status_id_str")]
public string QuotedStatusId { get; set; }
/// <summary>
/// Gets or sets quoted_status_permalink
/// </summary>
[JsonProperty("quoted_status_permalink")]
[JsonPropertyName("quoted_status_permalink")]
public TwitterUrl QuotedStatusPermalink { get; set; }
/// <summary>
/// Gets or sets approximate count of tweets quoting tweet
/// </summary>
[JsonProperty("quote_count")]
[JsonPropertyName("quote_count")]
public int QuoteCount { get; set; }
/// <summary>
@ -165,49 +165,49 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <remarks>
/// Premium and Enterprise API access only
/// </remarks>
[JsonProperty("reply_count")]
[JsonPropertyName("reply_count")]
public int ReplyCount { get; set; }
/// <summary>
/// Gets or sets number of times tweet has been retweeted
/// </summary>
[JsonProperty("retweet_count")]
[JsonPropertyName("retweet_count")]
public int RetweetCount { get; set; }
/// <summary>
/// Gets or sets number of times tweet has been liked
/// </summary>
[JsonProperty("favorite_count")]
[JsonPropertyName("favorite_count")]
public int FavoriteCount { get; set; }
/// <summary>
/// Gets or sets a value indicating whether or not logged-in user has liked tweet
/// </summary>
[JsonProperty("favorited")]
[JsonPropertyName("favorited")]
public bool Favorited { get; set; }
/// <summary>
/// Gets or sets a value indicating whether or not logged-in user has retweeted tweet
/// </summary>
[JsonProperty("retweeted")]
[JsonPropertyName("retweeted")]
public bool Retweeted { get; set; }
/// <summary>
/// Gets or sets a value indicating whether URL in tweet has been flagged for sensitive content
/// </summary>
[JsonProperty("possibly_sensitive")]
[JsonPropertyName("possibly_sensitive")]
public bool Sensitive { get; set; }
/// <summary>
/// Gets or sets stream filter of tweet
/// </summary>
[JsonProperty("filter_level")]
[JsonPropertyName("filter_level")]
public string FilterLevel { get; set; }
/// <summary>
/// Gets or sets BCP 47 language identifier of tweet content
/// </summary>
[JsonProperty("lang")]
[JsonPropertyName("lang")]
public string Language { get; set; }
}
}

Просмотреть файл

@ -3,7 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using Newtonsoft.Json;
using System.Text.Json;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -24,7 +24,7 @@ namespace Microsoft.Toolkit.Services.Twitter
return null;
}
return JsonConvert.DeserializeObject<List<Tweet>>(data);
return JsonSerializer.Deserialize<List<Tweet>>(data);
}
}
}

Просмотреть файл

@ -3,41 +3,97 @@
// See the LICENSE file in the project root for more information.
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
internal class TwitterCoordinatesConverter : JsonConverter
internal class TwitterCoordinatesConverter : JsonConverter<TwitterCoordinates>
{
private readonly JsonEncodedText latitudeName = JsonEncodedText.Encode("Latitude");
private readonly JsonEncodedText longitudeName = JsonEncodedText.Encode("Longitude");
public override bool CanConvert(Type objectType)
{
return false;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
private readonly JsonConverter<double> doubleConverter;
public TwitterCoordinatesConverter(JsonSerializerOptions options)
{
doubleConverter = options?.GetConverter(typeof(double)) as JsonConverter<double> ?? throw new InvalidOperationException();
}
public override TwitterCoordinates Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
try
{
if (reader.TokenType != JsonToken.StartObject)
if (reader.TokenType != JsonTokenType.StartObject)
{
return null;
}
var jObject = JObject.Load(reader);
var jCoordinates = jObject["coordinates"] as JArray;
double latitude = default;
bool latitudeSet = false;
if (jCoordinates.Count != 2)
double longitude = default;
bool longitudeSet = false;
// Get the first property.
reader.Read();
if (reader.TokenType != JsonTokenType.PropertyName)
{
return null;
throw new JsonException();
}
var twitterCoordinates = new TwitterCoordinates
if (reader.ValueTextEquals(latitudeName.EncodedUtf8Bytes))
{
Latitude = (double)jCoordinates[0],
Longitude = (double)jCoordinates[1]
latitude = ReadProperty(ref reader, options);
latitudeSet = true;
}
else if (reader.ValueTextEquals(longitudeName.EncodedUtf8Bytes))
{
longitude = ReadProperty(ref reader, options);
longitudeSet = true;
}
else
{
throw new JsonException();
}
// Get the second property.
reader.Read();
if (reader.TokenType != JsonTokenType.PropertyName)
{
throw new JsonException();
}
if (latitudeSet && reader.ValueTextEquals(longitudeName.EncodedUtf8Bytes))
{
longitude = ReadProperty(ref reader, options);
}
else if (longitudeSet && reader.ValueTextEquals(latitudeName.EncodedUtf8Bytes))
{
latitude = ReadProperty(ref reader, options);
}
else
{
throw new JsonException();
}
reader.Read();
if (reader.TokenType != JsonTokenType.EndObject)
{
throw new JsonException();
}
return new TwitterCoordinates
{
Latitude = latitude,
Longitude = longitude
};
return twitterCoordinates;
}
catch
{
@ -45,9 +101,15 @@ namespace Microsoft.Toolkit.Services.Twitter
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
private double ReadProperty(ref Utf8JsonReader reader, JsonSerializerOptions options)
{
reader.Read();
return doubleConverter.Read(ref reader, typeof(double), options);
}
public override void Write(Utf8JsonWriter writer, TwitterCoordinates value, JsonSerializerOptions options)
{
throw new NotImplementedException();
}
}
}
}

Просмотреть файл

@ -10,9 +10,9 @@ using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Toolkit.Services.Core;
using Newtonsoft.Json;
#if WINRT
using System.Runtime.InteropServices.WindowsRuntime;
@ -140,7 +140,7 @@ namespace Microsoft.Toolkit.Services.Twitter
TwitterOAuthRequest request = new TwitterOAuthRequest();
rawResult = await request.ExecuteGetAsync(uri, _tokens, _signatureManager);
return JsonConvert.DeserializeObject<TwitterUser>(rawResult);
return JsonSerializer.Deserialize<TwitterUser>(rawResult);
}
catch (UserNotFoundException)
{
@ -150,7 +150,7 @@ namespace Microsoft.Toolkit.Services.Twitter
{
if (!string.IsNullOrEmpty(rawResult))
{
var errors = JsonConvert.DeserializeObject<TwitterErrors>(rawResult);
var errors = JsonSerializer.Deserialize<TwitterErrors>(rawResult);
throw new TwitterException { Errors = errors };
}
@ -191,7 +191,7 @@ namespace Microsoft.Toolkit.Services.Twitter
{
if (!string.IsNullOrEmpty(rawResult))
{
var errors = JsonConvert.DeserializeObject<TwitterErrors>(rawResult);
var errors = JsonSerializer.Deserialize<TwitterErrors>(rawResult);
throw new TwitterException { Errors = errors };
}
@ -581,18 +581,16 @@ namespace Microsoft.Toolkit.Services.Twitter
using (var request = new HttpRequestMessage(HttpMethod.Get, new Uri(twitterUrl)))
{
using (var response = await _client.SendAsync(request).ConfigureAwait(false))
using var response = await _client.SendAsync(request).ConfigureAwait(false);
var data = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
var data = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
if (response.IsSuccessStatusCode)
{
getResponse = data;
}
else
{
Debug.WriteLine("HttpHelper call failed trying to retrieve Twitter Request Tokens. Message: {0}", data);
return false;
}
getResponse = data;
}
else
{
Debug.WriteLine("HttpHelper call failed trying to retrieve Twitter Request Tokens. Message: {0}", data);
return false;
}
}
@ -665,10 +663,8 @@ namespace Microsoft.Toolkit.Services.Twitter
{
request.Headers.Authorization = new AuthenticationHeaderValue("OAuth", authorizationHeaderParams);
using (var response = await _client.SendAsync(request).ConfigureAwait(false))
{
data = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
}
using var response = await _client.SendAsync(request).ConfigureAwait(false);
data = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
}
var screenName = ExtractTokenFromResponse(data, TwitterOAuthTokenType.ScreenName);

Просмотреть файл

@ -4,7 +4,7 @@
using System;
using System.Globalization;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -17,70 +17,70 @@ namespace Microsoft.Toolkit.Services.Twitter
/// Gets or sets the direct message id.
/// </summary>
/// <value>The direct message id.</value>
[JsonProperty(PropertyName = "id")]
[JsonPropertyName("id")]
public decimal Id { get; set; }
/// <summary>
/// Gets or sets the sender id.
/// </summary>
/// <value>The sender id.</value>
[JsonProperty(PropertyName = "sender_id")]
[JsonPropertyName("sender_id")]
public decimal SenderId { get; set; }
/// <summary>
/// Gets or sets the direct message text.
/// </summary>
/// <value>The direct message text.</value>
[JsonProperty(PropertyName = "text")]
[JsonPropertyName("text")]
public string Text { get; set; }
/// <summary>
/// Gets or sets the recipient id.
/// </summary>
/// <value>The recipient id.</value>
[JsonProperty(PropertyName = "recipient_id")]
[JsonPropertyName("recipient_id")]
public decimal RecipientId { get; set; }
/// <summary>
/// Gets or sets the created date.
/// </summary>
/// <value>The created date.</value>
[JsonProperty(PropertyName = "created_at")]
[JsonPropertyName("created_at")]
public string CreatedAt { get; set; }
/// <summary>
/// Gets or sets the name of the sender screen.
/// </summary>
/// <value>The name of the sender screen.</value>
[JsonProperty(PropertyName = "sender_screen_name")]
[JsonPropertyName("sender_screen_name")]
public string SenderScreenName { get; set; }
/// <summary>
/// Gets or sets the name of the recipient screen.
/// </summary>
/// <value>The name of the recipient screen.</value>
[JsonProperty(PropertyName = "recipient_screen_name")]
[JsonPropertyName("recipient_screen_name")]
public string RecipientScreenName { get; set; }
/// <summary>
/// Gets or sets the sender.
/// </summary>
/// <value>The sender.</value>
[JsonProperty(PropertyName = "sender")]
[JsonPropertyName("sender")]
public TwitterUser Sender { get; set; }
/// <summary>
/// Gets or sets the recipient.
/// </summary>
/// <value>The recipient.</value>
[JsonProperty(PropertyName = "recipient")]
[JsonPropertyName("recipient")]
public TwitterUser Recipient { get; set; }
/// <summary>
/// Gets or sets the entities.
/// </summary>
/// <value>The entities.</value>
[JsonProperty(PropertyName = "entities")]
[JsonPropertyName("entities")]
public TwitterEntities Entities { get; set; }
/// <summary>

Просмотреть файл

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -15,35 +15,35 @@ namespace Microsoft.Toolkit.Services.Twitter
/// Gets or sets Hashtags array of the tweet.
/// This array will be empty if no Hashtags are present.
/// </summary>
[JsonProperty("Hashtags")]
[JsonPropertyName("Hashtags")]
public TwitterHashtag[] Hashtags { get; set; }
/// <summary>
/// Gets or sets Symbols array of the tweet.
/// This array will be empty if no Symbols are present.
/// </summary>
[JsonProperty("Symbols")]
[JsonPropertyName("Symbols")]
public TwitterSymbol[] Symbols { get; set; }
/// <summary>
/// Gets or sets Media array of the tweet.
/// This array will not exist if no media is present.
/// </summary>
[JsonProperty("media")]
[JsonPropertyName("media")]
public TwitterMedia[] Media { get; set; }
/// <summary>
/// Gets or sets Urls array of the tweet.
/// This array will be empty if no Urls are present.
/// </summary>
[JsonProperty("urls")]
[JsonPropertyName("urls")]
public TwitterUrl[] Urls { get; set; }
/// <summary>
/// Gets or sets array of usernames mentioned in the tweet.
/// This array will be empty if no usernames are mentioned.
/// </summary>
[JsonProperty("user_mentions")]
[JsonPropertyName("user_mentions")]
public TwitterUserMention[] UserMentions { get; set; }
/// <summary>
@ -51,7 +51,7 @@ namespace Microsoft.Toolkit.Services.Twitter
/// This array will not exist if no poll is present.
/// This array will always have one poll.
/// </summary>
[JsonProperty("polls")]
[JsonPropertyName("polls")]
public TwitterPoll Poll { get; set; }
}
}

Просмотреть файл

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -14,13 +14,13 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <summary>
/// Gets or sets error code
/// </summary>
[JsonProperty("code")]
[JsonPropertyName("code")]
public int Code { get; set; }
/// <summary>
/// Gets or sets error message
/// </summary>
[JsonProperty("message")]
[JsonPropertyName("message")]
public string Message { get; set; }
}
}

Просмотреть файл

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -14,7 +14,7 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <summary>
/// Gets or sets the list of errors
/// </summary>
[JsonProperty("errors")]
[JsonPropertyName("errors")]
public TwitterError[] Errors { get; set; }
}
}

Просмотреть файл

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -14,7 +14,7 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <summary>
/// Gets or sets the text of the tweet (280 characters).
/// </summary>
[JsonProperty("full_text")]
[JsonPropertyName("full_text")]
public string FullText { get; set; }
}
}

Просмотреть файл

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -14,7 +14,7 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <summary>
/// Gets or sets Media of the tweet.
/// </summary>
[JsonProperty("media")]
[JsonPropertyName("media")]
public TwitterMedia[] Media { get; set; }
}
}

Просмотреть файл

@ -3,7 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Globalization;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -19,7 +19,7 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <summary>
/// Gets or sets the type of data
/// </summary>
[JsonProperty("type")]
[JsonPropertyName("type")]
public string DataType { get; set; }
/// <summary>
@ -43,7 +43,7 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <summary>
/// Gets or sets the coordinates of the geographic data
/// </summary>
[JsonProperty("coordinates")]
[JsonPropertyName("coordinates")]
public string[] Coordinates { get; set; }
/// <summary>

Просмотреть файл

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -14,13 +14,13 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <summary>
/// Gets or sets indices of hashtag location in tweet string.
/// </summary>
[JsonProperty("indices")]
[JsonPropertyName("indices")]
public int[] Indices { get; set; }
/// <summary>
/// Gets or sets hashtag text, excluding #.
/// </summary>
[JsonProperty("text")]
[JsonPropertyName("text")]
public string Text { get; set; }
}
}

Просмотреть файл

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -14,73 +14,73 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <summary>
/// Gets or sets ID as string.
/// </summary>
[JsonProperty("id_str")]
[JsonPropertyName("id_str")]
public string Id { get; set; }
/// <summary>
/// Gets or sets indices array.
/// </summary>
[JsonProperty("indices")]
[JsonPropertyName("indices")]
public int[] Indices { get; set; }
/// <summary>
/// Gets or sets MediaUrl (direct link to image).
/// </summary>
[JsonProperty("media_url")]
[JsonPropertyName("media_url")]
public string MediaUrl { get; set; }
/// <summary>
/// Gets or sets HTTPS MediaUrl.
/// </summary>
[JsonProperty("media_url_https")]
[JsonPropertyName("media_url_https")]
public string MediaUrlHttps { get; set; }
/// <summary>
/// Gets or sets t.co shortened tweet Url.
/// </summary>
[JsonProperty("url")]
[JsonPropertyName("url")]
public string Url { get; set; }
/// <summary>
/// Gets or sets DisplayUrl (pics.twitter.com Url).
/// </summary>
[JsonProperty("display_url")]
[JsonPropertyName("display_url")]
public string DisplayUrl { get; set; }
/// <summary>
/// Gets or sets DisplayUrl (pics.twitter.com Url).
/// </summary>
[JsonProperty("expanded_url")]
[JsonPropertyName("expanded_url")]
public string ExpandedUrl { get; set; }
/// <summary>
/// Gets or sets MediaType - photo, animated_gif, or video
/// </summary>
[JsonProperty("type")]
[JsonPropertyName("type")]
public string MediaType { get; set; }
/// <summary>
/// Gets or sets size array
/// </summary>
[JsonProperty("sizes")]
[JsonPropertyName("sizes")]
public TwitterMediaSizes Sizes { get; set; }
/// <summary>
/// Gets or sets the SourceId - tweet ID of media's original tweet
/// </summary>
[JsonProperty("source_status_id_str")]
[JsonPropertyName("source_status_id_str")]
public string SourceIdStr { get; set; }
/// <summary>
/// Gets or sets metadata for video attached to tweet
/// </summary>
[JsonProperty("video_info")]
[JsonPropertyName("video_info")]
public TwitterMediaVideoInfo VideoInfo { get; set; }
/// <summary>
/// Gets or sets extended metadata for video attached to tweet.
/// </summary>
[JsonProperty("additional_media_info")]
[JsonPropertyName("additional_media_info")]
public TwitterMediaAdditionalInfo AdditionalMediaInfo { get; set; }
}
}

Просмотреть файл

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -14,25 +14,25 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <summary>
/// Gets or sets title of video
/// </summary>
[JsonProperty("title")]
[JsonPropertyName("title")]
public string Title { get; set; }
/// <summary>
/// Gets or sets description of video
/// </summary>
[JsonProperty("description")]
[JsonPropertyName("description")]
public string Description { get; set; }
/// <summary>
/// Gets or sets a value indicating whether video is embeddable
/// </summary>
[JsonProperty("embeddable")]
[JsonPropertyName("embeddable")]
public bool Embeddable { get; set; }
/// <summary>
/// Gets or sets a value indicating whether "monetizable"
/// </summary>
[JsonProperty("monetizable")]
[JsonPropertyName("monetizable")]
public bool Monetizable { get; set; }
}
}

Просмотреть файл

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -14,19 +14,19 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <summary>
/// Gets or sets width integer.
/// </summary>
[JsonProperty("w")]
[JsonPropertyName("w")]
public int Width { get; set; }
/// <summary>
/// Gets or sets height integer.
/// </summary>
[JsonProperty("h")]
[JsonPropertyName("h")]
public int Height { get; set; }
/// <summary>
/// Gets or sets resize string.
/// </summary>
[JsonProperty("resize")]
[JsonPropertyName("resize")]
public string Resize { get; set; }
}
}

Просмотреть файл

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -14,25 +14,25 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <summary>
/// Gets or sets small metadata.
/// </summary>
[JsonProperty("small")]
[JsonPropertyName("small")]
public TwitterMediaSizeData Small { get; set; }
/// <summary>
/// Gets or sets thumbnail metadata.
/// </summary>
[JsonProperty("thumb")]
[JsonPropertyName("thumb")]
public TwitterMediaSizeData Thumb { get; set; }
/// <summary>
/// Gets or sets large metadata.
/// </summary>
[JsonProperty("large")]
[JsonPropertyName("large")]
public TwitterMediaSizeData Large { get; set; }
/// <summary>
/// Gets or sets medium metadata.
/// </summary>
[JsonProperty("medium")]
[JsonPropertyName("medium")]
public TwitterMediaSizeData Medium { get; set; }
}
}

Просмотреть файл

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -14,19 +14,19 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <summary>
/// Gets or sets video aspect ratio (width, height)
/// </summary>
[JsonProperty("aspect_ratio")]
[JsonPropertyName("aspect_ratio")]
public int[] AspectRatio { get; set; }
/// <summary>
/// Gets or sets duration of video in milliseconds
/// </summary>
[JsonProperty("duration_millis")]
[JsonPropertyName("duration_millis")]
public int Duration { get; set; }
/// <summary>
/// Gets or sets video variants for different codecs, bitrates, etc.
/// </summary>
[JsonProperty("variants")]
[JsonPropertyName("variants")]
public TwitterMediaVideoVariants[] Variants { get; set; }
}
}

Просмотреть файл

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -14,19 +14,19 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <summary>
/// Gets or sets video bitrate in bits-per-second
/// </summary>
[JsonProperty("bitrate")]
[JsonPropertyName("bitrate")]
public int Bitrate { get; set; }
/// <summary>
/// Gets or sets the MIME type of the video
/// </summary>
[JsonProperty("content_type")]
[JsonPropertyName("content_type")]
public string ContentType { get; set; }
/// <summary>
/// Gets or sets the direct URL for the video variant
/// </summary>
[JsonProperty("url")]
[JsonPropertyName("url")]
public string Url { get; set; }
}
}

Просмотреть файл

@ -8,10 +8,9 @@ using System.IO.Compression;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Toolkit.Services.Core;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -46,18 +45,14 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <returns>String result.</returns>
public async Task<string> ExecuteGetAsync(Uri requestUri, TwitterOAuthTokens tokens, ISignatureManager signatureManager)
{
using (var request = new HttpRequestMessage(HttpMethod.Get, requestUri))
{
var requestBuilder = new TwitterOAuthRequestBuilder(requestUri, tokens, signatureManager, "GET");
using var request = new HttpRequestMessage(HttpMethod.Get, requestUri);
var requestBuilder = new TwitterOAuthRequestBuilder(requestUri, tokens, signatureManager, "GET");
request.Headers.Authorization = AuthenticationHeaderValue.Parse(requestBuilder.AuthorizationHeader);
request.Headers.Authorization = AuthenticationHeaderValue.Parse(requestBuilder.AuthorizationHeader);
using (var response = await client.SendAsync(request).ConfigureAwait(false))
{
response.ThrowIfNotValid();
return ProcessErrors(await response.Content.ReadAsStringAsync().ConfigureAwait(false));
}
}
using var response = await client.SendAsync(request).ConfigureAwait(false);
response.ThrowIfNotValid();
return ProcessErrors(await response.Content.ReadAsStringAsync().ConfigureAwait(false));
}
/// <summary>
@ -70,29 +65,22 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <returns>awaitable task</returns>
public async Task ExecuteGetStreamAsync(Uri requestUri, TwitterOAuthTokens tokens, TwitterStreamCallbacks.RawJsonCallback callback, ISignatureManager signatureManager)
{
using (var request = new HttpRequestMessage(HttpMethod.Get, requestUri))
using var request = new HttpRequestMessage(HttpMethod.Get, requestUri);
var requestBuilder = new TwitterOAuthRequestBuilder(requestUri, tokens, signatureManager);
request.Headers.Authorization = AuthenticationHeaderValue.Parse(requestBuilder.AuthorizationHeader);
using var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
response.ThrowIfNotValid();
using var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
using var reader = new StreamReader(responseStream);
while (!_abort && !reader.EndOfStream)
{
var requestBuilder = new TwitterOAuthRequestBuilder(requestUri, tokens, signatureManager);
var result = reader.ReadLine();
request.Headers.Authorization = AuthenticationHeaderValue.Parse(requestBuilder.AuthorizationHeader);
using (var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false))
if (!string.IsNullOrEmpty(result))
{
response.ThrowIfNotValid();
var responseStream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
using (var reader = new StreamReader(responseStream))
{
while (!_abort && !reader.EndOfStream)
{
var result = reader.ReadLine();
if (!string.IsNullOrEmpty(result))
{
callback?.Invoke(result);
}
}
}
callback?.Invoke(result);
}
}
}
@ -114,18 +102,14 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <returns>String result.</returns>
public async Task<string> ExecutePostAsync(Uri requestUri, TwitterOAuthTokens tokens, ISignatureManager signatureManager)
{
using (var request = new HttpRequestMessage(HttpMethod.Post, requestUri))
{
var requestBuilder = new TwitterOAuthRequestBuilder(requestUri, tokens, signatureManager, "POST");
using var request = new HttpRequestMessage(HttpMethod.Post, requestUri);
var requestBuilder = new TwitterOAuthRequestBuilder(requestUri, tokens, signatureManager, "POST");
request.Headers.Authorization = AuthenticationHeaderValue.Parse(requestBuilder.AuthorizationHeader);
request.Headers.Authorization = AuthenticationHeaderValue.Parse(requestBuilder.AuthorizationHeader);
using (var response = await client.SendAsync(request).ConfigureAwait(false))
{
response.ThrowIfNotValid();
return ProcessErrors(await response.Content.ReadAsStringAsync().ConfigureAwait(false));
}
}
using var response = await client.SendAsync(request).ConfigureAwait(false);
response.ThrowIfNotValid();
return ProcessErrors(await response.Content.ReadAsStringAsync().ConfigureAwait(false));
}
/// <summary>
@ -139,35 +123,26 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <returns>String result.</returns>
public async Task<string> ExecutePostMultipartAsync(Uri requestUri, TwitterOAuthTokens tokens, string boundary, byte[] content, ISignatureManager signatureManager)
{
JToken mediaId = null;
JsonElement mediaId = default;
try
{
using (var multipartFormDataContent = new MultipartFormDataContent(boundary))
{
using (var byteContent = new ByteArrayContent(content))
{
multipartFormDataContent.Add(byteContent, "media");
using var multipartFormDataContent = new MultipartFormDataContent(boundary);
using var byteContent = new ByteArrayContent(content);
multipartFormDataContent.Add(byteContent, "media");
using (var request = new HttpRequestMessage(HttpMethod.Post, requestUri))
{
var requestBuilder = new TwitterOAuthRequestBuilder(requestUri, tokens, signatureManager, "POST");
using var request = new HttpRequestMessage(HttpMethod.Post, requestUri);
var requestBuilder = new TwitterOAuthRequestBuilder(requestUri, tokens, signatureManager, "POST");
request.Headers.Authorization = AuthenticationHeaderValue.Parse(requestBuilder.AuthorizationHeader);
request.Headers.Authorization = AuthenticationHeaderValue.Parse(requestBuilder.AuthorizationHeader);
request.Content = multipartFormDataContent;
request.Content = multipartFormDataContent;
using (var response = await client.SendAsync(request).ConfigureAwait(false))
{
response.ThrowIfNotValid();
string jsonResult = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
JObject jObj = JObject.Parse(jsonResult);
mediaId = jObj["media_id_string"];
}
}
}
}
using var response = await client.SendAsync(request).ConfigureAwait(false);
response.ThrowIfNotValid();
using var jsonResult = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
var jObj = await JsonDocument.ParseAsync(jsonResult).ConfigureAwait(false);
mediaId = jObj.RootElement.GetProperty("media_id_string");
}
catch (ObjectDisposedException)
{
@ -182,7 +157,7 @@ namespace Microsoft.Toolkit.Services.Twitter
{
if (content.StartsWith("{\"errors\":"))
{
var errors = JsonConvert.DeserializeObject<TwitterErrors>(content);
var errors = JsonSerializer.Deserialize<TwitterErrors>(content);
throw new TwitterException { Errors = errors };
}

Просмотреть файл

@ -2,16 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Microsoft.Toolkit.Services.Core;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Microsoft.Toolkit.Services.Twitter
{

Просмотреть файл

@ -3,7 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using Newtonsoft.Json;
using System.Text.Json;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -28,12 +28,12 @@ namespace Microsoft.Toolkit.Services.Twitter
try
{
return JsonConvert.DeserializeObject<List<T>>(data);
return JsonSerializer.Deserialize<List<T>>(data);
}
catch (JsonSerializationException)
catch (JsonException)
{
List<T> items = new List<T>();
items.Add(JsonConvert.DeserializeObject<T>(data));
items.Add(JsonSerializer.Deserialize<T>(data));
return items;
}
}

Просмотреть файл

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -14,49 +14,49 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <summary>
/// Gets or sets the ID of the place
/// </summary>
[JsonProperty("id")]
[JsonPropertyName("id")]
public string Id { get; set; }
/// <summary>
/// Gets or sets the URL of additional place metadata
/// </summary>
[JsonProperty("url")]
[JsonPropertyName("url")]
public string Url { get; set; }
/// <summary>
/// Gets or sets the place type.
/// </summary>
[JsonProperty("place_type")]
[JsonPropertyName("place_type")]
public string PlaceType { get; set; }
/// <summary>
/// Gets or sets the place name.
/// </summary>
[JsonProperty("name")]
[JsonPropertyName("name")]
public string Name { get; set; }
/// <summary>
/// Gets or sets the full, human-readable place name.
/// </summary>
[JsonProperty("full_name")]
[JsonPropertyName("full_name")]
public string FullName { get; set; }
/// <summary>
/// Gets or sets the shortened country code (e.g. US) for the place.
/// </summary>
[JsonProperty("country_code")]
[JsonPropertyName("country_code")]
public string CountryCode { get; set; }
/// <summary>
/// Gets or sets the name of the country for the place.
/// </summary>
[JsonProperty("country")]
[JsonPropertyName("country")]
public string Country { get; set; }
/// <summary>
/// Gets or sets the bounding box coordinates of a location.
/// </summary>
[JsonProperty("bounding_box")]
[JsonPropertyName("bounding_box")]
public TwitterPlaceBoundingBox BoundingBox { get; set; }
}
}

Просмотреть файл

@ -3,8 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using System.Globalization;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -16,13 +15,13 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <summary>
/// Gets or sets the bounding box coordinates of the tweet's geolocation data.
/// </summary>
[JsonProperty("coordinates")]
[JsonPropertyName("coordinates")]
public List<List<float[]>> Coordinates { get; set; }
/// <summary>
/// Gets or sets the coordinate type. Polygon for a bounding box, Point for an exact coordinate.
/// </summary>
[JsonProperty("type")]
[JsonPropertyName("type")]
public string Type { get; set; }
/// <summary>

Просмотреть файл

@ -4,7 +4,7 @@
using System;
using System.Globalization;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -16,19 +16,19 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <summary>
/// Gets or sets poll questions.
/// </summary>
[JsonProperty("options")]
[JsonPropertyName("options")]
public TwitterPollOptions[] Options { get; set; }
/// <summary>
/// Gets or sets end timestamp as a string.
/// </summary>
[JsonProperty("end_datetime")]
[JsonPropertyName("end_datetime")]
public string EndDateTime { get; set; }
/// <summary>
/// Gets or sets duration of the poll in minutes.
/// </summary>
[JsonProperty("duration_minutes")]
[JsonPropertyName("duration_minutes")]
public string DurationMinutes { get; set; }
/// <summary>

Просмотреть файл

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -14,13 +14,13 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <summary>
/// Gets or sets int value of the poll position.
/// </summary>
[JsonProperty("position")]
[JsonPropertyName("position")]
public int Position { get; set; }
/// <summary>
/// Gets or sets text of the poll question.
/// </summary>
[JsonProperty("text")]
[JsonPropertyName("text")]
public string Text { get; set; }
}
}

Просмотреть файл

@ -4,7 +4,7 @@
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
using System.Text.Json;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -25,7 +25,7 @@ namespace Microsoft.Toolkit.Services.Twitter
return null;
}
var result = JsonConvert.DeserializeObject<TwitterSearchResult>(data);
var result = JsonSerializer.Deserialize<TwitterSearchResult>(data);
return result.Statuses.ToList();
}

Просмотреть файл

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -15,14 +15,14 @@ namespace Microsoft.Toolkit.Services.Twitter
/// Gets or sets the user id of the event. This is always the user who initiated the event.
/// </summary>
/// <value>The user Id.</value>
[JsonProperty(PropertyName = "user_id_str")]
[JsonPropertyName("user_id_str")]
public string UserId { get; set; }
/// <summary>
/// Gets or sets the id of the event. This is the tweet that was affected.
/// </summary>
/// <value>The tweet Id.</value>
[JsonProperty(PropertyName = "id_str")]
[JsonPropertyName("id_str")]
public string Id { get; set; }
}
}

Просмотреть файл

@ -4,8 +4,7 @@
using System;
using System.Globalization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -18,8 +17,8 @@ namespace Microsoft.Toolkit.Services.Twitter
/// Gets or sets the type of the event.
/// </summary>
/// <value>The type of the event.</value>
[JsonProperty(PropertyName = "event")]
[JsonConverter(typeof(StringEnumConverter))]
[JsonPropertyName("event")]
[JsonConverter(typeof(JsonStringEnumConverter))]
public TwitterStreamEventType EventType { get; set; }
/// <summary>
@ -44,7 +43,7 @@ namespace Microsoft.Toolkit.Services.Twitter
/// Gets or sets the creation date.
/// </summary>
/// <value>The creation date.</value>
[JsonProperty(PropertyName = "created_at")]
[JsonPropertyName("created_at")]
public string CreatedAt { get; set; }
/// <summary>

Просмотреть файл

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -14,13 +14,13 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <summary>
/// Gets or sets indices of hashtag location in tweet string.
/// </summary>
[JsonProperty("indices")]
[JsonPropertyName("indices")]
public int[] Indices { get; set; }
/// <summary>
/// Gets or sets hashtag text, excluding #.
/// </summary>
[JsonProperty("text")]
[JsonPropertyName("text")]
public string Text { get; set; }
}
}

Просмотреть файл

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -14,31 +14,31 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <summary>
/// Gets or sets DisplayUrl of the Url.
/// </summary>
[JsonProperty("display_url")]
[JsonPropertyName("display_url")]
public string DisplayUrl { get; set; }
/// <summary>
/// Gets or sets ExpandedUrl of the Url.
/// </summary>
[JsonProperty("expanded_url")]
[JsonPropertyName("expanded_url")]
public string ExpandedUrl { get; set; }
/// <summary>
/// Gets or sets indices position of the tweet.
/// </summary>
[JsonProperty("indices")]
[JsonPropertyName("indices")]
public int[] Indices { get; set; }
/// <summary>
/// Gets or sets unwound Url metadata position of the tweet.
/// </summary>
[JsonProperty("unwound")]
[JsonPropertyName("unwound")]
public TwitterUrlUnwound Unwound { get; set; }
/// <summary>
/// Gets or sets t.co Url of the tweet.
/// </summary>
[JsonProperty("url")]
[JsonPropertyName("url")]
public string Url { get; set; }
}
}

Просмотреть файл

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -14,25 +14,25 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <summary>
/// Gets or sets fully unwound url.
/// </summary>
[JsonProperty("url")]
[JsonPropertyName("url")]
public string Url { get; set; }
/// <summary>
/// Gets or sets status of unwind; if anything but 200 is bad data.
/// </summary>
[JsonProperty("status")]
[JsonPropertyName("status")]
public int Status { get; set; }
/// <summary>
/// Gets or sets HTML title for url.
/// </summary>
[JsonProperty("title")]
[JsonPropertyName("title")]
public string Title { get; set; }
/// <summary>
/// Gets or sets description of link.
/// </summary>
[JsonProperty("description")]
[JsonPropertyName("description")]
public string Description { get; set; }
}
}

Просмотреть файл

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -14,194 +14,194 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <summary>
/// Gets or sets user Id.
/// </summary>
[JsonProperty("id_str")]
[JsonPropertyName("id_str")]
public string Id { get; set; }
/// <summary>
/// Gets or sets user name.
/// </summary>
[JsonProperty("name")]
[JsonPropertyName("name")]
public string Name { get; set; }
/// <summary>
/// Gets or sets user screen name.
/// </summary>
[JsonProperty("screen_name")]
[JsonPropertyName("screen_name")]
public string ScreenName { get; set; }
/// <summary>
/// Gets or sets profile location.
/// </summary>
[JsonProperty("location")]
[JsonPropertyName("location")]
public string Location { get; set; }
/// <summary>
/// Gets or sets profile url.
/// </summary>
[JsonProperty("url")]
[JsonPropertyName("url")]
public string Url { get; set; }
/// <summary>
/// Gets or sets profile description.
/// </summary>
[JsonProperty("description")]
[JsonPropertyName("description")]
public string Description { get; set; }
/// <summary>
/// Gets or sets a value indicating whether protected status of user.
/// </summary>
[JsonProperty("protected")]
[JsonPropertyName("protected")]
public bool Protected { get; set; }
/// <summary>
/// Gets or sets a value indicating whether account is verified (blue check mark).
/// </summary>
[JsonProperty("verified")]
[JsonPropertyName("verified")]
public bool Verified { get; set; }
/// <summary>
/// Gets or sets followers count.
/// </summary>
[JsonProperty("followers_count")]
[JsonPropertyName("followers_count")]
public int FollowersCount { get; set; }
/// <summary>
/// Gets or sets count of accounts user is following.
/// </summary>
[JsonProperty("friends_count")]
[JsonPropertyName("friends_count")]
public int FriendsCount { get; set; }
/// <summary>
/// Gets or sets count of public lists user is a member of.
/// </summary>
[JsonProperty("listed_count")]
[JsonPropertyName("listed_count")]
public int ListedCount { get; set; }
/// <summary>
/// Gets or sets total count of tweets user has liked.
/// </summary>
[JsonProperty("favourites_count")]
[JsonPropertyName("favourites_count")]
public int FavoritesCount { get; set; }
/// <summary>
/// Gets or sets total count of tweets (including retweets) posted by user.
/// </summary>
[JsonProperty("statuses_count")]
[JsonPropertyName("statuses_count")]
public int StatusesCount { get; set; }
/// <summary>
/// Gets or sets a value indicating whether geotagging is enabled.
/// This determines whether or not to geotag the user's posts.
/// </summary>
[JsonProperty("geo_enabled")]
[JsonPropertyName("geo_enabled")]
public bool GeoEnabled { get; set; }
/// <summary>
/// Gets or sets BCP 47 language code according to user's account settings.
/// </summary>
[JsonProperty("lang")]
[JsonPropertyName("lang")]
public string Lang { get; set; }
/// <summary>
/// Gets or sets a value indicating whether contributor mode is enabled.
/// </summary>
[JsonProperty("contributors_enabled")]
[JsonPropertyName("contributors_enabled")]
public bool ContributorsEnabled { get; set; }
/// <summary>
/// Gets or sets profile background color (web hex value).
/// </summary>
[JsonProperty("profile_background_color")]
[JsonPropertyName("profile_background_color")]
public string ProfileBackgroundColor { get; set; }
/// <summary>
/// Gets or sets profile background image url.
/// </summary>
[JsonProperty("profile_background_image_url")]
[JsonPropertyName("profile_background_image_url")]
public string ProfileBackgroundImageUrl { get; set; }
/// <summary>
/// Gets or sets profile background image url using https.
/// </summary>
[JsonProperty("profile_background_image_url_https")]
[JsonPropertyName("profile_background_image_url_https")]
public string ProfileBackgroundImageUrlHttps { get; set; }
/// <summary>
/// Gets or sets a value indicating whether profile background image is tiled.
/// </summary>
[JsonProperty("profile_background_tile")]
[JsonPropertyName("profile_background_tile")]
public bool ProfileBackgroundTile { get; set; }
/// <summary>
/// Gets or sets profile banner url.
/// </summary>
[JsonProperty("profile_banner_url")]
[JsonPropertyName("profile_banner_url")]
public string ProfileBannerUrl { get; set; }
/// <summary>
/// Gets or sets profile image url.
/// </summary>
[JsonProperty("profile_image_url")]
[JsonPropertyName("profile_image_url")]
public string ProfileImageUrl { get; set; }
/// <summary>
/// Gets or sets profile image url using https.
/// </summary>
[JsonProperty("profile_image_url_https")]
[JsonPropertyName("profile_image_url_https")]
public string ProfileImageUrlHttps { get; set; }
/// <summary>
/// Gets or sets profile link color (web hex value).
/// </summary>
[JsonProperty("profile_link_color")]
[JsonPropertyName("profile_link_color")]
public string ProfileLinkColor { get; set; }
/// <summary>
/// Gets or sets profile sidebar border color (web hex value).
/// </summary>
[JsonProperty("profile_sidebar_border_color")]
[JsonPropertyName("profile_sidebar_border_color")]
public string ProfileSidebarBorderColor { get; set; }
/// <summary>
/// Gets or sets profile sidebar fill color (web hex value).
/// </summary>
[JsonProperty("profile_sidebar_fill_color")]
[JsonPropertyName("profile_sidebar_fill_color")]
public string ProfileSidebarFillColor { get; set; }
/// <summary>
/// Gets or sets profile text color (web hex value).
/// </summary>
[JsonProperty("profile_text_color")]
[JsonPropertyName("profile_text_color")]
public string ProfileTextColor { get; set; }
/// <summary>
/// Gets or sets a value indicating whether the user has selected to use their uploaded background image in their profile.
/// </summary>
[JsonProperty("profile_use_background_image")]
[JsonPropertyName("profile_use_background_image")]
public bool ProfileUseBackgroundImage { get; set; }
/// <summary>
/// Gets or sets a value indicating whether or not user is using the default profile theme and background.
/// </summary>
[JsonProperty("default_profile")]
[JsonPropertyName("default_profile")]
public bool DefaultProfile { get; set; }
/// <summary>
/// Gets or sets a value indicating whether or not the user is using the default profile image.
/// </summary>
[JsonProperty("default_profile_image")]
[JsonPropertyName("default_profile_image")]
public bool DefaultProfileImage { get; set; }
/// <summary>
/// Gets or sets "withheld in" countries.
/// </summary>
[JsonProperty("withheld_in_countries")]
[JsonPropertyName("withheld_in_countries")]
public string[] WithheldInCountries { get; set; }
/// <summary>
/// Gets or sets withheld scope (status or profile).
/// </summary>
[JsonProperty("withheld_scope")]
[JsonPropertyName("withheld_scope")]
public string WithheldScope { get; set; }
}
}

Просмотреть файл

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -14,7 +14,7 @@ namespace Microsoft.Toolkit.Services.Twitter
/// <summary>
/// Gets or sets the start and end position of the user mention
/// </summary>
[JsonProperty("indices")]
[JsonPropertyName("indices")]
public int[] Indices { get; set; }
}
}

Просмотреть файл

@ -2,8 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Text.Json;
namespace Microsoft.Toolkit.Services.Twitter
{
@ -24,55 +23,47 @@ namespace Microsoft.Toolkit.Services.Twitter
return null;
}
var obj = (JObject)JsonConvert.DeserializeObject(data);
var obj = JsonDocument.Parse(data);
var friends = obj.SelectToken("friends", false);
if (friends != null && friends.HasValues)
if (obj.RootElement.TryGetProperty("friends", out var friends) && friends.GetArrayLength() > 0)
{
return null;
}
var delete = obj.SelectToken("delete", false);
if (delete != null)
if (obj.RootElement.TryGetProperty("delete", out var delete))
{
var deletedStatus = delete.SelectToken("status", false);
if (deletedStatus != null && deletedStatus.HasValues)
if (delete.TryGetProperty("status", out var deletedStatus) && deletedStatus.GetArrayLength() > 0)
{
return JsonConvert.DeserializeObject<TwitterStreamDeletedEvent>(deletedStatus.ToString());
return JsonSerializer.Deserialize<TwitterStreamDeletedEvent>(deletedStatus.ToString());
}
var deletedDirectMessage = delete.SelectToken("direct_message", false);
if (deletedDirectMessage != null && deletedDirectMessage.HasValues)
if (delete.TryGetProperty("direct_message", out var deletedDirectMessage) && deletedDirectMessage.GetArrayLength() > 0)
{
return JsonConvert.DeserializeObject<TwitterStreamDeletedEvent>(deletedDirectMessage.ToString());
return JsonSerializer.Deserialize<TwitterStreamDeletedEvent>(deletedDirectMessage.ToString());
}
}
var events = obj.SelectToken("event", false);
if (events != null)
if (obj.RootElement.TryGetProperty("event", out var events))
{
var targetObject = obj.SelectToken("target_object", false);
Tweet endTargetObject = null;
if (targetObject?.SelectToken("user", false) != null)
if (obj.RootElement.TryGetProperty("target_object", out var targetObject) && targetObject.TryGetProperty("user", out _))
{
endTargetObject = JsonConvert.DeserializeObject<Tweet>(targetObject.ToString());
endTargetObject = JsonSerializer.Deserialize<Tweet>(targetObject.ToString());
}
var endEvent = JsonConvert.DeserializeObject<TwitterStreamEvent>(obj.ToString());
var endEvent = JsonSerializer.Deserialize<TwitterStreamEvent>(obj.ToString());
endEvent.TargetObject = endTargetObject;
return endEvent;
}
var user = obj.SelectToken("user", false);
if (user != null && user.HasValues)
if (obj.RootElement.TryGetProperty("user", out var user) && user.GetArrayLength() > 0)
{
return JsonConvert.DeserializeObject<Tweet>(obj.ToString());
return JsonSerializer.Deserialize<Tweet>(obj.ToString());
}
var directMessage = obj.SelectToken("direct_message", false);
if (directMessage != null && directMessage.HasValues)
if (obj.RootElement.TryGetProperty("direct_message", out var directMessage) && directMessage.GetArrayLength() > 0)
{
return JsonConvert.DeserializeObject<TwitterDirectMessage>(directMessage.ToString());
return JsonSerializer.Deserialize<TwitterDirectMessage>(directMessage.ToString());
}
return null;

Просмотреть файл

@ -8,12 +8,11 @@ using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Toolkit.Parsers;
using Microsoft.Toolkit.Services.Core;
using Microsoft.Toolkit.Services.OAuth;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
#if WINRT
using System.Runtime.InteropServices.WindowsRuntime;
@ -224,15 +223,15 @@ namespace Microsoft.Toolkit.Services.Weibo
data = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
}
JObject jObject = JObject.Parse(data);
var jObject = JsonDocument.Parse(data);
string accessToken = jObject["access_token"].ToObject<string>();
string accessToken = jObject.RootElement.GetProperty("access_token").GetString();
if (string.IsNullOrEmpty(accessToken))
{
throw new NullReferenceException("The accessToken is null.");
}
long uid = jObject["uid"].ToObject<long>();
long uid = jObject.RootElement.GetProperty("uid").GetInt64();
Uid = uid;
_tokens.AccessToken = accessToken;
@ -265,7 +264,7 @@ namespace Microsoft.Toolkit.Services.Weibo
WeiboOAuthRequest request = new WeiboOAuthRequest();
rawResult = await request.ExecuteGetAsync(uri, _tokens);
return JsonConvert.DeserializeObject<WeiboUser>(rawResult);
return JsonSerializer.Deserialize<WeiboUser>(rawResult);
}
catch (UserNotFoundException)
{
@ -275,7 +274,7 @@ namespace Microsoft.Toolkit.Services.Weibo
{
if (!string.IsNullOrEmpty(rawResult))
{
var error = JsonConvert.DeserializeObject<WeiboError>(rawResult);
var error = JsonSerializer.Deserialize<WeiboError>(rawResult);
throw new WeiboException { Error = error };
}
@ -316,7 +315,7 @@ namespace Microsoft.Toolkit.Services.Weibo
{
if (!string.IsNullOrEmpty(rawResult))
{
var errors = JsonConvert.DeserializeObject<WeiboError>(rawResult);
var errors = JsonSerializer.Deserialize<WeiboError>(rawResult);
throw new WeiboException { Error = errors };
}

Просмотреть файл

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Weibo
{
@ -14,13 +14,13 @@ namespace Microsoft.Toolkit.Services.Weibo
/// <summary>
/// Gets or sets error code
/// </summary>
[JsonProperty("error_code")]
[JsonPropertyName("error_code")]
public int Code { get; set; }
/// <summary>
/// Gets or sets error message
/// </summary>
[JsonProperty("error")]
[JsonPropertyName("error")]
public string Message { get; set; }
}
}

Просмотреть файл

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Services.Weibo
{
@ -14,13 +14,13 @@ namespace Microsoft.Toolkit.Services.Services.Weibo
/// <summary>
/// Gets the type of geographic information
/// </summary>
[JsonProperty("type")]
[JsonPropertyName("type")]
public string Type { get; internal set; }
/// <summary>
/// Gets the coordinates
/// </summary>
[JsonProperty("coordinates")]
[JsonPropertyName("coordinates")]
public double[] Coordinates { get; internal set; }
/// <inheritdoc/>

Просмотреть файл

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Weibo
{
@ -14,19 +14,19 @@ namespace Microsoft.Toolkit.Services.Weibo
/// <summary>
/// Gets or sets the url of the attached image in thumbnail size.
/// </summary>
[JsonProperty("thumbnail_pic")]
[JsonPropertyName("thumbnail_pic")]
public string ThumbnailImageUrl { get; set; }
/// <summary>
/// Gets or sets the url of the attached image in medium size.
/// </summary>
[JsonProperty("bmiddle_pic")]
[JsonPropertyName("bmiddle_pic")]
public string MediumImageUrl { get; set; }
/// <summary>
/// Gets or sets the url of the attached image in original size.
/// </summary>
[JsonProperty("original_pic")]
[JsonPropertyName("original_pic")]
public string OriginalImageUrl { get; set; }
}
}

Просмотреть файл

@ -7,9 +7,9 @@ using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Toolkit.Services.OAuth;
using Newtonsoft.Json;
namespace Microsoft.Toolkit.Services.Weibo
{
@ -41,26 +41,22 @@ namespace Microsoft.Toolkit.Services.Weibo
/// <returns>String result.</returns>
public async Task<string> ExecuteGetAsync(Uri requestUri, WeiboOAuthTokens tokens)
{
using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUri))
using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUri);
UriBuilder requestUriBuilder = new UriBuilder(request.RequestUri);
if (requestUriBuilder.Query.StartsWith("?"))
{
UriBuilder requestUriBuilder = new UriBuilder(request.RequestUri);
if (requestUriBuilder.Query.StartsWith("?"))
{
requestUriBuilder.Query = requestUriBuilder.Query.Substring(1) + "&access_token=" + OAuthEncoder.UrlEncode(tokens.AccessToken);
}
else
{
requestUriBuilder.Query = requestUriBuilder.Query + "?access_token=" + OAuthEncoder.UrlEncode(tokens.AccessToken);
}
request.RequestUri = requestUriBuilder.Uri;
using (HttpResponseMessage response = await _client.SendAsync(request).ConfigureAwait(false))
{
response.ThrowIfNotValid();
return ProcessError(await response.Content.ReadAsStringAsync().ConfigureAwait(false));
}
requestUriBuilder.Query = requestUriBuilder.Query.Substring(1) + "&access_token=" + OAuthEncoder.UrlEncode(tokens.AccessToken);
}
else
{
requestUriBuilder.Query = requestUriBuilder.Query + "?access_token=" + OAuthEncoder.UrlEncode(tokens.AccessToken);
}
request.RequestUri = requestUriBuilder.Uri;
using HttpResponseMessage response = await _client.SendAsync(request).ConfigureAwait(false);
response.ThrowIfNotValid();
return ProcessError(await response.Content.ReadAsStringAsync().ConfigureAwait(false));
}
/// <summary>
@ -75,38 +71,33 @@ namespace Microsoft.Toolkit.Services.Weibo
var contentDict = new Dictionary<string, string>();
contentDict.Add("status", status);
using (var formUrlEncodedContent = new FormUrlEncodedContent(contentDict))
using var formUrlEncodedContent = new FormUrlEncodedContent(contentDict);
using var request = new HttpRequestMessage(HttpMethod.Post, requestUri);
UriBuilder requestUriBuilder = new UriBuilder(request.RequestUri);
if (requestUriBuilder.Query.StartsWith("?"))
{
using (var request = new HttpRequestMessage(HttpMethod.Post, requestUri))
{
UriBuilder requestUriBuilder = new UriBuilder(request.RequestUri);
if (requestUriBuilder.Query.StartsWith("?"))
{
requestUriBuilder.Query = requestUriBuilder.Query.Substring(1) + "&access_token=" + OAuthEncoder.UrlEncode(tokens.AccessToken);
}
else
{
requestUriBuilder.Query = requestUriBuilder.Query + "access_token=" + OAuthEncoder.UrlEncode(tokens.AccessToken);
}
requestUriBuilder.Query = requestUriBuilder.Query.Substring(1) + "&access_token=" + OAuthEncoder.UrlEncode(tokens.AccessToken);
}
else
{
requestUriBuilder.Query = requestUriBuilder.Query + "access_token=" + OAuthEncoder.UrlEncode(tokens.AccessToken);
}
request.RequestUri = requestUriBuilder.Uri;
request.RequestUri = requestUriBuilder.Uri;
request.Content = formUrlEncodedContent;
request.Content = formUrlEncodedContent;
using (var response = await _client.SendAsync(request).ConfigureAwait(false))
{
if (response.StatusCode == HttpStatusCode.OK)
{
return JsonConvert.DeserializeObject<WeiboStatus>(await response.Content.ReadAsStringAsync().ConfigureAwait(false));
}
else
{
response.ThrowIfNotValid();
ProcessError(await response.Content.ReadAsStringAsync().ConfigureAwait(false));
return null;
}
}
}
using var response = await _client.SendAsync(request).ConfigureAwait(false);
if (response.StatusCode == HttpStatusCode.OK)
{
using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
return await JsonSerializer.DeserializeAsync<WeiboStatus>(stream).ConfigureAwait(false);
}
else
{
response.ThrowIfNotValid();
ProcessError(await response.Content.ReadAsStringAsync().ConfigureAwait(false));
return null;
}
}
@ -122,49 +113,41 @@ namespace Microsoft.Toolkit.Services.Weibo
{
try
{
using (var multipartFormDataContent = new MultipartFormDataContent())
using var multipartFormDataContent = new MultipartFormDataContent();
using var stringContent = new StringContent(status);
multipartFormDataContent.Add(stringContent, "status");
using var byteContent = new ByteArrayContent(content);
// Somehow Weibo's backend requires a Filename field to work
byteContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { FileName = "attachment", Name = "pic" };
multipartFormDataContent.Add(byteContent, "pic");
using var request = new HttpRequestMessage(HttpMethod.Post, requestUri);
UriBuilder requestUriBuilder = new UriBuilder(request.RequestUri);
if (requestUriBuilder.Query.StartsWith("?"))
{
using (var stringContent = new StringContent(status))
{
multipartFormDataContent.Add(stringContent, "status");
using (var byteContent = new ByteArrayContent(content))
{
// Somehow Weibo's backend requires a Filename field to work
byteContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data") { FileName = "attachment", Name = "pic" };
multipartFormDataContent.Add(byteContent, "pic");
requestUriBuilder.Query = requestUriBuilder.Query.Substring(1) + "&access_token=" + OAuthEncoder.UrlEncode(tokens.AccessToken);
}
else
{
requestUriBuilder.Query = requestUriBuilder.Query + "access_token=" + OAuthEncoder.UrlEncode(tokens.AccessToken);
}
using (var request = new HttpRequestMessage(HttpMethod.Post, requestUri))
{
UriBuilder requestUriBuilder = new UriBuilder(request.RequestUri);
if (requestUriBuilder.Query.StartsWith("?"))
{
requestUriBuilder.Query = requestUriBuilder.Query.Substring(1) + "&access_token=" + OAuthEncoder.UrlEncode(tokens.AccessToken);
}
else
{
requestUriBuilder.Query = requestUriBuilder.Query + "access_token=" + OAuthEncoder.UrlEncode(tokens.AccessToken);
}
request.RequestUri = requestUriBuilder.Uri;
request.RequestUri = requestUriBuilder.Uri;
request.Content = multipartFormDataContent;
request.Content = multipartFormDataContent;
using (var response = await _client.SendAsync(request).ConfigureAwait(false))
{
if (response.StatusCode == HttpStatusCode.OK)
{
return JsonConvert.DeserializeObject<WeiboStatus>(await response.Content.ReadAsStringAsync().ConfigureAwait(false));
}
else
{
response.ThrowIfNotValid();
ProcessError(await response.Content.ReadAsStringAsync().ConfigureAwait(false));
return null;
}
}
}
}
}
using var response = await _client.SendAsync(request).ConfigureAwait(false);
if (response.StatusCode == HttpStatusCode.OK)
{
using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
return await JsonSerializer.DeserializeAsync<WeiboStatus>(stream).ConfigureAwait(false);
}
else
{
response.ThrowIfNotValid();
ProcessError(await response.Content.ReadAsStringAsync().ConfigureAwait(false));
return null;
}
}
catch (ObjectDisposedException)
@ -180,10 +163,15 @@ namespace Microsoft.Toolkit.Services.Weibo
{
if (content.StartsWith("{\"error\":"))
{
WeiboError error = JsonConvert.DeserializeObject<WeiboError>(content, new JsonSerializerSettings()
WeiboError error;
try
{
Error = (sender, args) => throw new JsonException("Invalid Weibo error response!", args.ErrorContext.Error)
});
error = JsonSerializer.Deserialize<WeiboError>(content);
}
catch (JsonException e)
{
throw new JsonException("Invalid Weibo error response!", e);
}
throw new WeiboException { Error = error };
}

Просмотреть файл

@ -2,16 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Microsoft.Toolkit.Services.Core;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Microsoft.Toolkit.Services.Weibo
{

Просмотреть файл

@ -3,7 +3,7 @@
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
using Newtonsoft.Json;
using System.Text.Json;
namespace Microsoft.Toolkit.Services.Weibo
{
@ -28,12 +28,12 @@ namespace Microsoft.Toolkit.Services.Weibo
try
{
return JsonConvert.DeserializeObject<List<T>>(data);
return JsonSerializer.Deserialize<List<T>>(data);
}
catch (JsonSerializationException)
catch (JsonException)
{
List<T> items = new List<T>();
items.Add(JsonConvert.DeserializeObject<T>(data));
items.Add(JsonSerializer.Deserialize<T>(data));
return items;
}
}

Просмотреть файл

@ -4,8 +4,8 @@
using System;
using System.Globalization;
using System.Text.Json.Serialization;
using Microsoft.Toolkit.Services.Services.Weibo;
using Newtonsoft.Json;
namespace Microsoft.Toolkit.Services.Weibo
{
@ -17,7 +17,7 @@ namespace Microsoft.Toolkit.Services.Weibo
/// <summary>
/// Gets or sets time item was created.
/// </summary>
[JsonProperty("created_at")]
[JsonPropertyName("created_at")]
public string CreatedAt { get; set; }
/// <summary>
@ -40,13 +40,13 @@ namespace Microsoft.Toolkit.Services.Weibo
/// <summary>
/// Gets or sets item Id.
/// </summary>
[JsonProperty("id")]
[JsonPropertyName("id")]
public string Id { get; set; }
/// <summary>
/// Gets or sets text of the status (handles both 140 and 280 characters)
/// </summary>
[JsonProperty("text")]
[JsonPropertyName("text")]
public string Text { get; set; }
/// <summary>
@ -54,85 +54,85 @@ namespace Microsoft.Toolkit.Services.Weibo
/// (true when Weibo status is longer than 140 characters)
/// This entity may be deprecated - it never seems to be set to true.
/// </summary>
[JsonProperty("truncated")]
[JsonPropertyName("truncated")]
public bool IsTruncated { get; set; }
/// <summary>
/// Gets or sets status source (client or website used)
/// </summary>
[JsonProperty("source")]
[JsonPropertyName("source")]
public string Source { get; set; }
/// <summary>
/// Gets or sets in_reply_to_screen_name
/// </summary>
[JsonProperty("in_reply_to_screen_name")]
[JsonPropertyName("in_reply_to_screen_name")]
public string InReplyToScreenName { get; set; }
/// <summary>
/// Gets or sets in_reply_to_status_id
/// </summary>
[JsonProperty("in_reply_to_status_id")]
[JsonPropertyName("in_reply_to_status_id")]
public string InReplyToStatusId { get; set; }
/// <summary>
/// Gets or sets in_reply_to_user_id
/// </summary>
[JsonProperty("in_reply_to_user_id")]
[JsonPropertyName("in_reply_to_user_id")]
public string InReplyToUserId { get; set; }
/// <summary>
/// Gets or sets user who posted the status.
/// </summary>
[JsonProperty("user")]
[JsonPropertyName("user")]
public WeiboUser User { get; set; }
/// <summary>
/// Gets or sets the Reposted Weibo status
/// </summary>
[JsonProperty("retweeted_status")]
[JsonPropertyName("retweeted_status")]
public WeiboStatus RepostedStatus { get; set; }
/// <summary>
/// Gets or sets the repost count
/// </summary>
[JsonProperty("reposts_count")]
[JsonPropertyName("reposts_count")]
public int RepostCount { get; set; }
/// <summary>
/// Gets or sets the comment count
/// </summary>
[JsonProperty("comments_count")]
[JsonPropertyName("comments_count")]
public int CommentCount { get; set; }
/// <summary>
/// Gets or sets the url of the attached image in thumbnail size.
/// </summary>
[JsonProperty("thumbnail_pic")]
[JsonPropertyName("thumbnail_pic")]
public string ThumbnailImageUrl { get; set; }
/// <summary>
/// Gets or sets the url of the attached image in medium size.
/// </summary>
[JsonProperty("bmiddle_pic")]
[JsonPropertyName("bmiddle_pic")]
public string MediumImageUrl { get; set; }
/// <summary>
/// Gets or sets the url of the attached image in original size.
/// </summary>
[JsonProperty("original_pic")]
[JsonPropertyName("original_pic")]
public string OriginalImageUrl { get; set; }
/// <summary>
/// Gets or sets attached images array of the weibo.
/// </summary>
[JsonProperty("pic_urls")]
[JsonPropertyName("pic_urls")]
public WeiboImage[] AttachedImages { get; set; }
/// <summary>
/// Gets or sets the geographic information.
/// </summary>
[JsonProperty("geo")]
[JsonPropertyName("geo")]
public WeiboGeoInfo GeographicInfo { get; set; }
/// <summary>

Просмотреть файл

@ -2,14 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Toolkit.Services.Weibo;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Text.Json;
namespace Microsoft.Toolkit.Services.Weibo
{
@ -30,14 +24,14 @@ namespace Microsoft.Toolkit.Services.Weibo
return null;
}
JObject rawObject = JObject.Parse(data);
var rawObject = JsonDocument.Parse(data);
IList<JToken> rawStatuses = rawObject["statuses"].Children().ToList();
var rawStatuses = rawObject.RootElement.GetProperty("statuses");
IList<WeiboStatus> statuses = new List<WeiboStatus>();
foreach (JToken result in rawStatuses)
foreach (var rawStatus in rawStatuses.EnumerateArray())
{
WeiboStatus searchResult = result.ToObject<WeiboStatus>();
WeiboStatus searchResult = JsonSerializer.Deserialize<WeiboStatus>(rawStatus.ToString());
statuses.Add(searchResult);
}

Просмотреть файл

@ -2,7 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Services.Weibo
{
@ -14,79 +14,79 @@ namespace Microsoft.Toolkit.Services.Weibo
/// <summary>
/// Gets or sets user Id.
/// </summary>
[JsonProperty("id")]
[JsonPropertyName("id")]
public string Id { get; set; }
/// <summary>
/// Gets or sets user name.
/// </summary>
[JsonProperty("name")]
[JsonPropertyName("name")]
public string Name { get; set; }
/// <summary>
/// Gets or sets user screen name.
/// </summary>
[JsonProperty("screen_name")]
[JsonPropertyName("screen_name")]
public string ScreenName { get; set; }
/// <summary>
/// Gets or sets profile location.
/// </summary>
[JsonProperty("location")]
[JsonPropertyName("location")]
public string Location { get; set; }
/// <summary>
/// Gets or sets profile url.
/// </summary>
[JsonProperty("url")]
[JsonPropertyName("url")]
public string Url { get; set; }
/// <summary>
/// Gets or sets profile description.
/// </summary>
[JsonProperty("description")]
[JsonPropertyName("description")]
public string Description { get; set; }
/// <summary>
/// Gets or sets profile image url.
/// </summary>
[JsonProperty("profile_image_url")]
[JsonPropertyName("profile_image_url")]
public string ProfileImageUrl { get; set; }
/// <summary>
/// Gets or sets high resolution profile image url.
/// </summary>
[JsonProperty("avatar_large")]
[JsonPropertyName("avatar_large")]
public string HighResolutionProfileImageUrl { get; set; }
/// <summary>
/// Gets or sets followers count.
/// </summary>
[JsonProperty("followers_count")]
[JsonPropertyName("followers_count")]
public int FollowersCount { get; set; }
/// <summary>
/// Gets or sets count of accounts user is following.
/// </summary>
[JsonProperty("friends_count")]
[JsonPropertyName("friends_count")]
public int FriendsCount { get; set; }
/// <summary>
/// Gets or sets total count of statuses user has liked.
/// </summary>
[JsonProperty("favourites_count")]
[JsonPropertyName("favourites_count")]
public int FavoritesCount { get; set; }
/// <summary>
/// Gets or sets total count of Weibo statuses (including reposted statuses) posted by user.
/// </summary>
[JsonProperty("statuses_count")]
[JsonPropertyName("statuses_count")]
public int StatusesCount { get; set; }
/// <summary>
/// Gets or sets a value indicating whether account is verified (blue check mark).
/// </summary>
[JsonProperty("verified")]
[JsonPropertyName("verified")]
public bool Verified { get; set; }
}
}

Просмотреть файл

@ -5,8 +5,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Windows.Web.Http;
namespace Microsoft.Toolkit.Uwp.SampleApp.Data
@ -31,7 +31,7 @@ namespace Microsoft.Toolkit.Uwp.SampleApp.Data
var uri = $"{_root}/repos/{_repoOwner}/{_repoName}/releases";
var result = await client.GetStringAsync(new Uri(uri));
_releases = JsonConvert.DeserializeObject<List<GitHubRelease>>(result).Take(5).ToList();
_releases = JsonSerializer.Deserialize<List<GitHubRelease>>(result).Take(5).ToList();
}
}
catch (Exception)

Просмотреть файл

@ -7,8 +7,8 @@ using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.Xaml.Data;
@ -88,7 +88,7 @@ namespace Microsoft.Toolkit.Uwp.SampleApp.Data
private static IEnumerable<PhotoDataItem> Parse(string jsonData)
{
return JsonConvert.DeserializeObject<IList<PhotoDataItem>>(jsonData);
return JsonSerializer.Deserialize<IList<PhotoDataItem>>(jsonData);
}
private static void CheckCacheState(bool online)

Просмотреть файл

@ -124,8 +124,8 @@
<PackageReference Include="Microsoft.Xaml.Behaviors.Uwp.Managed">
<Version>2.0.1</Version>
</PackageReference>
<PackageReference Include="Newtonsoft.Json">
<Version>10.0.3</Version>
<PackageReference Include="System.Text.Json">
<Version>4.7.2</Version>
</PackageReference>
<PackageReference Include="NotificationsVisualizerLibrary">
<Version>1.0.5</Version>

Просмотреть файл

@ -3,30 +3,30 @@
// See the LICENSE file in the project root for more information.
using System;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Uwp.SampleApp
{
public class GitHubRelease
{
[JsonProperty("published_at")]
[JsonPropertyName("published_at")]
public DateTime Published { get; set; }
[JsonProperty("body")]
[JsonPropertyName("body")]
public string Body { get; set; }
[JsonProperty("tag_name")]
[JsonPropertyName("tag_name")]
public string Tag { get; set; }
[JsonProperty("name")]
[JsonPropertyName("name")]
public string Name { get; set; }
public string FullName => $"Version {Name.Replace("v", string.Empty)} notes";
[JsonProperty("draft")]
[JsonPropertyName("draft")]
public bool IsDraft { get; set; }
[JsonProperty("html_url")]
[JsonPropertyName("html_url")]
public string Url { get; set; }
}
}

Просмотреть файл

@ -2,16 +2,16 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Uwp.SampleApp
{
public class LandingPageLink
{
[JsonProperty("title")]
[JsonPropertyName("title")]
public string Title { get; set; }
[JsonProperty("url")]
[JsonPropertyName("url")]
public string Url { get; set; }
}
}

Просмотреть файл

@ -2,19 +2,19 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Uwp.SampleApp
{
public class LandingPageLinks
{
[JsonProperty("new-section-title")]
[JsonPropertyName("new-section-title")]
public string NewSectionTitle { get; set; }
[JsonProperty("new-samples")]
[JsonPropertyName("new-samples")]
public string[] NewSamples { get; set; }
[JsonProperty("resources")]
[JsonPropertyName("resources")]
public LandingPageResource[] Resources { get; set; }
}
}

Просмотреть файл

@ -2,19 +2,19 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Uwp.SampleApp
{
public class LandingPageResource
{
[JsonProperty("title")]
[JsonPropertyName("title")]
public string Title { get; set; }
[JsonProperty("id")]
[JsonPropertyName("id")]
public string ID { get; set; }
[JsonProperty("links")]
[JsonPropertyName("links")]
public LandingPageLink[] Links { get; set; }
}
}

Просмотреть файл

@ -12,6 +12,8 @@ using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.Toolkit.Graph.Converters;
@ -22,7 +24,7 @@ using Microsoft.Toolkit.Uwp.SampleApp.Models;
using Microsoft.Toolkit.Uwp.UI.Animations;
using Microsoft.Toolkit.Uwp.UI.Controls;
using Microsoft.Toolkit.Uwp.UI.Media;
using Newtonsoft.Json;
using Microsoft.UI.Xaml;
using Windows.Foundation.Metadata;
using Windows.Storage;
using Windows.Storage.Streams;
@ -329,7 +331,7 @@ namespace Microsoft.Toolkit.Uwp.SampleApp
// Takes a second copy of the image stream, so that is can save the image data to cache.
using (var saveStream = await CopyStream(response.Content))
{
await SaveImageToCache(localpath, saveStream);
await SaveImageToCache(localPath, saveStream);
}
#endif
}
@ -759,7 +761,7 @@ namespace Microsoft.Toolkit.Uwp.SampleApp
{
var raw = await response.Content.ReadAsStringAsync();
Debug.WriteLine(raw);
var json = JsonConvert.DeserializeObject<GitRef>(raw);
var json = JsonSerializer.Deserialize<GitRef>(raw);
return json?.RefObject?.Sha;
}
}
@ -774,13 +776,13 @@ namespace Microsoft.Toolkit.Uwp.SampleApp
public class GitRef
{
[JsonProperty("object")]
[JsonPropertyName("object")]
public GitRefObject RefObject { get; set; }
}
public class GitRefObject
{
[JsonProperty("sha")]
[JsonPropertyName("sha")]
public string Sha { get; set; }
}
}

Просмотреть файл

@ -4,11 +4,12 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Toolkit.Uwp.Helpers;
using Newtonsoft.Json;
namespace Microsoft.Toolkit.Uwp.SampleApp
{
@ -56,8 +57,10 @@ namespace Microsoft.Toolkit.Uwp.SampleApp
List<SampleCategory> allCategories;
using (var jsonStream = await StreamHelper.GetPackagedFileStreamAsync("SamplePages/samples.json"))
{
var jsonString = await jsonStream.ReadTextAsync();
allCategories = JsonConvert.DeserializeObject<List<SampleCategory>>(jsonString);
allCategories = await JsonSerializer.DeserializeAsync<List<SampleCategory>>(jsonStream.AsStream(), new JsonSerializerOptions
{
ReadCommentHandling = JsonCommentHandling.Skip
});
}
// Check API

Просмотреть файл

@ -5,12 +5,14 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Toolkit.Uwp.Helpers;
using Microsoft.Toolkit.Uwp.UI.Animations;
using Newtonsoft.Json;
using Windows.ApplicationModel;
using Windows.UI.Composition;
using Windows.UI.Xaml;
@ -202,8 +204,7 @@ namespace Microsoft.Toolkit.Uwp.SampleApp.Pages
{
using (var jsonStream = await StreamHelper.GetPackagedFileStreamAsync("landingPageLinks.json"))
{
var jsonString = await jsonStream.ReadTextAsync();
var links = JsonConvert.DeserializeObject<LandingPageLinks>(jsonString);
var links = await JsonSerializer.DeserializeAsync<LandingPageLinks>(jsonStream.AsStream());
var packageVersion = Package.Current.Id.Version;
var resource = links.Resources.FirstOrDefault(item => item.ID == "app");

Просмотреть файл

@ -3,6 +3,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controls="using:Microsoft.Toolkit.Uwp.UI.Controls"
xmlns:brushes="using:Microsoft.Toolkit.Uwp.UI.Media"
mc:Ignorable="d">
<Page.Resources>
@ -50,19 +51,22 @@
</RichTextBlock>
<controls:AdaptiveGridView
Margin="0,12,0,0"
x:Name="AdaptiveGridViewControl"
ItemHeight="200"
DesiredWidth="300"
SelectionMode="None"
IsItemClickEnabled="False"
ItemTemplate="{StaticResource PhotosTemplate}" />
Margin="0,12,0,0"
x:Name="AdaptiveGridViewControl"
ItemHeight="200"
DesiredWidth="300"
SelectionMode="None"
IsItemClickEnabled="False"
ItemTemplate="{StaticResource PhotosTemplate}" />
</StackPanel>
</ScrollViewer>
<controls:Loading x:Name="LoadingControl">
<controls:Loading.Background>
<SolidColorBrush Color="@[Background:Brush:Black]" Opacity="@[Background Opacity:DoubleSlider:0.7:0-1]" />
<brushes:AcrylicBrush BackgroundSource="Backdrop"
TintColor="Black"
TintOpacity="@[Opacity:DoubleSlider:0.4:0.0-1.0]"
BlurAmount="@[BlurAmount:DoubleSlider:8:0.0-24.0]"/>
</controls:Loading.Background>
<ContentControl x:Name="LoadingContentControl" />
</controls:Loading>

Просмотреть файл

@ -3,7 +3,6 @@
// See the LICENSE file in the project root for more information.
using System.Threading.Tasks;
using Microsoft.Toolkit.Uwp.UI.Animations;
using Microsoft.Toolkit.Uwp.UI.Controls;
using Microsoft.Toolkit.Uwp.UI.Extensions;
using Windows.UI.Xaml;
@ -13,7 +12,6 @@ namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages
{
public sealed partial class LoadingPage : IXamlRenderListener
{
private AdaptiveGridView adaptiveGridViewControl;
private Loading loadingControl;
private ContentControl loadingContentControl;
private ResourceDictionary resources;
@ -26,14 +24,13 @@ namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages
public async void OnXamlRendered(FrameworkElement control)
{
adaptiveGridViewControl = control.FindChildByName("AdaptiveGridViewControl") as AdaptiveGridView;
loadingControl = control.FindDescendantByName("LoadingControl") as Loading;
loadingContentControl = control.FindChildByName("LoadingContentControl") as ContentControl;
resources = control.Resources;
if (adaptiveGridViewControl != null)
if (control.FindChildByName("AdaptiveGridViewControl") is AdaptiveGridView gridView)
{
adaptiveGridViewControl.ItemsSource = await new Data.PhotosDataSource().GetItemsAsync();
gridView.ItemsSource = await new Data.PhotosDataSource().GetItemsAsync();
}
}
@ -57,14 +54,12 @@ namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages
}
});
SampleController.Current.RegisterNewCommand("Loading control with logo and blurring when requested", async (sender, args) =>
SampleController.Current.RegisterNewCommand("Loading control with logo", async (sender, args) =>
{
if (loadingContentControl != null)
{
loadingContentControl.ContentTemplate = resources["LogoTemplate"] as DataTemplate;
await loadingContentControl.Blur(2, 100).StartAsync();
await ShowLoadingDialogAsync();
await loadingContentControl.Blur(0, 0).StartAsync();
}
});
}
@ -72,7 +67,7 @@ namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages
private async Task ShowLoadingDialogAsync()
{
loadingControl.IsLoading = true;
await Task.Delay(3000);
await Task.Delay(5000);
loadingControl.IsLoading = false;
}
}

Просмотреть файл

@ -2,9 +2,9 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.Toolkit.Parsers.Markdown;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Windows.UI.Xaml.Controls;
namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages
@ -35,7 +35,13 @@ namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages
var document = new MarkdownDocument();
document.Parse(RawMarkdown.Text);
var json = JsonConvert.SerializeObject(document, Formatting.Indented, new StringEnumConverter());
var jsonSerializerOptions = new JsonSerializerOptions
{
WriteIndented = true
};
jsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
var json = JsonSerializer.Serialize(document, typeof(MarkdownDocument), jsonSerializerOptions);
MarkdownResult.Text = json;
}
}

Просмотреть файл

@ -47,13 +47,18 @@ namespace Microsoft.Toolkit.Uwp.SampleApp.SamplePages
Languages.ItemsSource = null;
_translatorClient.SubscriptionKey = TranslatorServiceKey.Text;
var languages = await _translatorClient.GetLanguageNamesAsync("en");
try
{
_translatorClient.SubscriptionKey = TranslatorServiceKey.Text;
var languages = await _translatorClient.GetLanguageNamesAsync("en");
Languages.ItemsSource = languages;
Languages.SelectedIndex = 0;
SampleController.Current.DisplayWaitRing = false;
Languages.ItemsSource = languages;
Languages.SelectedIndex = 0;
}
finally
{
SampleController.Current.DisplayWaitRing = false;
}
}
private async void Translate_OnClick(object sender, RoutedEventArgs e)

Просмотреть файл

@ -84,10 +84,6 @@
"title": "Version",
"url": "http://aka.ms/uwptoolkit"
},
{
"title": "Newtonsoft Json (Dependency)",
"url": "http://www.newtonsoft.com/json"
},
{
"title": "ColorCode-Universal (Dependency)",
"url": "https://github.com/WilliamABradley/ColorCode-Universal"

Просмотреть файл

@ -44,8 +44,8 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.TextToolbarFormats.MarkDown
{
var select = Formatter.Selected;
int originalStart = Formatter.Selected.StartPosition;
string urlLabel = StringExtensions.GetLocalized("TextToolbarStrings_UrlLabel", "Microsoft.Toolkit.Uwp.UI.Controls/Resources");
string labelLabel = StringExtensions.GetLocalized("TextToolbarStrings_LabelLabel", "Microsoft.Toolkit.Uwp.UI.Controls/Resources");
string urlLabel = "WCT_TextToolbar_UrlLabel".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources");
string labelLabel = "WCT_TextToolbar_LabelLabel".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources");
// Replaces Selection of first Line only.
if (select.Text.Contains("\r"))

Просмотреть файл

@ -55,7 +55,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.TextToolbarFormats.MarkDown
{
Content = new MarkdownTextBlock
{
Text = val + StringExtensions.GetLocalized("TextToolbarStrings_HeaderLabel", "Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
Text = val + "WCT_TextToolbar_HeaderLabel".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
IsTextSelectionEnabled = false
},
Tag = val,
@ -462,7 +462,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.TextToolbarFormats.MarkDown
QuoteButton = new ToolbarButton
{
Name = QuoteElement,
ToolTip = StringExtensions.GetLocalized("TextToolbarStrings_QuoteLabel", "Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
ToolTip = "WCT_TextToolbar_QuoteLabel".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
Icon = new SymbolIcon { Symbol = Symbol.Message },
Activation = FormatQuote
};
@ -479,13 +479,13 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.TextToolbarFormats.MarkDown
{
Name = HeadersElement,
Icon = new SymbolIcon { Symbol = Symbol.FontSize },
ToolTip = StringExtensions.GetLocalized("TextToolbarStrings_HeaderLabel", "Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
ToolTip = "WCT_TextToolbar_HeaderLabel".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
Activation = StyleHeader
},
new ToolbarButton
{
Name = CodeElement,
ToolTip = StringExtensions.GetLocalized("TextToolbarStrings_CodeLabel", "Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
ToolTip = "WCT_TextToolbar_CodeLabel".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
Icon = new FontIcon { Glyph = "{}", FontFamily = new FontFamily("Segoe UI"), Margin = new Thickness(0, -5, 0, 0) },
Activation = FormatCode
},

Просмотреть файл

@ -68,7 +68,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
{
Width = _normalModeWidth;
VisualStateManager.GoToState(this, "Expanded", true);
var name = StringExtensions.GetLocalized("WindowsCommunityToolkit_BladeView_ExpandButton_Collapsed", "Microsoft.Toolkit.Uwp.UI.Controls/Resources");
var name = "WCT_BladeView_ExpandButton_Collapsed".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources");
if (_enlargeButton != null)
{
AutomationProperties.SetName(_enlargeButton, name);
@ -84,7 +84,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
{
Width = double.NaN;
VisualStateManager.GoToState(this, "Collapsed", true);
var name = StringExtensions.GetLocalized("WindowsCommunityToolkit_BladeView_ExpandButton_Expanded", "Microsoft.Toolkit.Uwp.UI.Controls/Resources");
var name = "WCT_BladeView_ExpandButton_Expanded".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources");
if (_enlargeButton != null)
{
AutomationProperties.SetName(_enlargeButton, name);

Просмотреть файл

@ -168,7 +168,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
{
DefaultStyleKey = typeof(GridSplitter);
Loaded += GridSplitter_Loaded;
string automationName = StringExtensions.GetLocalized("WindowsCommunityToolkit_GridSplitter_AutomationName", "/Microsoft.Toolkit.Uwp.UI.Controls/Resources");
string automationName = "WCT_GridSplitter_AutomationName".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources");
AutomationProperties.SetName(this, automationName);
}

Просмотреть файл

@ -63,7 +63,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
{
_dismissButton.Visibility = ShowDismissButton ? Visibility.Visible : Visibility.Collapsed;
_dismissButton.Click += DismissButton_Click;
AutomationProperties.SetName(_dismissButton, StringExtensions.GetLocalized("WindowsCommunityToolkit_InAppNotification_DismissButton_AutomationName", "Microsoft.Toolkit.Uwp.UI.Controls/Resources"));
AutomationProperties.SetName(_dismissButton, "WCT_InAppNotification_DismissButton_AutomationName".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources"));
}
if (_visualStateGroup != null)

Просмотреть файл

@ -30,7 +30,7 @@
<Setter Property="HorizontalOffset" Value="0" />
<Setter Property="AutomationProperties.LandmarkType" Value="Custom" />
<!-- The setter value is localized using x:Uid but we still need to set it explicitly to avoid a compiler warning -->
<Setter x:Uid="WindowsCommunityToolkit_InAppNotification_LandmarkProperty" Property="AutomationProperties.LocalizedLandmarkType" Value="Notification" />
<Setter x:Uid="WCT_InAppNotification_LandmarkProperty" Property="AutomationProperties.LocalizedLandmarkType" Value="Notification" />
<Setter Property="AutomationProperties.LiveSetting" Value="Assertive" />
<Setter Property="Template" Value="{StaticResource MSEdgeNotificationTemplate}" />
</Style>

Просмотреть файл

@ -5,11 +5,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.UI.Composition;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Windows.Foundation;
using Windows.Graphics;
using Windows.Storage;
@ -79,10 +78,38 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
internal string GetSerializedList()
{
var exportModel = new InkCanvasExportModel { DrawableList = _drawableList, Version = 1 };
return JsonConvert.SerializeObject(exportModel, Formatting.Indented, new JsonSerializerSettings
return JsonSerializer.Serialize(exportModel, GetJsonSerializerOptions());
}
private static JsonSerializerOptions GetJsonSerializerOptions()
{
var jsonSerializerOptions = new JsonSerializerOptions
{
TypeNameHandling = TypeNameHandling.Auto
});
WriteIndented = true
};
// This will be needed until These two issues are fixed:
// https://github.com/dotnet/runtime/issues/30083
// https://github.com/dotnet/runtime/issues/29937
jsonSerializerOptions.Converters.Add(new IDrawableConverter());
return jsonSerializerOptions;
}
internal static List<IDrawable> LoadJson(string json)
{
var token = JsonDocument.Parse(json);
List<IDrawable> newList;
if (token.RootElement.ValueKind == JsonValueKind.Array)
{
// first sin, because of creating a file without versioning so we have to be able to import without breaking changes.
newList = JsonSerializer.Deserialize<List<IDrawable>>(json, GetJsonSerializerOptions());
}
else
{
newList = JsonSerializer.Deserialize<InkCanvasExportModel>(json, GetJsonSerializerOptions()).DrawableList;
}
return newList;
}
internal void RenderFromJsonAndDraw(Rect viewPort, string json, float zoom)
@ -92,17 +119,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
_undoCommands.Clear();
_redoCommands.Clear();
var token = JToken.Parse(json);
List<IDrawable> newList;
if (token is JArray)
{
// first sin, because of creating a file without versioning so we have to be able to import without breaking changes.
newList = JsonConvert.DeserializeObject<List<IDrawable>>(json, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto });
}
else
{
newList = JsonConvert.DeserializeObject<InkCanvasExportModel>(json, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto }).DrawableList;
}
var newList = LoadJson(json);
foreach (var drawable in newList)
{

Просмотреть файл

@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Text.Json;
using Microsoft.Graphics.Canvas;
using Windows.Foundation;
@ -13,6 +14,12 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
bool IsVisible(Rect viewPort);
void WriteJson(Utf8JsonWriter writer);
void ReadProperty(string propertyName, ref Utf8JsonReader reader);
void OnDeserialized();
bool IsActive { get; set; }
Rect Bounds { get; set; }

Просмотреть файл

@ -5,9 +5,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.Graphics.Canvas;
using Newtonsoft.Json;
using Windows.Foundation;
using Windows.UI.Input.Inking;
using Windows.UI.Xaml;
@ -19,6 +19,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
[JsonIgnore]
public IReadOnlyList<InkStroke> Strokes { get; set; }
[JsonPropertyName("$type")]
public string Type => IDrawableConverter.GetDiscriminator(GetType());
public List<SerializableStroke> SerializableStrokeList { get; set; }
public Rect Bounds { get; set; }
@ -27,6 +30,11 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
internal static readonly InkStrokeBuilder StrokeBuilder = new InkStrokeBuilder();
// Don't remove! Used for deserialization.
public InkDrawable()
{
}
public InkDrawable(IReadOnlyList<InkStroke> strokes)
{
if (strokes == null || !strokes.Any())
@ -83,8 +91,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
return new InkPoint(new Point(point.Position.X - sessionBounds.X, point.Position.Y - sessionBounds.Y), point.Pressure, point.TiltX, point.TiltY, point.Timestamp);
}
[OnSerializing]
internal void OnSerializingMethod(StreamingContext context)
public void WriteJson(Utf8JsonWriter writer)
{
SerializableStrokeList = new List<SerializableStroke>(Strokes.Count);
foreach (var stroke in Strokes)
@ -103,10 +110,15 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
serializableStroke.PointTransform = stroke.PointTransform;
SerializableStrokeList.Add(serializableStroke);
}
var options = new JsonSerializerOptions();
options.Converters.Add(new SerializableStrokeConverter());
JsonSerializer.Serialize(writer, this, options);
SerializableStrokeList = null;
}
[OnDeserialized]
internal void OnDeserializedMethod(StreamingContext context)
public void OnDeserialized()
{
var finalStrokeList = new List<InkStroke>(SerializableStrokeList.Count);
@ -121,10 +133,18 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
SerializableStrokeList = null;
}
[OnSerialized]
internal void OnSerializedMethod(StreamingContext context)
public void ReadProperty(string propertyName, ref Utf8JsonReader reader)
{
SerializableStrokeList = null;
switch (propertyName)
{
case "SerializableStrokeList":
var options = new JsonSerializerOptions();
options.Converters.Add(new SerializableStrokeConverter());
SerializableStrokeList = JsonSerializer.Deserialize<List<SerializableStroke>>(ref reader, options);
break;
default:
break;
}
}
}
}

Просмотреть файл

@ -2,6 +2,8 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System.Text.Json;
using System.Text.Json.Serialization;
using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.Text;
using Windows.Foundation;
@ -13,6 +15,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
{
internal class TextDrawable : IDrawable
{
[JsonPropertyName("$type")]
public string Type => IDrawableConverter.GetDiscriminator(GetType());
public string Text { get; set; }
public Rect Bounds { get; set; }
@ -27,6 +32,11 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
public bool IsItalic { get; set; }
// Don't remove! Used for deserialization.
public TextDrawable()
{
}
public TextDrawable(double left, double top, double width, double height, float fontSize, string text, Color textColor, bool isBold, bool isItalic)
{
Bounds = new Rect(left, top, width, height);
@ -76,5 +86,38 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
return ((100 - FontSize) / 10) + 5;
}
}
public void WriteJson(Utf8JsonWriter writer)
{
JsonSerializer.Serialize(writer, this);
}
public void OnDeserialized()
{
}
public void ReadProperty(string propertyName, ref Utf8JsonReader reader)
{
switch (propertyName)
{
case "Text":
Text = reader.GetString();
break;
case "FontSize":
FontSize = reader.GetSingle();
break;
case "TextColor":
TextColor = JsonSerializer.Deserialize<Color>(ref reader);
break;
case "IsBold":
IsBold = reader.GetBoolean();
break;
case "IsItalic":
IsItalic = reader.GetBoolean();
break;
default:
break;
}
}
}
}

Просмотреть файл

@ -0,0 +1,96 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
using Windows.Foundation;
namespace Microsoft.Toolkit.Uwp.UI.Controls
{
internal class IDrawableConverter : JsonConverter<IDrawable>
{
public override bool CanConvert(Type typeToConvert) => typeof(IDrawable).IsAssignableFrom(typeToConvert);
public override IDrawable Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartObject)
{
throw new JsonException();
}
reader.Read();
if (reader.TokenType != JsonTokenType.PropertyName)
{
throw new JsonException();
}
string propertyName = reader.GetString();
if (propertyName != "$type")
{
throw new JsonException();
}
reader.Read();
if (reader.TokenType != JsonTokenType.String)
{
throw new JsonException();
}
var typeDiscriminator = reader.GetString();
IDrawable drawable;
if (typeDiscriminator == GetDiscriminator(typeof(InkDrawable)))
{
drawable = new InkDrawable();
}
else if (typeDiscriminator == GetDiscriminator(typeof(TextDrawable)))
{
drawable = new TextDrawable();
}
else
{
throw new JsonException();
}
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject)
{
drawable.OnDeserialized();
return drawable;
}
if (reader.TokenType == JsonTokenType.PropertyName)
{
propertyName = reader.GetString();
reader.Read();
switch (propertyName)
{
case "IsActive":
drawable.IsActive = reader.GetBoolean();
break;
case "Bounds":
drawable.Bounds = JsonSerializer.Deserialize<Rect>(ref reader);
break;
default:
drawable.ReadProperty(propertyName, ref reader);
break;
}
}
}
throw new JsonException();
}
public override void Write(Utf8JsonWriter writer, IDrawable drawable, JsonSerializerOptions options)
{
drawable.WriteJson(writer);
}
internal static string GetDiscriminator(Type type)
{
return $"{type.FullName}, {type.Assembly.GetName().Name}";
}
}
}

Просмотреть файл

@ -0,0 +1,83 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Numerics;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Uwp.UI.Controls
{
internal class Matrix3x2Converter : JsonConverter<Matrix3x2>
{
public override Matrix3x2 Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.StartObject)
{
throw new JsonException();
}
string propertyName;
Matrix3x2 matrix = default;
while (reader.Read())
{
if (reader.TokenType == JsonTokenType.EndObject)
{
return matrix;
}
if (reader.TokenType == JsonTokenType.PropertyName)
{
propertyName = reader.GetString();
reader.Read();
switch (propertyName)
{
case "M11":
matrix.M11 = reader.GetSingle();
break;
case "M12":
matrix.M12 = reader.GetSingle();
break;
case "M21":
matrix.M21 = reader.GetSingle();
break;
case "M22":
matrix.M22 = reader.GetSingle();
break;
case "M31":
matrix.M31 = reader.GetSingle();
break;
case "M32":
matrix.M32 = reader.GetSingle();
break;
case "IsIdentity":
// Ignore, as it is readonly, and from v1
break;
case "Translation":
var translation = JsonSerializer.Deserialize<Vector2>(ref reader);
matrix.Translation = translation;
break;
}
}
}
throw new JsonException();
}
public override void Write(Utf8JsonWriter writer, Matrix3x2 value, JsonSerializerOptions options)
{
writer.WriteStartObject();
writer.WriteNumber("M11", value.M11);
writer.WriteNumber("M12", value.M12);
writer.WriteNumber("M21", value.M21);
writer.WriteNumber("M22", value.M22);
writer.WriteNumber("M31", value.M31);
writer.WriteNumber("M32", value.M32);
writer.WriteEndObject();
}
}
}

Просмотреть файл

@ -4,8 +4,8 @@
using System.Collections.Generic;
using System.Numerics;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using System.Text.Json;
using System.Text.Json.Serialization;
using Windows.UI.Input.Inking;
namespace Microsoft.Toolkit.Uwp.UI.Controls
@ -29,8 +29,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
public Matrix3x2 PointTransform { get; set; }
[OnSerializing]
internal void OnSerializingMethod(StreamingContext context)
internal void Write(Utf8JsonWriter writer, JsonSerializerOptions options)
{
SerializableFinalPointList = new List<SerializablePoint>(FinalPointList.Count);
foreach (var point in FinalPointList)
@ -60,10 +59,13 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
DrawAsHighlighter = DrawingAttributesIgnored.DrawAsHighlighter
};
}
JsonSerializer.Serialize(writer, this, options);
SerializableFinalPointList = null;
}
[OnDeserialized]
internal void OnDeserializedMethod(StreamingContext context)
internal void OnDeserialized()
{
var finalPointList = new List<InkPoint>(SerializableFinalPointList.Count);
@ -108,11 +110,5 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
SerializableFinalPointList = null;
SerializableDrawingAttributesKind = null;
}
[OnSerialized]
internal void OnSerializedMethod(StreamingContext context)
{
SerializableFinalPointList = null;
}
}
}

Просмотреть файл

@ -0,0 +1,31 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Microsoft.Toolkit.Uwp.UI.Controls
{
internal class SerializableStrokeConverter : JsonConverter<SerializableStroke>
{
public override SerializableStroke Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
var matrixOptions = new JsonSerializerOptions();
matrixOptions.Converters.Add(new Matrix3x2Converter());
SerializableStroke serializableStroke = JsonSerializer.Deserialize<SerializableStroke>(ref reader, matrixOptions);
serializableStroke.OnDeserialized();
return serializableStroke;
}
public override void Write(Utf8JsonWriter writer, SerializableStroke value, JsonSerializerOptions options)
{
var matrixOptions = new JsonSerializerOptions();
matrixOptions.Converters.Add(new Matrix3x2Converter());
value.Write(writer, matrixOptions);
}
}
}

Просмотреть файл

@ -41,6 +41,7 @@
<PackageTags>UWP Toolkit Windows Controls XAML Range WrapPanel Adaptive Markdown BladeView Blade CameraPreview Camera Carousel DockPanel DropShadow Expander GridSplitter HeaderedContent ImageEx InAppNotification InfiniteCanvas Master Details MasterDetails Orbit Radial Gauge RadiaGauge RadialProgressBar Scroll ScrollHeader StaggeredPanel Staggered Tile Tokenizing TextBox UniformGrid Uniform Grid</PackageTags>
<!-- ARM64 builds for managed apps use .NET Native. We can't use the Reflection Provider for that. -->
<EnableTypeInfoReflection Condition="'$(Configuration)' == 'Debug'">false</EnableTypeInfoReflection>
<LangVersion>8.0</LangVersion>
</PropertyGroup>
<ItemGroup>

Просмотреть файл

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Library Name="Microsoft.Toolkit.Uwp.UI.Controls">
<Namespace Name="System.Text.Json.Serialization.Converters" Dynamic="Required All"/>
<Type Name="System.Text.Json.ReflectionMemberAccessor" Dynamic="Required All"/>
</Library>
</Directives>

Просмотреть файл

@ -117,107 +117,107 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="TextToolbarStrings_BoldLabel" xml:space="preserve">
<data name="WCT_TextToolbar_BoldLabel" xml:space="preserve">
<value>Bold</value>
<comment>Label for TextToolbar Control bold button.</comment>
</data>
<data name="TextToolbarStrings_CancelLabel" xml:space="preserve">
<data name="WCT_TextToolbar_CancelLabel" xml:space="preserve">
<value>Cancel</value>
<comment>Label for TextToolbar Control Cancel message.</comment>
</data>
<data name="TextToolbarStrings_CodeLabel" xml:space="preserve">
<data name="WCT_TextToolbar_CodeLabel" xml:space="preserve">
<value>Code</value>
<comment>Label for TextToolbar Control Code button.</comment>
</data>
<data name="TextToolbarStrings_CreateLinkLabel" xml:space="preserve">
<data name="WCT_TextToolbar_CreateLinkLabel" xml:space="preserve">
<value>Create Link</value>
<comment>Label for TextToolbar Control Create Link button.</comment>
</data>
<data name="TextToolbarStrings_EmptyTextLabel" xml:space="preserve">
<data name="WCT_TextToolbar_EmptyTextLabel" xml:space="preserve">
<value>Empty Text</value>
<comment>Label for TextToolbar Control Empty Text.</comment>
</data>
<data name="TextToolbarStrings_HeaderLabel" xml:space="preserve">
<data name="WCT_TextToolbar_HeaderLabel" xml:space="preserve">
<value>Header</value>
<comment>Label for TextToolbar Control Header button.</comment>
</data>
<data name="TextToolbarStrings_ItalicsLabel" xml:space="preserve">
<data name="WCT_TextToolbar_ItalicsLabel" xml:space="preserve">
<value>Italics</value>
<comment>Label for TextToolbar Control italics button.</comment>
</data>
<data name="TextToolbarStrings_LabelLabel" xml:space="preserve">
<data name="WCT_TextToolbar_LabelLabel" xml:space="preserve">
<value>Label</value>
<comment>Label for TextToolbar Control Label button.</comment>
</data>
<data name="TextToolbarStrings_LinkInvalidLabel" xml:space="preserve">
<data name="WCT_TextToolbar_LinkInvalidLabel" xml:space="preserve">
<value>Link Invalid</value>
<comment>Label for TextToolbar Control Link Invalid message.</comment>
</data>
<data name="TextToolbarStrings_LinkLabel" xml:space="preserve">
<data name="WCT_TextToolbar_LinkLabel" xml:space="preserve">
<value>Link</value>
<comment>Label for TextToolbar Control Link button.</comment>
</data>
<data name="TextToolbarStrings_ListLabel" xml:space="preserve">
<data name="WCT_TextToolbar_ListLabel" xml:space="preserve">
<value>List</value>
<comment>Label for TextToolbar Control List button.</comment>
</data>
<data name="TextToolbarStrings_OkLabel" xml:space="preserve">
<data name="WCT_TextToolbar_OkLabel" xml:space="preserve">
<value>Ok</value>
<comment>Label for TextToolbar Control Ok message.</comment>
</data>
<data name="TextToolbarStrings_OrderedListLabel" xml:space="preserve">
<data name="WCT_TextToolbar_OrderedListLabel" xml:space="preserve">
<value>Ordered List</value>
<comment>Label for TextToolbar Control Ordered List button.</comment>
</data>
<data name="TextToolbarStrings_QuoteLabel" xml:space="preserve">
<data name="WCT_TextToolbar_QuoteLabel" xml:space="preserve">
<value>Quote</value>
<comment>Label for TextToolbar Control Quote button.</comment>
</data>
<data name="TextToolbarStrings_RelativeLabel" xml:space="preserve">
<data name="WCT_TextToolbar_RelativeLabel" xml:space="preserve">
<value>Relative</value>
<comment>Label for TextToolbar Control Relative.</comment>
</data>
<data name="TextToolbarStrings_StrikethroughLabel" xml:space="preserve">
<data name="WCT_TextToolbar_StrikethroughLabel" xml:space="preserve">
<value>Strikethrough</value>
<comment>Label for TextToolbar Control Strikethrough button.</comment>
</data>
<data name="TextToolbarStrings_UnderlineLabel" xml:space="preserve">
<data name="WCT_TextToolbar_UnderlineLabel" xml:space="preserve">
<value>Underline</value>
<comment>Label for TextToolbar Control Underline button.</comment>
</data>
<data name="TextToolbarStrings_UrlLabel" xml:space="preserve">
<data name="WCT_TextToolbar_UrlLabel" xml:space="preserve">
<value>Url</value>
<comment>Label for TextToolbar Control Url button.</comment>
</data>
<data name="TextToolbarStrings_WarningLabel" xml:space="preserve">
<data name="WCT_TextToolbar_WarningLabel" xml:space="preserve">
<value>Warning</value>
<comment>Label for TextToolbar Control Warning message.</comment>
</data>
<data name="WindowsCommunityToolkit_BladeView_ExpandButton_Collapsed" xml:space="preserve">
<data name="WCT_BladeView_ExpandButton_Collapsed" xml:space="preserve">
<value>Collapse Blade</value>
<comment>Narrator Resource for BladeView collapsed status</comment>
</data>
<data name="WindowsCommunityToolkit_BladeView_ExpandButton_Expanded" xml:space="preserve">
<data name="WCT_BladeView_ExpandButton_Expanded" xml:space="preserve">
<value>Expand Blade</value>
<comment>Narrator Resource for BladeView expanded status</comment>
</data>
<data name="WindowsCommunityToolkit_GridSplitter_AutomationName" xml:space="preserve">
<data name="WCT_GridSplitter_AutomationName" xml:space="preserve">
<value>GridSplitter</value>
<comment>Narrator Resource for GridSplitter control</comment>
</data>
<data name="WindowsCommunityToolkit_InAppNotification_DismissButton_AutomationName" xml:space="preserve">
<data name="WCT_InAppNotification_DismissButton_AutomationName" xml:space="preserve">
<value>Dismiss</value>
<comment>The automation name for the dismiss button of the InAppNotification control.</comment>
</data>
<data name="WindowsCommunityToolkit_InAppNotification_LandmarkProperty.Value" xml:space="preserve">
<data name="WCT_InAppNotification_LandmarkProperty.Value" xml:space="preserve">
<value>Notification</value>
<comment>The landmark name for the InAppNotification control. It is said by the narrator when using landmark navigation.</comment>
</data>
<data name="WindowsCommunityToolkit_TokenizingTextBoxItem_MenuFlyout_Remove" xml:space="preserve">
<data name="WCT_TokenizingTextBoxItem_MenuFlyout_Remove" xml:space="preserve">
<value>Remove</value>
<comment>Label for TokenizingTextBox MenuFlyout 'Remove' option.</comment>
</data>
<data name="WindowsCommunityToolkit_TokenizingTextBox_MenuFlyout_SelectAll" xml:space="preserve">
<data name="WCT_TokenizingTextBox_MenuFlyout_SelectAll" xml:space="preserve">
<value>Select All</value>
<comment>Label for TokenizingTextBox MenuFlyout 'Select All' option.</comment>
</data>

Просмотреть файл

@ -120,7 +120,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.TextToolbarFormats.RichText
StrikeButton = CommonButtons.Strikethrough;
Underline = new ToolbarButton
{
ToolTip = StringExtensions.GetLocalized("TextToolbarStrings_UnderlineLabel", "Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
ToolTip = "WCT_TextToolbar_UnderlineLabel".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
Icon = new SymbolIcon { Symbol = Symbol.Underline },
ShortcutKey = VirtualKey.U,
Activation = ((RichTextButtonActions)ButtonActions).FormatUnderline

Просмотреть файл

@ -54,13 +54,13 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.TextToolbarButtons.Common
var labelBox = new RichEditBox
{
PlaceholderText = StringExtensions.GetLocalized("TextToolbarStrings_LabelLabel", "Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
PlaceholderText = "WCT_TextToolbar_LabelLabel".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
Margin = new Thickness(0, 0, 0, 5),
AcceptsReturn = false
};
var linkBox = new TextBox
{
PlaceholderText = StringExtensions.GetLocalized("TextToolbarStrings_UrlLabel", "Microsoft.Toolkit.Uwp.UI.Controls/Resources")
PlaceholderText = "WCT_TextToolbar_UrlLabel".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources")
};
CheckBox relativeBox = null;
@ -78,7 +78,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.TextToolbarButtons.Common
{
relativeBox = new CheckBox
{
Content = StringExtensions.GetLocalized("TextToolbarStrings_RelativeLabel", "Microsoft.Toolkit.Uwp.UI.Controls/Resources")
Content = "WCT_TextToolbar_RelativeLabel".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources")
};
contentPanel.Children.Add(relativeBox);
}
@ -89,10 +89,10 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.TextToolbarButtons.Common
var contentDialog = new ContentDialog
{
Title = StringExtensions.GetLocalized("TextToolbarStrings_CreateLinkLabel", "Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
Title = "WCT_TextToolbar_CreateLinkLabel".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
Content = contentPanel,
PrimaryButtonText = StringExtensions.GetLocalized("TextToolbarStrings_OkLabel", "Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
SecondaryButtonText = StringExtensions.GetLocalized("TextToolbarStrings_CancelLabel", "Microsoft.Toolkit.Uwp.UI.Controls/Resources")
PrimaryButtonText = "WCT_TextToolbar_OkLabel".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
SecondaryButtonText = "WCT_TextToolbar_CancelLabel".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources")
};
if (ControlHelpers.IsXamlRootAvailable && button.XamlRoot != null)
@ -107,9 +107,9 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.TextToolbarButtons.Common
labelBox.Document.GetText(Windows.UI.Text.TextGetOptions.None, out string labelText);
labelBox.Document.GetText(Windows.UI.Text.TextGetOptions.FormatRtf, out string formattedlabelText);
string linkInvalidLabel = StringExtensions.GetLocalized("TextToolbarStrings_LinkInvalidLabel", "Microsoft.Toolkit.Uwp.UI.Controls/Resources");
string okLabel = StringExtensions.GetLocalized("TextToolbarStrings_OkLabel", "Microsoft.Toolkit.Uwp.UI.Controls/Resources");
string warningLabel = StringExtensions.GetLocalized("TextToolbarStrings_WarningLabel", "Microsoft.Toolkit.Uwp.UI.Controls/Resources");
string linkInvalidLabel = "WCT_TextToolbar_LinkInvalidLabel".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources");
string okLabel = "WCT_TextToolbar_OkLabel".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources");
string warningLabel = "WCT_TextToolbar_WarningLabel".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources");
string linkText = linkBox.Text.Trim();
if (string.IsNullOrWhiteSpace(linkText))

Просмотреть файл

@ -37,7 +37,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.TextToolbarButtons.Common
return new ToolbarButton
{
Name = TextToolbar.BoldElement,
ToolTip = StringExtensions.GetLocalized("TextToolbarStrings_BoldLabel", "Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
ToolTip = "WCT_TextToolbar_BoldLabel".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
Icon = new SymbolIcon { Symbol = Symbol.Bold },
ShortcutKey = VirtualKey.B,
Activation = MakeBold
@ -55,7 +55,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.TextToolbarButtons.Common
return new ToolbarButton
{
Name = TextToolbar.ItalicsElement,
ToolTip = StringExtensions.GetLocalized("TextToolbarStrings_StrikethroughLabel", "Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
ToolTip = "WCT_TextToolbar_ItalicsLabel".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
Icon = new SymbolIcon { Symbol = Symbol.Italic },
ShortcutKey = VirtualKey.I,
Activation = MakeItalics
@ -73,7 +73,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.TextToolbarButtons.Common
return new ToolbarButton
{
Name = TextToolbar.StrikethoughElement,
ToolTip = StringExtensions.GetLocalized("TextToolbarStrings_StrikethroughLabel", "Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
ToolTip = "WCT_TextToolbar_StrikethroughLabel".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
Icon = new FontIcon { Glyph = "\u0335a\u0335b\u0335c\u0335", FontFamily = new FontFamily("Segoe UI"), Margin = new Thickness(0, -5, 0, 0) },
Activation = MakeStrike,
ShortcutKey = VirtualKey.Subtract,
@ -92,7 +92,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.TextToolbarButtons.Common
return new ToolbarButton
{
Name = TextToolbar.LinkElement,
ToolTip = StringExtensions.GetLocalized("TextToolbarStrings_LinkLabel", "Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
ToolTip = "WCT_TextToolbar_LinkLabel".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
Icon = new SymbolIcon { Symbol = Symbol.Link },
ShortcutKey = VirtualKey.K,
Activation = OpenLinkCreator,
@ -111,7 +111,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.TextToolbarButtons.Common
return new ToolbarButton
{
Name = TextToolbar.ListElement,
ToolTip = StringExtensions.GetLocalized("TextToolbarStrings_ListLabel", "Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
ToolTip = "WCT_TextToolbar_ListLabel".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
Content = new TextToolbarSymbols.List(),
Activation = MakeList
};
@ -128,7 +128,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls.TextToolbarButtons.Common
return new ToolbarButton
{
Name = TextToolbar.OrderedElement,
ToolTip = StringExtensions.GetLocalized("TextToolbarStrings_OrderedListLabel", "Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
ToolTip = "WCT_TextToolbar_OrderedListLabel".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources"),
Content = new TextToolbarSymbols.NumberedList(),
Activation = MakeOList
};

Просмотреть файл

@ -185,7 +185,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
var selectAllMenuItem = new MenuFlyoutItem
{
Text = "WindowsCommunityToolkit_TokenizingTextBox_MenuFlyout_SelectAll".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources")
Text = "WCT_TokenizingTextBox_MenuFlyout_SelectAll".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources")
};
selectAllMenuItem.Click += (s, e) => this.SelectAllTokensAndText();
var menuFlyout = new MenuFlyout();
@ -349,7 +349,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
var removeMenuItem = new MenuFlyoutItem
{
Text = "WindowsCommunityToolkit_TokenizingTextBoxItem_MenuFlyout_Remove".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources")
Text = "WCT_TokenizingTextBoxItem_MenuFlyout_Remove".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources")
};
removeMenuItem.Click += (s, e) => TokenizingTextBoxItem_ClearClicked(tokenitem, null);
@ -361,7 +361,7 @@ namespace Microsoft.Toolkit.Uwp.UI.Controls
var selectAllMenuItem = new MenuFlyoutItem
{
Text = "WindowsCommunityToolkit_TokenizingTextBox_MenuFlyout_SelectAll".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources")
Text = "WCT_TokenizingTextBox_MenuFlyout_SelectAll".GetLocalized("Microsoft.Toolkit.Uwp.UI.Controls/Resources")
};
selectAllMenuItem.Click += (s, e) => this.SelectAllTokensAndText();

Просмотреть файл

@ -14,7 +14,18 @@ namespace Microsoft.Toolkit.Uwp.Extensions
/// </summary>
public static class StringExtensions
{
private static readonly ResourceLoader IndependentLoader = ResourceLoader.GetForViewIndependentUse();
private static readonly ResourceLoader IndependentLoader;
static StringExtensions()
{
try
{
IndependentLoader = ResourceLoader.GetForViewIndependentUse();
}
catch
{
}
}
/// <summary>
/// Retrieves the provided resource for the current view context.
@ -52,17 +63,27 @@ namespace Microsoft.Toolkit.Uwp.Extensions
}
else
{
return IndependentLoader.GetString(resourceKey);
return IndependentLoader?.GetString(resourceKey);
}
}
/// <summary>
/// Retrieves the provided resource for the given key for use independent of the UI thread.
/// Retrieves the provided resource for the given key for use independent of the UI thread. First looks up resource at the application level, before falling back to provided resourcePath. This allows for easily overridable resources within a library.
/// </summary>
/// <param name="resourceKey">Resource key to retrieve.</param>
/// <param name="resourcePath">Resource path to retrieve.</param>
/// <param name="resourcePath">Resource path to fall back to in case resourceKey not found in app resources.</param>
/// <returns>string value for given resource or empty string if not found.</returns>
public static string GetLocalized(this string resourceKey, string resourcePath)
=> ResourceLoader.GetForViewIndependentUse(resourcePath).GetString(resourceKey);
{
// Try and retrieve resource at app level first.
var result = IndependentLoader?.GetString(resourceKey);
if (string.IsNullOrEmpty(result))
{
result = ResourceLoader.GetForViewIndependentUse(resourcePath).GetString(resourceKey);
}
return result;
}
}
}

Просмотреть файл

@ -2,14 +2,14 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Newtonsoft.Json;
using System.Text.Json;
namespace Microsoft.Toolkit.Uwp.Helpers
{
internal class JsonObjectSerializer : IObjectSerializer
{
public string Serialize<T>(T value) => JsonConvert.SerializeObject(value);
public string Serialize<T>(T value) => JsonSerializer.Serialize(value);
public T Deserialize<T>(string value) => JsonConvert.DeserializeObject<T>(value);
public T Deserialize<T>(string value) => JsonSerializer.Deserialize<T>(value);
}
}

Просмотреть файл

@ -8,8 +8,8 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="10.0.3" />
<PackageReference Include="System.Text.Json" Version="4.7.2" />
<ProjectReference Include="..\Microsoft.Toolkit\Microsoft.Toolkit.csproj" />

Просмотреть файл

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Library Name="Microsoft.Toolkit.Uwp">
<Namespace Name="System.Text.Json.Serialization.Converters" Dynamic="Required All"/>
</Library>
</Directives>

Просмотреть файл

@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
This file contains Runtime Directives, specifications about types your application accesses
through reflection and other dynamic code patterns. Runtime Directives are used to control the
.NET Native optimizer and ensure that it does not remove code accessed by your library. If your
library does not do any reflection, then you generally do not need to edit this file. However,
if your library reflects over types, especially types passed to it or derived from its types,
then you should write Runtime Directives.
The most common use of reflection in libraries is to discover information about types passed
to the library. Runtime Directives have three ways to express requirements on types passed to
your library.
1. Parameter, GenericParameter, TypeParameter, TypeEnumerableParameter
Use these directives to reflect over types passed as a parameter.
2. SubTypes
Use a SubTypes directive to reflect over types derived from another type.
3. AttributeImplies
Use an AttributeImplies directive to indicate that your library needs to reflect over
types or methods decorated with an attribute.
For more information on writing Runtime Directives for libraries, please visit
http://go.microsoft.com/fwlink/?LinkID=391919
-->
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata">
<Library Name="Microsoft.Toolkit.Uwp">
<!-- add directives for your library here -->
</Library>
</Directives>

Просмотреть файл

@ -0,0 +1,102 @@
{
"DrawableList": [
{
"$type": "Microsoft.Toolkit.Uwp.UI.Controls.InkDrawable, Microsoft.Toolkit.Uwp.UI.Controls",
"SerializableStrokeList": [
{
"DrawingAttributes": {
"Color": {
"A": 255,
"R": 0,
"G": 0,
"B": 0
},
"FitToCurve": true,
"IgnorePressure": false,
"IgnoreTilt": true,
"Size": {
"Width": 4.0,
"Height": 4.0,
"IsEmpty": false
},
"PenTip": 0,
"PenTipTransform": {
"M11": 1.0,
"M12": 0.0,
"M21": 0.0,
"M22": 1.0,
"M31": 0.0,
"M32": 0.0,
"IsIdentity": true,
"Translation": {
"X": 0.0,
"Y": 0.0
}
},
"DrawAsHighlighter": false
},
"SerializableFinalPointList": [
{
"Position": {
"X": 103.97531127929688,
"Y": 45.995269775390625
},
"Pressure": 0.5,
"TiltX": 0.0,
"TiltY": 0.0,
"Timestamp": 0
},
{
"Position": {
"X": 103.80825805664063,
"Y": 45.995269775390625
},
"Pressure": 0.5,
"TiltX": 0.0,
"TiltY": 0.0,
"Timestamp": 0
},
{
"Position": {
"X": 103.41259002685547,
"Y": 45.995269775390625
},
"Pressure": 0.5,
"TiltX": 0.0,
"TiltY": 0.0,
"Timestamp": 0
}
],
"SerializableDrawingAttributesKind": 0,
"SerializableDrawingAttributesPencilProperties": null,
"PointTransform": {
"M11": 1.0,
"M12": 0.0,
"M21": 0.0,
"M22": 1.0,
"M31": 0.0,
"M32": 0.0,
"IsIdentity": true,
"Translation": {
"X": 0.0,
"Y": 0.0
}
}
}
],
"Bounds": {
"X": 69.949455261230469,
"Y": 28.069997787475586,
"Width": 1668.2589111328125,
"Height": 280.38735961914062,
"Left": 69.949455261230469,
"Top": 28.069997787475586,
"Right": 1738.2083740234375,
"Bottom": 308.45736694335938,
"IsEmpty": false
},
"IsActive": true
}
],
"Version": 1
}

Просмотреть файл

@ -4,8 +4,8 @@
using Microsoft.Toolkit.Uwp.Helpers;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json;
using System;
using System.Text.Json;
using UnitTests.UI;
namespace UnitTests.Helpers
@ -24,7 +24,7 @@ namespace UnitTests.Helpers
int input = 42;
// simulate previous version by generating json and manually inserting it as string
string jsonInput = JsonConvert.SerializeObject(input);
string jsonInput = JsonSerializer.Serialize(input);
storageHelper.Save<string>(key, jsonInput);
@ -43,7 +43,7 @@ namespace UnitTests.Helpers
DateTime input = new DateTime(2017, 12, 25);
// simulate previous version by generating json and manually inserting it as string
string jsonInput = JsonConvert.SerializeObject(input);
string jsonInput = JsonSerializer.Serialize(input);
storageHelper.Save<string>(key, jsonInput);
@ -62,7 +62,7 @@ namespace UnitTests.Helpers
Person input = new Person() { Name = "Joe Bloggs", Age = 42 };
// simulate previous version by generating json and manually inserting it as string
string jsonInput = JsonConvert.SerializeObject(input);
string jsonInput = JsonSerializer.Serialize(input);
storageHelper.Save<string>(key, jsonInput);

Просмотреть файл

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="WCT_TextToolbar_ItalicsLabel" xml:space="preserve">
<value>ItalicsOverride</value>
</data>
</root>

Просмотреть файл

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="WCT_TextToolbar_ItalicsLabel" xml:space="preserve">
<value>ItalicsFr</value>
</data>
</root>

Просмотреть файл

@ -0,0 +1,43 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Threading.Tasks;
using FluentAssertions;
using Microsoft.Toolkit.Uwp.Helpers;
using Microsoft.Toolkit.Uwp.UI.Controls;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Windows.ApplicationModel.Core;
using Windows.UI.Core;
namespace UnitTests.UI.Controls
{
[TestClass]
public class Test_InfiniteCanvas_Regression
{
[TestCategory("InfiniteCanvas")]
[TestMethod]
public async Task Test_InfiniteCanvas_LoadsV1File()
{
var taskSource = new TaskCompletionSource<object>();
await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
CoreDispatcherPriority.Normal, async () =>
{
try
{
string json = await StorageFileHelper.ReadTextFromPackagedFileAsync(@"Assets\Samples\InfiniteCanvasExport.json");
InfiniteCanvasVirtualDrawingSurface.LoadJson(json).Should().NotBeEmpty();
taskSource.SetResult(null);
}
catch (Exception e)
{
taskSource.SetException(e);
}
});
await taskSource.Task;
}
}
}

Просмотреть файл

@ -0,0 +1,109 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using Microsoft.Toolkit.Uwp.Helpers;
using Microsoft.Toolkit.Uwp.UI.Controls;
using Microsoft.Toolkit.Uwp.UI.Controls.TextToolbarButtons.Common;
using Microsoft.Toolkit.Uwp.UI.Controls.TextToolbarFormats.RichText;
using Microsoft.Toolkit.Uwp.UI.Extensions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.VisualStudio.TestTools.UnitTesting.AppContainer;
using System.Linq;
using System.Threading.Tasks;
using Windows.ApplicationModel.Core;
using Windows.Globalization;
using Windows.System;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Markup;
namespace UnitTests.UI.Controls
{
[TestClass]
public class Test_TextToolbar_Localization
{
/// <summary>
/// Tests the general ability to look-up a resource from the UI control as a base-case.
/// </summary>
[TestCategory("Test_TextToolbar_Localization")]
[UITestMethod]
public void Test_TextToolbar_Localization_Retrieve()
{
var treeRoot = XamlReader.Load(
@"<Page
xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""
xmlns:controls=""using:Microsoft.Toolkit.Uwp.UI.Controls"">
<controls:TextToolbar x:Name=""TextToolbarControl"">
</controls:TextToolbar>
</Page>") as FrameworkElement;
Assert.IsNotNull(treeRoot, "Could not load XAML tree.");
var toolbar = treeRoot.FindChildByName("TextToolbarControl") as TextToolbar;
Assert.IsNotNull(toolbar, "Could not find TextToolbar in tree.");
var commonButtons = new CommonButtons(toolbar);
var boldButton = commonButtons.Bold;
Assert.IsNotNull(boldButton, "Bold Button not found.");
Assert.AreEqual("Bold", boldButton.ToolTip, "Label doesn't match expected default value.");
}
/// <summary>
/// Tests the ability to override the resource lookup for a toolkit component in the app resource dictionary.
/// See Link:Strings/en-us/Resources.resw
/// </summary>
[TestCategory("Test_TextToolbar_Localization")]
[UITestMethod]
public void Test_TextToolbar_Localization_Override()
{
var commonButtons = new CommonButtons(new TextToolbar());
var italicsButton = commonButtons.Italics;
Assert.IsNotNull(italicsButton, "Italics Button not found.");
Assert.AreEqual("ItalicsOverride", italicsButton.ToolTip, "Label doesn't match expected default value.");
}
/// <summary>
/// Tests the ability to have different overrides in different languages.
/// </summary>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
[TestCategory("Test_TextToolbar_Localization")]
[TestMethod]
public async Task Test_TextToolbar_Localization_Override_Fr()
{
await CoreApplication.MainView.DispatcherQueue.ExecuteOnUIThreadAsync(async () =>
{
// Just double-check we've got the right environment setup in our tests.
CollectionAssert.AreEquivalent(new string[] { "en-US", "fr" }, ApplicationLanguages.ManifestLanguages.ToArray(), "Missing locales for test");
// Override the default language for this test only (we'll set it back after).
var defaultLanguage = ApplicationLanguages.PrimaryLanguageOverride;
ApplicationLanguages.PrimaryLanguageOverride = "fr";
// Need to add a delay for release mode as otherwise the language switch doesn't kickover quick enough
// This should be sufficient as we're just using this as a test-harness.
await Task.Delay(3000);
var commonButtons = new CommonButtons(new TextToolbar());
var italicsButton = commonButtons.Italics;
// Note: When running locally if the test somehow fails before the default is reset, then
// the tests will be in a bad state as PrimaryLanguageOverride is persisted.
// To fix this, uninstall the UnitTests UWP app and run the tests again.
ApplicationLanguages.PrimaryLanguageOverride = defaultLanguage;
// Check for expected values.
Assert.IsNotNull(italicsButton, "Italics Button not found.");
Assert.AreEqual("ItalicsFr", italicsButton.ToolTip, "Label doesn't match expected default value.");
});
}
}
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше