Merge pull request #225 from microsoft/release/update/220107073544

Sync up from Mainline branch for CommitId 6636c16f03f6b9276362d2c2b29…
This commit is contained in:
MattB 2022-01-07 11:39:06 -08:00 коммит произвёл GitHub
Родитель bb983179c9 bb0e24d631
Коммит 57e6ba83df
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
24 изменённых файлов: 25027 добавлений и 111 удалений

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

@ -5,7 +5,7 @@
</PropertyGroup>
<PropertyGroup Condition="'$(ProjectSpecificFx)' == ''">
<TargetFrameworks>net462;net472;net48;netcoreapp3.0;netcoreapp3.1</TargetFrameworks>
<TargetFrameworks>net462;net472;net48;netcoreapp3.0;netcoreapp3.1;netstandard2.0</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>

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

@ -1,4 +1,4 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Identity.Client;
using Microsoft.PowerPlatform.Dataverse.Client.Auth.TokenCache;
using Microsoft.PowerPlatform.Dataverse.Client.Utils;
@ -90,11 +90,11 @@ namespace Microsoft.PowerPlatform.Dataverse.Client.Auth
}
else
{
var rslt = GetAuthorityFromTargetServiceAsync(ClientServiceProviders.Instance.GetService<IHttpClientFactory>(), processResult.TargetServiceUrl, logSink).ConfigureAwait(false).GetAwaiter().GetResult();
if (!string.IsNullOrEmpty(rslt.Authority))
var details = GetAuthorityFromTargetServiceAsync(ClientServiceProviders.Instance.GetService<IHttpClientFactory>(), processResult.TargetServiceUrl, logSink).ConfigureAwait(false).GetAwaiter().GetResult();
if (details.Success)
{
Authority = rslt.Authority;
Resource = rslt.Resource;
Authority = details.Authority.AbsoluteUri;
Resource = details.Resource.AbsoluteUri;
}
else
throw new ArgumentNullException("Authority", "Need a non-empty authority");
@ -446,18 +446,6 @@ namespace Microsoft.PowerPlatform.Dataverse.Client.Auth
return versionTaggedUriBuilder;
}
private const string AuthenticateHeader = "WWW-Authenticate";
private const string Bearer = "bearer";
private const string AuthorityKey = "authorization_uri";
private const string ResourceKey = "resource_id";
internal class AuthRoutingProperties
{
public string Authority { get; set; }
public string Resource { get; set; }
}
/// <summary>
/// Get authority and resource for this instance.
/// </summary>
@ -465,66 +453,11 @@ namespace Microsoft.PowerPlatform.Dataverse.Client.Auth
/// <param name="logger">Logger to write info too</param>
/// <param name="clientFactory">HTTP Client factory to use for this request.</param>
/// <returns></returns>
private static async Task<AuthRoutingProperties> GetAuthorityFromTargetServiceAsync(IHttpClientFactory clientFactory, Uri targetServiceUrl, DataverseTraceLogger logger)
private static async Task<AuthenticationDetails> GetAuthorityFromTargetServiceAsync(IHttpClientFactory clientFactory, Uri targetServiceUrl, DataverseTraceLogger logger)
{
AuthRoutingProperties authRoutingProperties = new AuthRoutingProperties();
var client = clientFactory.CreateClient("DataverseHttpClientFactory");
var rslt = await client.GetAsync(targetServiceUrl).ConfigureAwait(false);
if (rslt.StatusCode == System.Net.HttpStatusCode.NotFound || rslt.StatusCode == System.Net.HttpStatusCode.BadRequest)
{
// didn't find endpoint.
logger.Log($"Failed to get Authority and Resource error. Attempt to Access Endpoint {targetServiceUrl.ToString()} resulted in {rslt.StatusCode}.", TraceEventType.Error);
return authRoutingProperties;
}
if (rslt.Headers.Contains("WWW-Authenticate"))
{
var authenticateHeader = rslt.Headers.GetValues("WWW-Authenticate").FirstOrDefault();
authenticateHeader = authenticateHeader.Trim();
// This also checks for cases like "BearerXXXX authorization_uri=...." and "Bearer" and "Bearer "
if (!authenticateHeader.StartsWith(Bearer, StringComparison.OrdinalIgnoreCase)
|| authenticateHeader.Length < Bearer.Length + 2
|| !char.IsWhiteSpace(authenticateHeader[Bearer.Length]))
{
//var ex = new ArgumentException(AdalErrorMessage.InvalidAuthenticateHeaderFormat,
// nameof(authenticateHeader));
//CoreLoggerBase.Default.Error(AdalErrorMessage.InvalidAuthenticateHeaderFormat);
//CoreLoggerBase.Default.ErrorPii(ex);
//throw ex;
}
authenticateHeader = authenticateHeader.Substring(Bearer.Length).Trim();
IDictionary<string, string> authenticateHeaderItems = null;
try
{
authenticateHeaderItems =
EncodingHelper.ParseKeyValueListStrict(authenticateHeader, ',', false, true);
}
catch //(ArgumentException ex)
{
//var newEx = new ArgumentException(AdalErrorMessage.InvalidAuthenticateHeaderFormat,
// nameof(authenticateHeader), ex);
//CoreLoggerBase.Default.Error(AdalErrorMessage.InvalidAuthenticateHeaderFormat);
//CoreLoggerBase.Default.ErrorPii(newEx);
//throw newEx;
}
if (authenticateHeaderItems != null)
{
string param;
authenticateHeaderItems.TryGetValue(AuthorityKey, out param);
authRoutingProperties.Authority =
param.Replace("oauth2/authorize", "") // swap out the old oAuth pattern.
.Replace("common", "organizations"); // swap common for organizations because MSAL reasons.
authenticateHeaderItems.TryGetValue(ResourceKey, out param);
authRoutingProperties.Resource = param;
}
}
return authRoutingProperties;
var resolver = new AuthorityResolver(client, (t, msg) => logger.Log(msg, t));
return await resolver.ProbeForExpectedAuthentication(targetServiceUrl);
}
/// <summary>

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

@ -0,0 +1,155 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
namespace Microsoft.PowerPlatform.Dataverse.Client.Auth
{
/// <summary>
/// Details of expected authentication.
/// </summary>
public sealed class AuthenticationDetails
{
/// <summary>
/// True if probing returned a WWW-Authenticate header.
/// </summary>
public bool Success { get; internal set; }
/// <summary>
/// Authority to initiate OAuth flow with.
/// </summary>
// TODO: the 2 Uris here should be nullable: Uri? but that requires to update C# used for this solution from current 7.x to C# 9 or 10
public Uri Authority { get; internal set; }
/// <summary>
/// OAuth resource to request authentication for.
/// </summary>
public Uri Resource { get; internal set; }
}
/// <summary>
/// Probes API endpoint to elicit a 401 response with the WWW-Authenticate header and processes the found information
/// </summary>
public sealed class AuthorityResolver
{
private const string AuthenticateHeader = "WWW-Authenticate";
private const string Bearer = "bearer";
private const string AuthorityKey = "authorization_uri";
private const string ResourceKey = "resource_id";
private readonly HttpClient _httpClient;
private readonly Action<TraceEventType, string> _logger;
/// <summary>
/// instantiate resolver, using specified HttpClient to be used.
/// </summary>
/// <param name="httpClient"></param>
/// <param name="logger"></param>
public AuthorityResolver(HttpClient httpClient, Action<TraceEventType, string> logger = null)
{
_ = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
_httpClient = httpClient;
_logger = logger;
}
/// <summary>
/// Attemtps to solicit a WWW-Authenticate reply using an unauthenticated GET call to the given endpoint.
/// Parses returned header for details
/// </summary>
/// <param name="endpoint"></param>
/// <returns></returns>
/// <exception cref="ArgumentNullException"></exception>
public async Task<AuthenticationDetails> ProbeForExpectedAuthentication(Uri endpoint)
{
_ = endpoint ?? throw new ArgumentNullException(nameof(endpoint));
var details = new AuthenticationDetails();
HttpResponseMessage response;
try
{
response = await _httpClient.GetAsync(endpoint).ConfigureAwait(false);
}
catch (HttpRequestException ex)
{
var errDetails = string.Empty;
if (ex.InnerException is WebException wex)
{
errDetails = $"; details: {wex.Message} ({wex.Status})";
}
LogError($"Failed to get response from: {endpoint}; error: {ex.Message}{errDetails}");
return details;
}
if (response.StatusCode == HttpStatusCode.NotFound || response.StatusCode == HttpStatusCode.BadRequest)
{
// didn't find endpoint.
LogError($"Failed to get Authority and Resource error. Attempt to Access Endpoint {endpoint} resulted in {response.StatusCode}.");
return details;
}
if (response.Headers.Contains(AuthenticateHeader))
{
var authenticateHeader = response.Headers.GetValues(AuthenticateHeader).FirstOrDefault();
authenticateHeader = authenticateHeader.Trim();
// This also checks for cases like "BearerXXXX authorization_uri=...." and "Bearer" and "Bearer "
if (!authenticateHeader.StartsWith(Bearer, StringComparison.OrdinalIgnoreCase)
|| authenticateHeader.Length < Bearer.Length + 2
|| !char.IsWhiteSpace(authenticateHeader[Bearer.Length]))
{
LogError($"Malformed 'Bearer' format: {authenticateHeader}");
return details;
}
authenticateHeader = authenticateHeader.Substring(Bearer.Length).Trim();
IDictionary<string, string> authenticateHeaderItems = null;
try
{
authenticateHeaderItems =
EncodingHelper.ParseKeyValueListStrict(authenticateHeader, ',', false, true);
}
catch (ArgumentException)
{
LogError($"Malformed arguments in '{AuthenticateHeader}: {authenticateHeader}");
return details;
}
if (authenticateHeaderItems != null)
{
if (!authenticateHeaderItems.TryGetValue(AuthorityKey, out var auth))
{
LogError($"Response header from {endpoint} is missing expected key/value for {AuthorityKey}");
return details;
}
details.Authority = new Uri(
auth.Replace("oauth2/authorize", "") // swap out the old oAuth pattern.
.Replace("common", "organizations")); // swap common for organizations because MSAL reasons.
if (!authenticateHeaderItems.TryGetValue(ResourceKey, out var res))
{
LogError($"Response header from {endpoint} is missing expected key/value for {ResourceKey}");
return details;
}
details.Resource = new Uri(res);
details.Success = true;
}
}
return details;
}
private void LogError(string message)
{
if (_logger != null)
{
_logger(TraceEventType.Error, message);
}
}
}
}

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

@ -591,7 +591,7 @@ namespace Microsoft.PowerPlatform.Dataverse.Client
/// Cookies that are being passed though clients, when cookies are used
/// </summary>
internal Dictionary<string, string> CurrentCookieCollection { get; set; } = null;
/// <summary>
/// Server Hint for the number of concurrent threads that would provbide optimal processing.
/// </summary>
@ -1581,7 +1581,9 @@ namespace Microsoft.PowerPlatform.Dataverse.Client
}
else if (req.Parameters.ContainsKey("Target") && req.Parameters["Target"] is EntityReference entRef) // this should cover things that have targets.
{
cReq = new Entity(entRef.LogicalName, entRef.Id);
cReq = entRef.KeyAttributes.Any()
? new Entity(entRef.LogicalName, entRef.KeyAttributes)
: new Entity(entRef.LogicalName, entRef.Id);
}
EntityMetadata entityMetadata = null;

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

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ComponentAreaName>DataverseConnectControl</ComponentAreaName>
<ComponentAreaName>DataverseClient</ComponentAreaName>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.PowerPlatform.Dataverse.ConnectControl</RootNamespace>
@ -11,7 +11,7 @@
<Import Project="..\..\..\Build.Common.StandardAndLegacy.props" />
<PropertyGroup>
<TargetFrameworks>$(DotNetClassicTargetFrameworks)</TargetFrameworks>
<DocumentationFile>$(OutDir)\Microsoft.PowerPlatform.Dataverse.CrmConnectControl.xml</DocumentationFile>
<DocumentationFile>$(OutDir)\Microsoft.PowerPlatform.Dataverse.ConnectControl.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.IdentityModel.Clients.ActiveDirectory" Version="$(PackageVersion_Adal)" />

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

@ -5,6 +5,8 @@ VisualStudioVersion = 16.0.31729.503
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LivePackageTestsConsole", "UnitTests\LivePackageTestsConsole\LivePackageTestsConsole.csproj", "{AD21CFD4-EDA7-4F31-9A07-CC90C03B4C27}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LivePackageRunUnitTests", "UnitTests\LivePackageRunUnitTests\LivePackageRunUnitTests.csproj", "{F90838B9-F2D2-499B-8C37-4F8389380743}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -15,6 +17,10 @@ Global
{AD21CFD4-EDA7-4F31-9A07-CC90C03B4C27}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AD21CFD4-EDA7-4F31-9A07-CC90C03B4C27}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AD21CFD4-EDA7-4F31-9A07-CC90C03B4C27}.Release|Any CPU.Build.0 = Release|Any CPU
{F90838B9-F2D2-499B-8C37-4F8389380743}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F90838B9-F2D2-499B-8C37-4F8389380743}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F90838B9-F2D2-499B-8C37-4F8389380743}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F90838B9-F2D2-499B-8C37-4F8389380743}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

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

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ComponentAreaName>DataverseConnectControl</ComponentAreaName>
<ComponentAreaName>DataverseClient</ComponentAreaName>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>LoginControlTester</RootNamespace>

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

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ComponentAreaName>DataverseConnectControl</ComponentAreaName>
<ComponentAreaName>DataverseClient</ComponentAreaName>
<SignAssembly>true</SignAssembly>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.PowerPlatform.Dataverse.Ui.Styles</RootNamespace>

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

@ -0,0 +1,96 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using FluentAssertions;
using Microsoft.PowerPlatform.Dataverse.Client.Auth;
using Xunit;
namespace Client_Core_Tests.Auth
{
public class AuthResolverTests
{
private const string AuthenticateHeader = "www-authenticate";
private readonly MockHttpMessageHandler _msgHandler;
private readonly HttpClient _httpClient;
public AuthResolverTests()
{
_msgHandler = new MockHttpMessageHandler();
_httpClient = new HttpClient(_msgHandler);
}
[Theory]
[InlineData("https://login.somewhere.tst/abc/authorize", "https://hello.com", HttpStatusCode.Unauthorized, true, "Bearer authorization_uri=https://login.somewhere.tst/abc/authorize, resource_id=https://hello.com")]
[InlineData("https://login.somewhere.tst/abc/authorize", "https://hello.com", HttpStatusCode.Unauthorized, true, "BeArEr AUTHORIZATION_URI=https://login.somewhere.tst/abc/authorize, reSoUrCe_ID=https://hello.com")]
[InlineData("n/a", "n/a", HttpStatusCode.Unauthorized, false, "Bearer")]
[InlineData("https://login.somewhere.tst/abc/authorize", "n/a", HttpStatusCode.Unauthorized, false, "Bearer authorization_uri=https://login.somewhere.tst/abc/authorize")]
[InlineData("n/a", "https://hello.com", HttpStatusCode.Unauthorized, false, "Bearer resource_id=https://hello.com")]
public async Task ProbeSuccessful(string expectedAuthority, string expectedResource, HttpStatusCode expectedStatus, bool success, string responseHeader)
{
var endpoint = new Uri("https://ppdevtools.crm.dynamics.com/api/data/v9");
var log = new List<string>();
var resolver = new AuthorityResolver(_httpClient, (et, msg) =>
{
et.Should().Be(TraceEventType.Error);
log.Add(msg);
});
_msgHandler.ResponseHeader = responseHeader;
_msgHandler.ResponseStatus = expectedStatus;
var details = await resolver.ProbeForExpectedAuthentication(endpoint);
details.Success.Should().Be(success);
if (success)
{
details.Authority.Should().Be(new Uri(expectedAuthority));
details.Resource.Should().Be(new Uri(expectedResource));
}
else
{
log.Count.Should().BeGreaterOrEqualTo(1);
}
}
[Fact]
public async void DnsErrorsHandled()
{
var endpoint = new Uri("https://doesnotexist-bad.crm.dynamics.com/api/data/v9");
var log = new List<string>();
var resolver = new AuthorityResolver(_httpClient, (et, msg) =>
{
et.Should().Be(TraceEventType.Error);
log.Add(msg);
});
_msgHandler.ErrorOnSend = true;
var details = await resolver.ProbeForExpectedAuthentication(endpoint);
details.Success.Should().BeFalse();
log.Count.Should().BeGreaterOrEqualTo(1);
}
private class MockHttpMessageHandler : HttpMessageHandler
{
public string ResponseHeader { get; set; }
public HttpStatusCode ResponseStatus { get; set; } = HttpStatusCode.Unauthorized;
public bool ErrorOnSend { get; set; }
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
if (ErrorOnSend)
{
throw new HttpRequestException("Failed to get response", new WebException("The remote name could not be resolved", WebExceptionStatus.NameResolutionFailure));
}
var response = new HttpResponseMessage(ResponseStatus);
response.Headers.Remove(AuthenticateHeader);
response.Headers.TryAddWithoutValidation(AuthenticateHeader, ResponseHeader);
return Task.FromResult(response);
}
}
}
}

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

@ -19,7 +19,7 @@ namespace DataverseClient_Core_UnitTests.Properties {
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {

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

@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ProjectSpecificFx>true</ProjectSpecificFx>
<!-- only test with one of the Classic and Core frameworks each -->
<TargetFrameworks>net462;net472;net48;netcoreapp3.1;net5.0</TargetFrameworks>
<SignAssembly>true</SignAssembly>
<ComponentAreaName>DataverseClient-Tests-Package</ComponentAreaName>
<IsPackable>false</IsPackable>
</PropertyGroup>
<Import Project="..\..\..\..\Build.Common.core.props" />
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
<PackageReference Include="xunit" Version="$(PackageVersion_XUnit)" />
<PackageReference Include="xunit.runner.visualstudio" Version="$(PackageVersion_XUnit)" />
<PackageReference Include="coverlet.collector" Version="1.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LivePackageTestsConsole\LivePackageTestsConsole.csproj" />
</ItemGroup>
</Project>

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

@ -0,0 +1,69 @@
using System;
using System.IO;
using System.Text;
using Xunit;
using Xunit.Abstractions;
namespace LivePackageRunUnitTests
{
public class RunTests
{
public RunTests(ITestOutputHelper output)
{
var converter = new Converter(output);
Console.SetOut(converter);
}
[Fact]
public void InvokeBasicTest()
{
LivePackageTestsConsole.Program.SkipStop = true;
LivePackageTestsConsole.Program.Main(new string[] { "BasicFlow" });
}
[Fact]
public void InvokeReadSolutionsTest()
{
LivePackageTestsConsole.Program.SkipStop = true;
LivePackageTestsConsole.Program.Main(new string[] { "listsolutions" });
}
[Fact]
public void InvokeCUDTestTest()
{
LivePackageTestsConsole.Program.SkipStop = true;
LivePackageTestsConsole.Program.Main(new string[] { "CUDTest" });
}
#region Utility
private class Converter : TextWriter
{
ITestOutputHelper _output;
public Converter(ITestOutputHelper output)
{
_output = output;
}
public override Encoding Encoding
{
get { return Encoding.UTF8; }
}
public override void WriteLine(string message)
{
_output.WriteLine(message);
}
public override void WriteLine(string format, params object[] args)
{
_output.WriteLine(format, args);
}
public override void Write(char value)
{
throw new NotSupportedException("This text writer only supports WriteLine(string) and WriteLine(string, params object[]).");
}
}
#endregion
}
}

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

@ -0,0 +1,79 @@
using FluentAssertions;
using System;
using Microsoft.Xrm.Sdk;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CrmSdk;
namespace LivePackageTestsConsole
{
public class CUDTest
{
public void RunTest()
{
Console.WriteLine("Starting CUDTest Flow");
var client = Auth.CreateClient();
client.IsReady.Should().BeTrue();
Console.WriteLine("Creating Account");
Entity acct = new Entity("account");
acct.Attributes["name"] = "testaccount";
Guid id = client.Create(acct);
Console.WriteLine("Updating Account");
Entity acct2 = new Entity("account"); // changing to force a 'new' situation
acct2.Id = id;
acct2.Attributes["name"] = "testaccount2";
client.Update(acct2);
Console.WriteLine("Deleting Account");
client.Delete("account", id);
}
public void RunTest2()
{
Console.WriteLine("Starting CUDTest Flow - OrganziationContext");
var client = Auth.CreateClient();
client.IsReady.Should().BeTrue();
using (DvServiceContext svcCtx = new DvServiceContext(client))
{
//svcCtx.MergeOption = Microsoft.Xrm.Sdk.Client.MergeOption.NoTracking; // So as to not keep cached copies while working on test cases.
Console.WriteLine("Creating Account");
Account acct = new Account();
acct.Name = "testaccount";
svcCtx.AddObject(acct);
svcCtx.SaveChanges();
Guid id = acct.Id;
Console.WriteLine("Query Account");
var aQ = (from a1 in svcCtx.AccountSet
where a1.Name.Equals("testaccount")
select a1);
if (aQ != null )
Console.WriteLine($"Found Account by Name {aQ.FirstOrDefault().Name}");
Console.WriteLine("Updating Account");
Entity acct2 = new Entity("account"); // changing to force a 'new' situation
acct2.Id = id;
acct2.Attributes["name"] = "testaccount2";
client.Update(acct2);
Console.WriteLine("Deleting Account");
client.Delete("account", id);
}
}
}
}

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

@ -17,7 +17,7 @@
<RestoreAdditionalProjectSources>
$(RepoRoot)\binSigned\$(Configuration)\packages
</RestoreAdditionalProjectSources>
<TargetDvClientPackageVersion Condition=" '$(targetDvClientPackageVersion)' == '' ">0.5.9</TargetDvClientPackageVersion>
<TargetDvClientPackageVersion Condition=" '$(TargetDvClientPackageVersion)' == '' ">0.5.9</TargetDvClientPackageVersion>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)|$(Platform)'=='Debug|net462|AnyCPU'">
@ -28,7 +28,7 @@
<ItemGroup>
<PackageReference Include="FluentAssertions" Version="5.10.3" />
<PackageReference Include="Microsoft.PowerPlatform.Dataverse.Client" Version="$(TargetDvClientPackageVersion)" />
<PackageReference Include="Microsoft.PowerPlatform.Dataverse.Client.Dynamics" Version="$(targetDvClientPackageVersion)" />
<PackageReference Include="Microsoft.PowerPlatform.Dataverse.Client.Dynamics" Version="$(TargetDvClientPackageVersion)" />
</ItemGroup>
<ItemGroup>

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

@ -5,9 +5,10 @@ namespace LivePackageTestsConsole
/// <summary>
/// This program will test run against live tests on a known Nuget Package version.
/// </summary>
class Program
public class Program
{
static void Main(string[] args)
public static bool SkipStop { get; set; } = false;
public static void Main(string[] args)
{
Console.WriteLine("Starting Tests");
@ -48,6 +49,12 @@ namespace LivePackageTestsConsole
tests.Run();
}
else if ( string.Compare(args[0], "CUDTest", StringComparison.OrdinalIgnoreCase) == 0)
{
var tests = new CUDTest();
tests.RunTest();
tests.RunTest2();
}
}
else
{
@ -55,7 +62,8 @@ namespace LivePackageTestsConsole
tests.Run();
}
Console.ReadKey();
if (!SkipStop)
Console.ReadKey();
}
}
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ComponentAreaName>DataverseConnectControl</ComponentAreaName>
<ComponentAreaName>DataverseClient</ComponentAreaName>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Microsoft.PowerPlatform.Dataverse.WebResourceUtility</RootNamespace>
<AssemblyName>Microsoft.PowerPlatform.Dataverse.WebResourceUtility</AssemblyName>

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

@ -6,6 +6,9 @@ Notice:
https://docs.microsoft.com/en-us/dotnet/api/microsoft.crm.sdk.messages?view=dynamics-general-ce-9
++CURRENTRELEASEID++
Updated Min dependency to DV ServiceClient 0.5.10
0.5.10:
Updated Newtonsoft.Json to v11.0.2 to match server.
0.4.12:

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

@ -15,19 +15,19 @@
<tags>Dynamics CommonDataService CDS PowerApps PowerPlatform</tags>
<dependencies>
<group targetFramework=".NETFramework4.6.2">
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="0.5.0" exclude="Build,Analyzers" />
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="0.5.10" exclude="Build,Analyzers" />
</group>
<group targetFramework=".NETFramework4.7.2">
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="0.5.0" exclude="Build,Analyzers" />
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="0.5.10" exclude="Build,Analyzers" />
</group>
<group targetFramework=".NETFramework4.8">
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="0.5.0" exclude="Build,Analyzers" />
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="0.5.10" exclude="Build,Analyzers" />
</group>
<group targetFramework=".NETCoreApp3.0">
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="0.5.0" exclude="Build,Analyzers" />
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="0.5.10" exclude="Build,Analyzers" />
</group>
<group targetFramework=".NETCoreApp3.1">
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="0.5.0" exclude="Build,Analyzers" />
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="0.5.10" exclude="Build,Analyzers" />
</group>
</dependencies>
<frameworkAssemblies>

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

@ -3,6 +3,9 @@ Notice:
This package is intended to work with .net full framework 4.6.2, 4.7.2 and 4.8, .net core 3.0 and 3.1
++CURRENTRELEASEID++
updated min dependency to DV ServiceClient 0.5.10
0.5.10:
Updated Newtonsoft.Json to v11.0.2 to match server.
0.4.12:

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

@ -15,19 +15,19 @@
<tags>Dynamics CommonDataService CDS PowerApps PowerPlatform CdsServiceClient Dataverse</tags>
<dependencies>
<group targetFramework=".NETFramework4.6.2">
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="0.5.0" exclude="Build,Analyzers" />
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="0.5.10" exclude="Build,Analyzers" />
</group>
<group targetFramework=".NETFramework4.7.2">
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="0.5.0" exclude="Build,Analyzers" />
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="0.5.10" exclude="Build,Analyzers" />
</group>
<group targetFramework=".NETFramework4.8">
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="0.5.0" exclude="Build,Analyzers" />
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="0.5.10" exclude="Build,Analyzers" />
</group>
<group targetFramework=".NETCoreApp3.0">
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="0.5.0" exclude="Build,Analyzers" />
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="0.5.10" exclude="Build,Analyzers" />
</group>
<group targetFramework=".NETCoreApp3.1">
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="0.5.0" exclude="Build,Analyzers" />
<dependency id="Microsoft.PowerPlatform.Dataverse.Client" version="0.5.10" exclude="Build,Analyzers" />
</group>
</dependencies>
<frameworkAssemblies>

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

@ -8,6 +8,13 @@ Notice:
Note: that only OAuth, Certificate, ClientSecret Authentication types are supported at this time.
++CURRENTRELEASEID++
Accepted fix requested here: https://github.com/microsoft/PowerPlatform-DataverseServiceClient/issues/205
fixing delete by alternate key request in client.
Fixed dependency issue for System.Security.Premisions (git #203)
Refactored AuthorityResolver to discover AAD authentication authorities to allow for direct access by other clients.
0.5.10:
Added new property "RecommendedDegreesOfParallelism".
This property will report the recommended number of threads for communicating with Dataverse.

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

@ -58,10 +58,10 @@
<dependency id="System.Reflection.TypeExtensions" version="4.7.0" exclude="Build,Analyzers" />
<dependency id="System.Runtime.Serialization.Primitives" version="4.3.0" exclude="Build,Analyzers" />
<dependency id="System.Runtime.Serialization.Xml" version="4.3.0" exclude="Build,Analyzers" />
<dependency id="System.Security.Permissions" version="4.7.0" exclude="Build,Analyzers" />
<dependency id="System.ServiceModel.Duplex" version="4.7.0" exclude="Build,Analyzers" />
<dependency id="System.ServiceModel.Http" version="4.7.0" exclude="Build,Analyzers" />
<dependency id="System.ServiceModel.Primitives" version="4.7.0" exclude="Build,Analyzers" />
<dependency id="System.Security.Permissions" version="5.0.0" exclude="Build,Analyzers" />
<dependency id="System.ServiceModel.Duplex" version="4.8.1" exclude="Build,Analyzers" />
<dependency id="System.ServiceModel.Http" version="4.8.1" exclude="Build,Analyzers" />
<dependency id="System.ServiceModel.Primitives" version="4.8.1" exclude="Build,Analyzers" />
<dependency id="System.Text.Json" version="5.0.2" exclude="Build,Analyzers" />
<dependency id="Microsoft.Extensions.DependencyInjection" version="3.1.8" exclude="Build,Analyzers" />
<dependency id="Microsoft.Extensions.Http" version="3.1.8" exclude="Build,Analyzers" />
@ -88,10 +88,10 @@
<dependency id="System.Reflection.TypeExtensions" version="4.7.0" exclude="Build,Analyzers" />
<dependency id="System.Runtime.Serialization.Primitives" version="4.3.0" exclude="Build,Analyzers" />
<dependency id="System.Runtime.Serialization.Xml" version="4.3.0" exclude="Build,Analyzers" />
<dependency id="System.Security.Permissions" version="4.7.0" exclude="Build,Analyzers" />
<dependency id="System.ServiceModel.Duplex" version="4.7.0" exclude="Build,Analyzers" />
<dependency id="System.ServiceModel.Http" version="4.7.0" exclude="Build,Analyzers" />
<dependency id="System.ServiceModel.Primitives" version="4.7.0" exclude="Build,Analyzers" />
<dependency id="System.Security.Permissions" version="5.0.0" exclude="Build,Analyzers" />
<dependency id="System.ServiceModel.Duplex" version="4.8.1" exclude="Build,Analyzers" />
<dependency id="System.ServiceModel.Http" version="4.8.1" exclude="Build,Analyzers" />
<dependency id="System.ServiceModel.Primitives" version="4.8.1" exclude="Build,Analyzers" />
<dependency id="System.Text.Json" version="5.0.2" exclude="Build,Analyzers" />
<dependency id="Microsoft.Extensions.DependencyInjection" version="3.1.8" exclude="Build,Analyzers" />
<dependency id="Microsoft.Extensions.Http" version="3.1.8" exclude="Build,Analyzers" />