This commit is contained in:
Родитель
be9ee13289
Коммит
c16a939caa
|
@ -5,8 +5,9 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(ProjectSpecificFx)' == ''">
|
||||
<TargetFrameworks>net462;net472;net48;netstandard2.0;net6.0</TargetFrameworks>
|
||||
<TargetFrameworks>net462;net472;net48;netstandard2.0;net6.0;net8.0</TargetFrameworks>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<NoWarn>NU5104</NoWarn>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
|
|
@ -9,10 +9,11 @@ using Microsoft.PowerPlatform.Dataverse.Client.Auth;
|
|||
using Microsoft.PowerPlatform.Dataverse.Client.Auth.TokenCache;
|
||||
using Microsoft.PowerPlatform.Dataverse.Client.Connector;
|
||||
using Microsoft.PowerPlatform.Dataverse.Client.Connector.OnPremises;
|
||||
using Microsoft.PowerPlatform.Dataverse.Client.Exceptions;
|
||||
using Microsoft.PowerPlatform.Dataverse.Client.HttpUtils;
|
||||
using Microsoft.PowerPlatform.Dataverse.Client.InternalExtensions;
|
||||
using Microsoft.PowerPlatform.Dataverse.Client.Model;
|
||||
using Microsoft.PowerPlatform.Dataverse.Client.Utils;
|
||||
using Microsoft.Rest;
|
||||
using Microsoft.Xrm.Sdk;
|
||||
using Microsoft.Xrm.Sdk.Discovery;
|
||||
using Microsoft.Xrm.Sdk.Messages;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.PowerPlatform.Dataverse.Client.Utils;
|
||||
using Microsoft.Rest;
|
||||
using Microsoft.Xrm.Sdk;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
|
@ -12,6 +11,7 @@ using System.Globalization;
|
|||
using System.ServiceModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Microsoft.PowerPlatform.Dataverse.Client.Exceptions;
|
||||
|
||||
namespace Microsoft.PowerPlatform.Dataverse.Client
|
||||
{
|
||||
|
@ -21,9 +21,6 @@ namespace Microsoft.PowerPlatform.Dataverse.Client
|
|||
[LocalizableAttribute(false)]
|
||||
internal sealed class DataverseTraceLogger : TraceLoggerBase
|
||||
{
|
||||
// Internal connection of exceptions since last clear.
|
||||
private List<Exception> _ActiveExceptionsList;
|
||||
|
||||
internal ILogger _logger;
|
||||
|
||||
#region Properties
|
||||
|
@ -79,8 +76,6 @@ namespace Microsoft.PowerPlatform.Dataverse.Client
|
|||
TraceSourceName = traceSourceName;
|
||||
}
|
||||
|
||||
_ActiveExceptionsList = new List<Exception>();
|
||||
|
||||
base.Initialize();
|
||||
}
|
||||
|
||||
|
@ -88,7 +83,6 @@ namespace Microsoft.PowerPlatform.Dataverse.Client
|
|||
{
|
||||
_logger = logger;
|
||||
TraceSourceName = DefaultTraceSourceName;
|
||||
_ActiveExceptionsList = new List<Exception>();
|
||||
base.Initialize();
|
||||
}
|
||||
|
||||
|
@ -98,7 +92,6 @@ namespace Microsoft.PowerPlatform.Dataverse.Client
|
|||
if (base.LastError.Length > 0)
|
||||
base.LastError = base.LastError.Remove(0, LastError.Length - 1);
|
||||
LastException = null;
|
||||
_ActiveExceptionsList.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -151,39 +144,34 @@ namespace Microsoft.PowerPlatform.Dataverse.Client
|
|||
exception = new Exception(message);
|
||||
}
|
||||
|
||||
StringBuilder detailedDump = new StringBuilder();
|
||||
StringBuilder lastMessage = new StringBuilder();
|
||||
StringBuilder detailedDump = new StringBuilder(4096);
|
||||
StringBuilder lastMessage = new StringBuilder(2048);
|
||||
|
||||
lastMessage.AppendLine(message); // Added to fix missing last error line.
|
||||
detailedDump.AppendLine(message); // Added to fix missing error line.
|
||||
|
||||
if (!(exception != null && _ActiveExceptionsList.Contains(exception))) // Skip this line if its already been done.
|
||||
GetExceptionDetail(exception, detailedDump, 0, lastMessage);
|
||||
GetExceptionDetail(exception, detailedDump, 0, lastMessage);
|
||||
|
||||
TraceEvent(eventType, (int)eventType, detailedDump.ToString(), exception);
|
||||
if (eventType == TraceEventType.Error)
|
||||
{
|
||||
base.LastError += lastMessage.ToString();
|
||||
if (!(exception != null && _ActiveExceptionsList.Contains(exception))) // Skip this line if its already been done.
|
||||
// check and or alter the exception is its and HTTPOperationExecption.
|
||||
if (exception is HttpOperationException httpOperationException)
|
||||
{
|
||||
// check and or alter the exception is its and HTTPOperationExecption.
|
||||
if (exception is HttpOperationException httpOperationException)
|
||||
string errorMessage = "Not Provided";
|
||||
if (!string.IsNullOrWhiteSpace(httpOperationException.Response.Content))
|
||||
{
|
||||
string errorMessage = "Not Provided";
|
||||
if (!string.IsNullOrWhiteSpace(httpOperationException.Response.Content))
|
||||
{
|
||||
JObject contentBody = JObject.Parse(httpOperationException.Response.Content);
|
||||
errorMessage = string.IsNullOrEmpty(contentBody["error"]["message"]?.ToString()) ? "Not Provided" : GetFirstLineFromString(contentBody["error"]["message"]?.ToString()).Trim();
|
||||
}
|
||||
|
||||
Utils.DataverseOperationException webApiExcept = new Utils.DataverseOperationException(errorMessage, httpOperationException);
|
||||
LastException = webApiExcept;
|
||||
JObject contentBody = JObject.Parse(httpOperationException.Response.Content);
|
||||
errorMessage = string.IsNullOrEmpty(contentBody["error"]["message"]?.ToString()) ? "Not Provided" : GetFirstLineFromString(contentBody["error"]["message"]?.ToString()).Trim();
|
||||
}
|
||||
else
|
||||
LastException = exception;
|
||||
|
||||
Utils.DataverseOperationException webApiExcept = new Utils.DataverseOperationException(errorMessage, httpOperationException);
|
||||
LastException = webApiExcept;
|
||||
}
|
||||
else
|
||||
LastException = exception;
|
||||
}
|
||||
_ActiveExceptionsList.Add(exception);
|
||||
|
||||
detailedDump.Clear();
|
||||
lastMessage.Clear();
|
||||
|
@ -196,18 +184,13 @@ namespace Microsoft.PowerPlatform.Dataverse.Client
|
|||
/// <param name="exception"></param>
|
||||
public override void Log(Exception exception)
|
||||
{
|
||||
if (exception != null && _ActiveExceptionsList.Contains(exception))
|
||||
return; // already logged this one .
|
||||
|
||||
StringBuilder detailedDump = new StringBuilder();
|
||||
StringBuilder lastMessage = new StringBuilder();
|
||||
StringBuilder detailedDump = new StringBuilder(4096);
|
||||
StringBuilder lastMessage = new StringBuilder(2048);
|
||||
GetExceptionDetail(exception, detailedDump, 0, lastMessage);
|
||||
TraceEvent(TraceEventType.Error, (int)TraceEventType.Error, detailedDump.ToString(), exception);
|
||||
base.LastError += lastMessage.ToString();
|
||||
LastException = exception;
|
||||
|
||||
_ActiveExceptionsList.Add(exception);
|
||||
|
||||
detailedDump.Clear();
|
||||
lastMessage.Clear();
|
||||
}
|
||||
|
@ -594,7 +577,7 @@ namespace Microsoft.PowerPlatform.Dataverse.Client
|
|||
{
|
||||
if (errorDetails != null && errorDetails.Count > 0)
|
||||
{
|
||||
StringBuilder sw = new StringBuilder();
|
||||
StringBuilder sw = new StringBuilder(2048);
|
||||
sw.AppendLine("Error Details\t:");
|
||||
foreach (var itm in errorDetails)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
//using Microsoft.Rest;
|
||||
using Microsoft.PowerPlatform.Dataverse.Client.Exceptions;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Microsoft.PowerPlatform.Dataverse.Client.Utils
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to encompass a ServiceClient Connection Centric exceptions
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class DataverseConnectionException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a dataverse connection Exception
|
||||
/// </summary>
|
||||
/// <param name="message">Error Message</param>
|
||||
public DataverseConnectionException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a dataverse connection Exception
|
||||
/// </summary>
|
||||
/// <param name="message">Error Message</param>
|
||||
/// <param name="innerException">Supporting Exception</param>
|
||||
public DataverseConnectionException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
this.HResult = innerException.HResult;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a dataverse connection Exception
|
||||
/// </summary>
|
||||
/// <param name="message">Error Message</param>
|
||||
/// <param name="errorCode">Error code</param>
|
||||
/// <param name="data">Data Properties</param>
|
||||
/// <param name="helpLink">Help Link</param>
|
||||
/// <param name="httpOperationException"></param>
|
||||
public DataverseConnectionException(string message, int errorCode, string helpLink, IDictionary<string, string> data, HttpOperationException httpOperationException = null)
|
||||
: base(message, httpOperationException)
|
||||
{
|
||||
HResult = errorCode;
|
||||
HelpLink = helpLink;
|
||||
Source = "Dataverse Server API";
|
||||
foreach (var itm in data)
|
||||
{
|
||||
this.Data.Add(itm.Key, itm.Value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a Dataverse Connection Exception from an httpOperationError
|
||||
/// </summary>
|
||||
/// <param name="httpOperationException"></param>
|
||||
/// <returns></returns>
|
||||
public static DataverseConnectionException GenerateClientConnectionException(HttpOperationException httpOperationException)
|
||||
{
|
||||
string errorDetailPrefixString = "@Microsoft.PowerApps.CDS.ErrorDetails.";
|
||||
Dictionary<string, string> cdsErrorData = new Dictionary<string, string>();
|
||||
|
||||
JToken ErrorBlock = null;
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(httpOperationException.Response.Content))
|
||||
{
|
||||
JObject contentBody = JObject.Parse(httpOperationException.Response.Content);
|
||||
ErrorBlock = contentBody["error"];
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
if (ErrorBlock != null)
|
||||
{
|
||||
string errorMessage = DataverseTraceLogger.GetFirstLineFromString(ErrorBlock["message"]?.ToString()).Trim();
|
||||
var code = ErrorBlock["code"];
|
||||
int HResult = code != null && !string.IsNullOrWhiteSpace(code.ToString()) ? Convert.ToInt32(code.ToString(), 16) : -1;
|
||||
|
||||
string HelpLink = ErrorBlock["@Microsoft.PowerApps.CDS.HelpLink"]?.ToString();
|
||||
|
||||
foreach (var node in ErrorBlock.ToArray())
|
||||
{
|
||||
if (node.Path.Contains(errorDetailPrefixString))
|
||||
{
|
||||
cdsErrorData.Add(node.Value<JProperty>().Name.ToString().Replace(errorDetailPrefixString, string.Empty), node.HasValues ? node.Value<JProperty>().Value.ToString() : string.Empty);
|
||||
}
|
||||
}
|
||||
return new DataverseConnectionException(errorMessage, HResult, HelpLink, cdsErrorData, httpOperationException);
|
||||
}
|
||||
else
|
||||
return new DataverseConnectionException("Server Error, no error report generated from server", -1, string.Empty, cdsErrorData, httpOperationException);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,100 @@
|
|||
//using Microsoft.Rest;
|
||||
using Microsoft.PowerPlatform.Dataverse.Client.Exceptions;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.PowerPlatform.Dataverse.Client.Utils
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to encompass a ServiceClient Operation Exception
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class DataverseOperationException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a CdsService Client Exception
|
||||
/// </summary>
|
||||
/// <param name="message">Error Message</param>
|
||||
public DataverseOperationException(string message)
|
||||
: base(message)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a CdsService Client Exception
|
||||
/// </summary>
|
||||
/// <param name="message">Error Message</param>
|
||||
/// <param name="errorCode">Error code</param>
|
||||
/// <param name="data">Data Properties</param>
|
||||
/// <param name="helpLink">Help Link</param>
|
||||
/// <param name="httpOperationException"></param>
|
||||
public DataverseOperationException(string message, int errorCode, string helpLink, IDictionary<string, string> data, HttpOperationException httpOperationException = null)
|
||||
: base(message, httpOperationException)
|
||||
{
|
||||
HResult = errorCode;
|
||||
HelpLink = helpLink;
|
||||
Source = "Dataverse Server API";
|
||||
foreach (var itm in data)
|
||||
{
|
||||
this.Data.Add(itm.Key, itm.Value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a CdsService Client Exception from a httpOperationResult.
|
||||
/// </summary>
|
||||
/// <param name="httpOperationException"></param>
|
||||
public static DataverseOperationException GenerateClientOperationException(HttpOperationException httpOperationException)
|
||||
{
|
||||
string errorDetailPrefixString = "@Microsoft.PowerApps.CDS.ErrorDetails.";
|
||||
Dictionary<string, string> cdsErrorData = new Dictionary<string, string>();
|
||||
|
||||
JToken ErrorBlock = null;
|
||||
try
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(httpOperationException.Response.Content))
|
||||
{
|
||||
JObject contentBody = JObject.Parse(httpOperationException.Response.Content);
|
||||
ErrorBlock = contentBody["error"];
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
|
||||
if (ErrorBlock != null)
|
||||
{
|
||||
string errorMessage = DataverseTraceLogger.GetFirstLineFromString(ErrorBlock["message"]?.ToString()).Trim();
|
||||
var code = ErrorBlock["code"];
|
||||
int HResult = code != null && !string.IsNullOrWhiteSpace(code.ToString()) ? Convert.ToInt32(code.ToString(), 16) : -1;
|
||||
|
||||
string HelpLink = ErrorBlock["@Microsoft.PowerApps.CDS.HelpLink"]?.ToString();
|
||||
|
||||
foreach (var node in ErrorBlock.ToArray())
|
||||
{
|
||||
if (node.Path.Contains(errorDetailPrefixString))
|
||||
{
|
||||
cdsErrorData.Add(node.Value<JProperty>().Name.ToString().Replace(errorDetailPrefixString, string.Empty), node.HasValues ? node.Value<JProperty>().Value.ToString() : string.Empty);
|
||||
}
|
||||
}
|
||||
return new DataverseOperationException(errorMessage, HResult, HelpLink, cdsErrorData, httpOperationException);
|
||||
}
|
||||
else
|
||||
return new DataverseOperationException("Server Error, no error report generated from server", -1, string.Empty, cdsErrorData, httpOperationException);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a CdsService Client Exception
|
||||
/// </summary>
|
||||
/// <param name="message">Error Message</param>
|
||||
/// <param name="innerException">Supporting Exception</param>
|
||||
public DataverseOperationException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using Microsoft.PowerPlatform.Dataverse.Client.HttpUtils;
|
||||
|
||||
|
||||
namespace Microsoft.PowerPlatform.Dataverse.Client.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Http Exception wrapper class
|
||||
/// </summary>
|
||||
public class HttpOperationException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public HttpOperationException()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
public HttpOperationException(string message) : this(message, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="innerException"></param>
|
||||
public HttpOperationException(string message, Exception innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
|
||||
// Properties
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public object Body { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public HttpRequestMessageWrapper Request { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public HttpResponseMessageWrapper Response { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.PowerPlatform.Dataverse.Client.HttpUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Base class used to wrap HTTP requests and responses to preserve data after disposal of
|
||||
/// HttpClient.
|
||||
/// </summary>
|
||||
public abstract class HttpMessageWrapper
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the HttpMessageWrapper class.
|
||||
/// </summary>
|
||||
protected HttpMessageWrapper()
|
||||
{
|
||||
Headers = new Dictionary<string, IEnumerable<string>>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Exposes the HTTP message contents.
|
||||
/// </summary>
|
||||
public string Content { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of HTTP headers.
|
||||
/// </summary>
|
||||
public IDictionary<string, IEnumerable<string>> Headers { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Copies HTTP message headers to the error object.
|
||||
/// </summary>
|
||||
/// <param name="headers">Collection of HTTP headers.</param>
|
||||
protected void CopyHeaders(HttpHeaders headers)
|
||||
{
|
||||
if (headers != null)
|
||||
{
|
||||
foreach (KeyValuePair<string, IEnumerable<string>> header in headers)
|
||||
{
|
||||
IEnumerable<string> values = null;
|
||||
if (Headers.TryGetValue(header.Key, out values))
|
||||
{
|
||||
values = values.Concat(header.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
values = header.Value;
|
||||
}
|
||||
Headers[header.Key] = values;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
using Microsoft.PowerPlatform.Dataverse.Client.InternalExtensions;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
namespace Microsoft.PowerPlatform.Dataverse.Client.HttpUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Wrapper around HttpRequestMessage type that copies properties of HttpRequestMessage so that
|
||||
/// they are available after the HttpClient gets disposed.
|
||||
/// </summary>
|
||||
public class HttpRequestMessageWrapper : HttpMessageWrapper
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the HttpRequestMessageWrapper class from HttpRequestMessage
|
||||
/// and content.
|
||||
/// </summary>
|
||||
public HttpRequestMessageWrapper(HttpRequestMessage httpRequest, string content)
|
||||
{
|
||||
if (httpRequest == null)
|
||||
{
|
||||
throw new ArgumentNullException("httpRequest");
|
||||
}
|
||||
|
||||
CopyHeaders(httpRequest.Headers);
|
||||
CopyHeaders(httpRequest.GetContentHeaders());
|
||||
HttpRequestSanitizer.SanitizerHeaders(Headers);
|
||||
|
||||
Content = content;
|
||||
Method = httpRequest.Method;
|
||||
RequestUri = httpRequest.RequestUri;
|
||||
#pragma warning disable CS0618 // Options are only supported in .net 6
|
||||
if (httpRequest.Properties != null)
|
||||
{
|
||||
Properties = new Dictionary<string, object>();
|
||||
foreach (KeyValuePair<string, object> pair in httpRequest.Properties)
|
||||
{
|
||||
Properties[pair.Key] = pair.Value;
|
||||
}
|
||||
}
|
||||
#pragma warning restore CS0618
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the HTTP method used by the HTTP request message.
|
||||
/// </summary>
|
||||
public HttpMethod Method { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the Uri used for the HTTP request.
|
||||
/// </summary>
|
||||
public Uri RequestUri { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a set of properties for the HTTP request.
|
||||
/// </summary>
|
||||
public IDictionary<string, object> Properties { get; private set; }
|
||||
}
|
||||
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Microsoft.PowerPlatform.Dataverse.Client.HttpUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Sanitizer used internal by <see cref="HttpRequestMessageWrapper"/>.
|
||||
/// </summary>
|
||||
internal class HttpRequestSanitizer
|
||||
{
|
||||
private readonly static string _redactedPlaceholder = "REDACTED";
|
||||
private readonly static HashSet<string> _allowedHeaders = new HashSet<string>(new string[]
|
||||
{
|
||||
"x-ms-request-id",
|
||||
"x-ms-client-request-id",
|
||||
"x-ms-return-client-request-id",
|
||||
"traceparent",
|
||||
"MS-CV",
|
||||
|
||||
"Accept",
|
||||
"Cache-Control",
|
||||
"Connection",
|
||||
"Content-Length",
|
||||
"Content-Type",
|
||||
"Date",
|
||||
"ETag",
|
||||
"Expires",
|
||||
"If-Match",
|
||||
"If-Modified-Since",
|
||||
"If-None-Match",
|
||||
"If-Unmodified-Since",
|
||||
"Last-Modified",
|
||||
"Pragma",
|
||||
"Request-Id",
|
||||
"Retry-After",
|
||||
"Server",
|
||||
"Transfer-Encoding",
|
||||
"User-Agent",
|
||||
"WWW-Authenticate" // OAuth Challenge header.
|
||||
}, StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
/// <summary>
|
||||
/// Sanitize value of sensitive headers in the given <paramref name="headers"/>.
|
||||
/// </summary>
|
||||
/// <param name="headers">A collection of headers to sanitize.</param>
|
||||
public static void SanitizerHeaders(IDictionary<string, IEnumerable<string>> headers)
|
||||
{
|
||||
if (headers == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var namesOfHeaderToSanitize = headers.Keys.Except(_allowedHeaders, StringComparer.OrdinalIgnoreCase).ToList();
|
||||
|
||||
foreach (string name in namesOfHeaderToSanitize)
|
||||
{
|
||||
headers[name] = new string[] { _redactedPlaceholder };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Net;
|
||||
using Microsoft.PowerPlatform.Dataverse.Client.InternalExtensions;
|
||||
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
namespace Microsoft.PowerPlatform.Dataverse.Client.HttpUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Wrapper around HttpResponseMessage type that copies properties of HttpResponseMessage so that
|
||||
/// they are available after the HttpClient gets disposed.
|
||||
/// </summary>
|
||||
public class HttpResponseMessageWrapper : HttpMessageWrapper
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the HttpResponseMessageWrapper class from HttpResponseMessage
|
||||
/// and content.
|
||||
/// </summary>
|
||||
public HttpResponseMessageWrapper(HttpResponseMessage httpResponse, string content)
|
||||
{
|
||||
if (httpResponse == null)
|
||||
{
|
||||
throw new ArgumentNullException("httpResponse");
|
||||
}
|
||||
|
||||
CopyHeaders(httpResponse.Headers);
|
||||
CopyHeaders(httpResponse.GetContentHeaders());
|
||||
|
||||
Content = content;
|
||||
StatusCode = httpResponse.StatusCode;
|
||||
ReasonPhrase = httpResponse.ReasonPhrase;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the status code of the HTTP response.
|
||||
/// </summary>
|
||||
public HttpStatusCode StatusCode { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Exposes the reason phrase, typically sent along with the status code.
|
||||
/// </summary>
|
||||
public string ReasonPhrase { get; protected set; }
|
||||
}
|
||||
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
|
||||
}
|
|
@ -0,0 +1,228 @@
|
|||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Net.Http;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
|
||||
namespace Microsoft.PowerPlatform.Dataverse.Client.InternalExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Extensions for manipulating HTTP request and response objects.
|
||||
/// </summary>
|
||||
internal static class HttpExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Formats an HttpContent object as String.
|
||||
/// </summary>
|
||||
/// <param name="content">The HttpContent to format.</param>
|
||||
/// <returns>The formatted string.</returns>
|
||||
public static string AsString(this HttpContent content)
|
||||
{
|
||||
if (content != null)
|
||||
{
|
||||
// Await for the content.
|
||||
return
|
||||
content
|
||||
.ReadAsStringAsync()
|
||||
.ConfigureAwait(false)
|
||||
.GetAwaiter()
|
||||
.GetResult();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the content headers of an HtttRequestMessage.
|
||||
/// </summary>
|
||||
/// <param name="request">The request message.</param>
|
||||
/// <returns>The content headers.</returns>
|
||||
public static HttpHeaders GetContentHeaders(this HttpRequestMessage request)
|
||||
{
|
||||
if (request != null && request.Content != null)
|
||||
{
|
||||
return request.Content.Headers;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the content headers of an HttpResponseMessage.
|
||||
/// </summary>
|
||||
/// <param name="response">The response message.</param>
|
||||
/// <returns>The content headers.</returns>
|
||||
public static HttpHeaders GetContentHeaders(this HttpResponseMessage response)
|
||||
{
|
||||
if (response != null && response.Content != null)
|
||||
{
|
||||
return response.Content.Headers;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns string representation of a HttpRequestMessage.
|
||||
/// </summary>
|
||||
/// <param name="httpRequest">Request object to format.</param>
|
||||
/// <returns>The string, formatted into curly braces.</returns>
|
||||
public static string AsFormattedString(this HttpRequestMessage httpRequest)
|
||||
{
|
||||
if (httpRequest == null)
|
||||
{
|
||||
throw new ArgumentNullException("httpRequest");
|
||||
}
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
stringBuilder.AppendLine(httpRequest.ToString());
|
||||
if (httpRequest.Content != null)
|
||||
{
|
||||
stringBuilder.AppendLine();
|
||||
stringBuilder.AppendLine("Body:");
|
||||
stringBuilder.AppendLine("{");
|
||||
stringBuilder.AppendLine(httpRequest.Content.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult());
|
||||
stringBuilder.AppendLine("}");
|
||||
}
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns string representation of a HttpResponseMessage.
|
||||
/// </summary>
|
||||
/// <param name="httpResponse">Response object to format.</param>
|
||||
/// <returns>The string, formatted into curly braces.</returns>
|
||||
public static string AsFormattedString(this HttpResponseMessage httpResponse)
|
||||
{
|
||||
if (httpResponse == null)
|
||||
{
|
||||
throw new ArgumentNullException("httpResponse");
|
||||
}
|
||||
var stringBuilder = new StringBuilder();
|
||||
stringBuilder.AppendLine(httpResponse.ToString());
|
||||
if (httpResponse.Content != null)
|
||||
{
|
||||
stringBuilder.AppendLine();
|
||||
stringBuilder.AppendLine("Body:");
|
||||
stringBuilder.AppendLine("{");
|
||||
stringBuilder.AppendLine(httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false).GetAwaiter().GetResult());
|
||||
stringBuilder.AppendLine("}");
|
||||
}
|
||||
return stringBuilder.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Converts given dictionary into a log string.
|
||||
/// </summary>
|
||||
/// <typeparam name="TKey">The dictionary key type.</typeparam>
|
||||
/// <typeparam name="TValue">The dictionary value type.</typeparam>
|
||||
/// <param name="dictionary">The dictionary object.</param>
|
||||
/// <returns>The string, formatted into curly braces.</returns>
|
||||
public static string AsFormattedString<TKey, TValue>(this IDictionary<TKey, TValue> dictionary)
|
||||
{
|
||||
if (dictionary == null)
|
||||
{
|
||||
return "{}";
|
||||
}
|
||||
|
||||
return "{" + string.Join(",",
|
||||
dictionary.Select(kv => kv.Key.ToString() +
|
||||
"=" +
|
||||
(kv.Value == null ? string.Empty : kv.Value.ToString()))
|
||||
.ToArray()) + "}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes HttpHeaders as Json dictionary.
|
||||
/// </summary>
|
||||
/// <param name="headers">HttpHeaders</param>
|
||||
/// <returns>Json string</returns>
|
||||
public static JObject ToJson(this HttpHeaders headers)
|
||||
{
|
||||
if (headers == null || !headers.Any())
|
||||
{
|
||||
return new JObject();
|
||||
}
|
||||
else
|
||||
{
|
||||
return headers.ToDictionary(h => h.Key, h => h.Value).ToJson();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes header dictionary as Json dictionary.
|
||||
/// </summary>
|
||||
/// <param name="headers">Dictionary</param>
|
||||
/// <returns>Json string</returns>
|
||||
public static JObject ToJson(this IDictionary<string, IEnumerable<string>> headers)
|
||||
{
|
||||
if (headers == null || !headers.Any())
|
||||
{
|
||||
return new JObject();
|
||||
}
|
||||
else
|
||||
{
|
||||
var jObject = new JObject();
|
||||
foreach (var httpResponseHeader in headers)
|
||||
{
|
||||
if (httpResponseHeader.Value.Count() > 1)
|
||||
{
|
||||
jObject[httpResponseHeader.Key] = new JArray(httpResponseHeader.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
jObject[httpResponseHeader.Key] = httpResponseHeader.Value.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
return jObject;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Serializes HttpResponseHeaders and HttpContentHeaders as Json dictionary.
|
||||
/// </summary>
|
||||
/// <param name="message">HttpResponseMessage</param>
|
||||
/// <returns>Json string</returns>
|
||||
public static JObject GetHeadersAsJson(this HttpResponseMessage message)
|
||||
{
|
||||
if (message == null)
|
||||
{
|
||||
return new JObject();
|
||||
}
|
||||
|
||||
var jObject = new JObject();
|
||||
foreach (var httpResponseHeader in message.Headers)
|
||||
{
|
||||
if (httpResponseHeader.Value.Count() > 1)
|
||||
{
|
||||
jObject[httpResponseHeader.Key] = new JArray(httpResponseHeader.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
jObject[httpResponseHeader.Key] = httpResponseHeader.Value.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
if (message.Content != null)
|
||||
{
|
||||
foreach (var httpResponseHeader in message.Content.Headers)
|
||||
{
|
||||
if (httpResponseHeader.Value.Count() > 1)
|
||||
{
|
||||
jObject[httpResponseHeader.Key] = new JArray(httpResponseHeader.Value);
|
||||
}
|
||||
else
|
||||
{
|
||||
jObject[httpResponseHeader.Key] = httpResponseHeader.Value.FirstOrDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
return jObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
|
|
@ -32,10 +32,11 @@
|
|||
<PackageReference Include="Microsoft.Extensions.Http" Version="$(PackageVersion_Microsoft_Extensions)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="$(PackageVersion_Microsoft_Extensions)" />
|
||||
<PackageReference Include="Microsoft.Identity.Client" version="$(PackageVersion_MSAL)" />
|
||||
<PackageReference Include="Microsoft.Rest.ClientRuntime" Version="$(PackageVersion_RestClientRuntime)" />
|
||||
<!--<PackageReference Include="Microsoft.Rest.ClientRuntime" Version="$(PackageVersion_RestClientRuntime)" />-->
|
||||
<PackageReference Include="Microsoft.VisualBasic" Version="10.3.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="$(PackageVersion_Newtonsoft)" />
|
||||
<PackageReference Include="System.Configuration.ConfigurationManager" Version="$(PackageVersion_SystemConfigurationConfigurationManager)" />
|
||||
<PackageReference Include="System.Formats.Asn1" Version="8.0.1" />
|
||||
<PackageReference Include="System.Text.Json" Version="$(PackageVersion_SystemTextJson)" />
|
||||
<PackageReference Include="Microsoft.Identity.Client.Extensions.Msal" Version="$(PackageVersion_MSAL)" />
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="$(PackageVersion_Microsoft_Extensions)" />
|
||||
|
@ -44,7 +45,7 @@
|
|||
<When Condition="'$(TargetFramework)' == 'net6.0' or '$(TargetFramework)' == 'net8.0'">
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.ServiceModel.Http" version="$(PackageVersion_System_ServiceModel_PostNet6)" />
|
||||
<PackageReference Include="System.ServiceModel.Primitives" version="$(PackageVersion_System_ServiceModel_PostNet6)"/>
|
||||
<PackageReference Include="System.ServiceModel.Primitives" version="$(PackageVersion_System_ServiceModel_PostNet6)" />
|
||||
</ItemGroup>
|
||||
</When>
|
||||
<Otherwise>
|
||||
|
|
|
@ -3,7 +3,6 @@ using Microsoft.Extensions.DependencyInjection;
|
|||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.PowerPlatform.Dataverse.Client.Model;
|
||||
using Microsoft.PowerPlatform.Dataverse.Client.Utils;
|
||||
using Microsoft.Rest;
|
||||
using Microsoft.Xrm.Sdk;
|
||||
using Microsoft.Xrm.Sdk.Discovery;
|
||||
using Microsoft.Xrm.Sdk.Metadata;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Xrm.Sdk" Version="$(PackageVersion_CdsSdk)" />
|
||||
<PackageReference Include="Microsoft.Crm.Sdk.Proxy" Version="$(PackageVersion_CrmProxy)" />
|
||||
<PackageReference Include="System.Formats.Asn1" Version="8.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -2,19 +2,19 @@
|
|||
|
||||
<PropertyGroup>
|
||||
<RootNamespace>Microsoft.PowerPlatform.Dataverse.ServiceClientConverter</RootNamespace>
|
||||
<ComponentAreaName>DataverseClient</ComponentAreaName>
|
||||
<ComponentAreaName>DataverseClientConverter</ComponentAreaName>
|
||||
<SignAssembly>true</SignAssembly>
|
||||
</PropertyGroup>
|
||||
<Import Project="..\..\..\..\Build.Common.core.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net462;net472;net48</TargetFrameworks>
|
||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||
<DocumentationFile>$(OutDir)\Microsoft.PowerPlatform.Dataverse.ServiceClientConverter.xml</DocumentationFile>
|
||||
<TargetFrameworks>net462;net472;net48</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CrmSdk.XrmTooling.CoreAssembly" Version="9.1.0.110" />
|
||||
<PackageReference Include="Microsoft.PowerPlatform.Dataverse.Client" Version="1.0.0" />
|
||||
<PackageReference Include="Microsoft.CrmSdk.XrmTooling.CoreAssembly" Version="9.1.*" />
|
||||
<PackageReference Include="Microsoft.PowerPlatform.Dataverse.Client" Version="1.*" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.11.35327.3
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.PowerPlatform.Dataverse.ServiceClientConverter", "Microsoft.PowerPlatform.Dataverse.ServiceClientConverter.csproj", "{1222F666-B1B9-4219-9EA9-EDCCEFDB7687}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{1222F666-B1B9-4219-9EA9-EDCCEFDB7687}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1222F666-B1B9-4219-9EA9-EDCCEFDB7687}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1222F666-B1B9-4219-9EA9-EDCCEFDB7687}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1222F666-B1B9-4219-9EA9-EDCCEFDB7687}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {6944BCB7-36A1-45BC-AA26-489DC42D4EDA}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -7,7 +7,9 @@ using Microsoft.Extensions.Configuration;
|
|||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.PowerPlatform.Dataverse.Client;
|
||||
using Microsoft.PowerPlatform.Dataverse.Client.Auth;
|
||||
using Microsoft.PowerPlatform.Dataverse.Client.Exceptions;
|
||||
using Microsoft.PowerPlatform.Dataverse.Client.Extensions;
|
||||
using Microsoft.PowerPlatform.Dataverse.Client.HttpUtils;
|
||||
using Microsoft.PowerPlatform.Dataverse.Client.Model;
|
||||
using Microsoft.PowerPlatform.Dataverse.Client.Utils;
|
||||
using Microsoft.Xrm.Sdk;
|
||||
|
@ -138,10 +140,10 @@ namespace Client_Core_Tests
|
|||
|
||||
|
||||
// error throw.
|
||||
Microsoft.Rest.HttpOperationException operationException = new Microsoft.Rest.HttpOperationException("HTTPOPEXC");
|
||||
HttpOperationException operationException = new HttpOperationException("HTTPOPEXC");
|
||||
HttpResponseMessage Resp500 = new HttpResponseMessage(System.Net.HttpStatusCode.ServiceUnavailable);
|
||||
Resp500.Headers.Add("REQ_ID", "39393F77-8F8B-4416-846E-28B4D2AA5667");
|
||||
operationException.Response = new Microsoft.Rest.HttpResponseMessageWrapper(Resp500, "{\"error\":{\"code\":\"0x80040203\",\"message\":\"Communication activity cannot have more than one Sender party\",\"@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionSourceKey\":\"Plugin/Microsoft.Crm.Common.ObjectModel.PhoneCallService\",\"@Microsoft.PowerApps.CDS.ErrorDetails.ApiStepKey\":\"3ccabb1b-ea3e-db11-86a7-000a3a5473e8\",\"@Microsoft.PowerApps.CDS.ErrorDetails.ApiDepthKey\":\"1\",\"@Microsoft.PowerApps.CDS.ErrorDetails.ApiActivityIdKey\":\"1736f387-e025-4828-a2bb-74ea8ac768a2\",\"@Microsoft.PowerApps.CDS.ErrorDetails.ApiPluginSolutionNameKey\":\"System\",\"@Microsoft.PowerApps.CDS.ErrorDetails.ApiStepSolutionNameKey\":\"System\",\"@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionCategory\":\"ClientError\",\"@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionMesageName\":\"InvalidArgument\",\"@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionHttpStatusCode\":\"400\",\"@Microsoft.PowerApps.CDS.HelpLink\":\"http://go.microsoft.com/fwlink/?LinkID=398563&error=Microsoft.Crm.CrmException%3a80040203&client=platform\",\"@Microsoft.PowerApps.CDS.InnerError.Message\":\"Communication activity cannot have more than one Sender party\"}}");
|
||||
operationException.Response = new HttpResponseMessageWrapper(Resp500, "{\"error\":{\"code\":\"0x80040203\",\"message\":\"Communication activity cannot have more than one Sender party\",\"@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionSourceKey\":\"Plugin/Microsoft.Crm.Common.ObjectModel.PhoneCallService\",\"@Microsoft.PowerApps.CDS.ErrorDetails.ApiStepKey\":\"3ccabb1b-ea3e-db11-86a7-000a3a5473e8\",\"@Microsoft.PowerApps.CDS.ErrorDetails.ApiDepthKey\":\"1\",\"@Microsoft.PowerApps.CDS.ErrorDetails.ApiActivityIdKey\":\"1736f387-e025-4828-a2bb-74ea8ac768a2\",\"@Microsoft.PowerApps.CDS.ErrorDetails.ApiPluginSolutionNameKey\":\"System\",\"@Microsoft.PowerApps.CDS.ErrorDetails.ApiStepSolutionNameKey\":\"System\",\"@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionCategory\":\"ClientError\",\"@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionMesageName\":\"InvalidArgument\",\"@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionHttpStatusCode\":\"400\",\"@Microsoft.PowerApps.CDS.HelpLink\":\"http://go.microsoft.com/fwlink/?LinkID=398563&error=Microsoft.Crm.CrmException%3a80040203&client=platform\",\"@Microsoft.PowerApps.CDS.InnerError.Message\":\"Communication activity cannot have more than one Sender party\"}}");
|
||||
logger.Log(operationException);
|
||||
|
||||
Assert.NotNull(logger.LastError);
|
||||
|
|
|
@ -7,14 +7,14 @@
|
|||
<PackageVersion_CrmProxy>9.2.24073.11611-master</PackageVersion_CrmProxy>
|
||||
<PackageVersion_Newtonsoft>13.0.1</PackageVersion_Newtonsoft>
|
||||
<PackageVersion_RestClientRuntime>2.3.24</PackageVersion_RestClientRuntime>
|
||||
<PackageVersion_XrmSdk>9.0.2.55</PackageVersion_XrmSdk>
|
||||
<PackageVersion_XrmSdk>9.0.2.56</PackageVersion_XrmSdk>
|
||||
<PackageVersion_Dep_OutlookXrmSdk>9.0.2.34</PackageVersion_Dep_OutlookXrmSdk>
|
||||
<PackageVersion_BatchedTelemetry>3.0.8</PackageVersion_BatchedTelemetry>
|
||||
<PackageVersion_DataverseClient>1.1.22</PackageVersion_DataverseClient>
|
||||
<PackageVersion_CoverletCollector>3.1.0</PackageVersion_CoverletCollector>
|
||||
<PackageVersion_Microsoft_Extensions>3.1.8</PackageVersion_Microsoft_Extensions>
|
||||
<PackageVersion_SystemRuntime>6.0.0</PackageVersion_SystemRuntime>
|
||||
<PackageVersion_SystemTextJson>7.0.3</PackageVersion_SystemTextJson>
|
||||
<PackageVersion_SystemTextJson>8.0.4</PackageVersion_SystemTextJson>
|
||||
<PackageVersion_SystemTextEncodingsWeb>7.0.0</PackageVersion_SystemTextEncodingsWeb>
|
||||
<PackageVersion_SystemMemory>4.5.5</PackageVersion_SystemMemory>
|
||||
<PackageVersion_SystemConfigurationConfigurationManager>6.0.0</PackageVersion_SystemConfigurationConfigurationManager>
|
||||
|
|
|
@ -1443,7 +1443,7 @@
|
|||
</member>
|
||||
<member name="F:Microsoft.PowerPlatform.Dataverse.Client.ImportSolutionProperties.CONVERTTOMANAGED">
|
||||
<summary>
|
||||
Direct the system to convert any matching unmanaged customizations into your managed solution</summary>
|
||||
Obsolete. The system will convert unmanaged solution components to managed when you import a managed solution.</summary>
|
||||
</member>
|
||||
<member name="F:Microsoft.PowerPlatform.Dataverse.Client.ImportSolutionProperties.DESIREDLAYERORDERPARAM">
|
||||
<summary>
|
||||
|
|
|
@ -7,6 +7,20 @@ Notice:
|
|||
Note: Only AD on FullFramework, OAuth, Certificate, ClientSecret Authentication types are supported at this time.
|
||||
|
||||
++CURRENTRELEASEID++
|
||||
***** POSSIBLE Breaking Changes *****
|
||||
Minor Release Bump,
|
||||
Added .net 8.0 Target.
|
||||
.net 6.0 Target will be removed in a subsequent release.
|
||||
Removed dependance on Microsoft.Rest.Client. this was primary used for exception handling, and the necessary components have been reworked in to DVSC Exception management classes.
|
||||
|
||||
Fix memory consumption when too many exception are throw by DV client. Git: https://github.com/microsoft/PowerPlatform-DataverseServiceClient/issues/474
|
||||
Dependency Changes:
|
||||
Modified:
|
||||
System.Text.Json to 8.0.4
|
||||
Removed:
|
||||
Microsoft.Rest.Client - Necessary carried over in client.
|
||||
|
||||
1.1.32:
|
||||
Fix for endless retry loop issue in WebAPI calls when specific error states are encountered.
|
||||
Fix for Logging MSAL telemetry when using ILogger
|
||||
Previously, Logs for MSAL were not written to the configured ILogger, they would only go to Trace Source and InMemory Logs.
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
<dependency id="Microsoft.Extensions.Caching.Memory" version="[$PackageVersion_Microsoft_Extensions$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.Identity.Client" version="[$PackageVersion_MSAL$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.Identity.Client.Extensions.Msal" version="[$PackageVersion_MSAL$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.Rest.ClientRuntime" version="[$PackageVersion_RestClientRuntime$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="Newtonsoft.Json" version="[$PackageVersion_Newtonsoft$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Text.Json" version="[$PackageVersion_SystemTextJson$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="System.ServiceModel.Http" version="[$PackageVersion_System_ServiceModel_PreNet6$,)" />
|
||||
|
@ -35,7 +34,6 @@
|
|||
<dependency id="Microsoft.Extensions.Caching.Memory" version="[$PackageVersion_Microsoft_Extensions$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.Identity.Client" version="[$PackageVersion_MSAL$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.Identity.Client.Extensions.Msal" version="[$PackageVersion_MSAL$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.Rest.ClientRuntime" version="[$PackageVersion_RestClientRuntime$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="Newtonsoft.Json" version="[$PackageVersion_Newtonsoft$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Text.Json" version="[$PackageVersion_SystemTextJson$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="System.ServiceModel.Http" version="[$PackageVersion_System_ServiceModel_PreNet6$,)" />
|
||||
|
@ -48,7 +46,6 @@
|
|||
<dependency id="Microsoft.Extensions.Caching.Memory" version="[$PackageVersion_Microsoft_Extensions$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.Identity.Client" version="[$PackageVersion_MSAL$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.Identity.Client.Extensions.Msal" version="[$PackageVersion_MSAL$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.Rest.ClientRuntime" version="[$PackageVersion_RestClientRuntime$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="Newtonsoft.Json" version="[$PackageVersion_Newtonsoft$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Text.Json" version="[$PackageVersion_SystemTextJson$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="System.ServiceModel.Http" version="[$PackageVersion_System_ServiceModel_PreNet6$,)" />
|
||||
|
@ -75,12 +72,37 @@
|
|||
<dependency id="Microsoft.Extensions.Caching.Memory" version="[$PackageVersion_Microsoft_Extensions$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.Identity.Client" version="[$PackageVersion_MSAL$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.Identity.Client.Extensions.Msal" version="[$PackageVersion_MSAL$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.Rest.ClientRuntime" version="[$PackageVersion_RestClientRuntime$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.VisualBasic" version="10.3.0" exclude="Build,Analyzers" />
|
||||
<dependency id="Newtonsoft.Json" version="[$PackageVersion_Newtonsoft$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Configuration.ConfigurationManager" version="[$PackageVersion_SystemConfigurationConfigurationManager$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Runtime.Caching" version="4.7.0" exclude="Build,Analyzers" />
|
||||
</group>
|
||||
<group targetFramework="NET8.0">
|
||||
<dependency id="System.Collections" version="4.3.0" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Globalization" version="4.3.0" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Linq" version="4.3.0" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Linq.Expressions" version="4.3.0" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Private.DataContractSerialization" version="4.3.0" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Reflection" version="4.3.0" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Reflection.Extensions" version="4.3.0" exclude="Build,Analyzers" />
|
||||
<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="[$PackageVersion_SystemSecurityPermissions$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="System.ServiceModel.Http" version="[$PackageVersion_System_ServiceModel_PostNet6$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="System.ServiceModel.Primitives" version="[$PackageVersion_System_ServiceModel_PostNet6$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Text.Json" version="[$PackageVersion_SystemTextJson$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.Extensions.DependencyInjection" version="[$PackageVersion_Microsoft_Extensions$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.Extensions.Http" version="[$PackageVersion_Microsoft_Extensions$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.Extensions.Logging" version="[$PackageVersion_Microsoft_Extensions$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.Extensions.Caching.Memory" version="[$PackageVersion_Microsoft_Extensions$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.Identity.Client" version="[$PackageVersion_MSAL$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.Identity.Client.Extensions.Msal" version="[$PackageVersion_MSAL$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="Microsoft.VisualBasic" version="10.3.0" exclude="Build,Analyzers" />
|
||||
<dependency id="Newtonsoft.Json" version="[$PackageVersion_Newtonsoft$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Configuration.ConfigurationManager" version="[$PackageVersion_SystemConfigurationConfigurationManager$,)" exclude="Build,Analyzers" />
|
||||
<dependency id="System.Runtime.Caching" version="4.7.0" exclude="Build,Analyzers" />
|
||||
</group>
|
||||
</dependencies>
|
||||
<frameworkAssemblies>
|
||||
<frameworkAssembly assemblyName="System.Web" targetFramework=".NETFramework4.6.2, .NETFramework4.7.2, .NETFramework4.8" />
|
||||
|
|
Загрузка…
Ссылка в новой задаче