Skip to content

Commit

Permalink
Merge pull request #297 from microsoft/users/mbarbour/update19072022
Browse files Browse the repository at this point in the history
Resync from Main Branch - Fixes from internal and git.
  • Loading branch information
MattB-msft authored Jul 19, 2022
2 parents dfba939 + 7f0de25 commit dc278e3
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 25 deletions.
2 changes: 1 addition & 1 deletion src/Build.Shared.props
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<PackageVersion_CdsSdkProxy>4.7.6346-master</PackageVersion_CdsSdkProxy>
<PackageVersion_Newtonsoft>13.0.1</PackageVersion_Newtonsoft>
<PackageVersion_RestClientRuntime>2.3.20</PackageVersion_RestClientRuntime>
<PackageVersion_XrmSdk>9.0.2.42</PackageVersion_XrmSdk>
<PackageVersion_XrmSdk>9.0.2.45</PackageVersion_XrmSdk>
<PackageVersion_Dep_OutlookXrmSdk>9.0.2.34</PackageVersion_Dep_OutlookXrmSdk>
<PackageVersion_BatchedTelemetry>2.0.19</PackageVersion_BatchedTelemetry>
<PackageVersion_DataverseClient>0.4.20</PackageVersion_DataverseClient>
Expand Down
48 changes: 25 additions & 23 deletions src/GeneralTools/DataverseClient/Client/ConnectionService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1742,23 +1742,24 @@ internal async Task<OrganizationResponse> Command_WebAPIProcess_ExecuteAsync(Org
{
cancellationToken.ThrowIfCancellationRequested();

if (!Utilities.IsRequestValidForTranslationToWebAPI(req , inLoginFlow)) // THIS WILL GET REMOVED AT SOME POINT, TEMP FOR TRANSTION //TODO:REMOVE ON COMPELTE
if (!Utilities.IsRequestValidForTranslationToWebAPI(req , inLoginFlow))
{
logEntry.Log("Execute Organization Request failed, WebAPI is only supported for limited type of messages at this time.", TraceEventType.Error);
return null;
}

HttpMethod methodToExecute = Utilities.RequestNameToHttpVerb(req.RequestName);
Entity cReq = null;
if (req.Parameters.ContainsKey("Target") && req.Parameters["Target"] is Entity ent) // this should cover things that have targets.
if (req.Parameters.ContainsKey("Target") && req.Parameters["Target"] is Entity ent)
{
cReq = ent;
}
else if (req.Parameters.ContainsKey("Target") && req.Parameters["Target"] is EntityReference entRef) // this should cover things that have targets.
else if (req.Parameters.ContainsKey("Target") && req.Parameters["Target"] is EntityReference entRef)
{
cReq = entRef.KeyAttributes.Any()
? new Entity(entRef.LogicalName, entRef.KeyAttributes)
: new Entity(entRef.LogicalName, entRef.Id);
cReq.RowVersion = entRef.RowVersion;
}

EntityMetadata entityMetadata = null;
Expand Down Expand Up @@ -1861,7 +1862,7 @@ internal async Task<OrganizationResponse> Command_WebAPIProcess_ExecuteAsync(Org
}
else
{
DataverseOperationException opEx = new DataverseOperationException("Request Failed, RowVersion is missing and is required when ConcurrencyBehavior is set to a value other then Default.");
DataverseOperationException opEx = new DataverseOperationException("Request Failed, RowVersion is missing and is required when ConcurrencyBehavior is set to a value other than Default.");
logEntry.Log(opEx);
return null;
}
Expand Down Expand Up @@ -2145,9 +2146,16 @@ internal async Task<HttpResponseMessage> Command_WebExecuteAsync(string queryStr
foreach (var hrdProp in addedHeaders)
{
// General handling from here on out.
if (!customHeaders.ContainsKey(hrdProp.Key))
if (customHeaders.Keys.Contains(hrdProp.Key))
{
customHeaders[hrdProp.Key] = new List<string>() { hrdProp.Value };
if (customHeaders[hrdProp.Key] == null)
customHeaders[hrdProp.Key] = new List<string>();

customHeaders[hrdProp.Key].Add(hrdProp.Value);
}
else
{
customHeaders.Add(hrdProp.Key, new List<string>() { hrdProp.Value });
}
}
addedHeaders.Clear();
Expand Down Expand Up @@ -2359,30 +2367,24 @@ private bool ShouldRetryWebAPI(Exception ex, int retryCount, int maxRetryCount,
_httpRequest.RequestUri = new System.Uri(uri);

// Set Headers
// Add User Agent and request id to send.
string Agent = "Unknown";
if (AppDomain.CurrentDomain != null)
{
Agent = AppDomain.CurrentDomain.FriendlyName;
}
Agent = $"{Agent} (DataverseSvcClient:{Environs.DvSvcClientFileVersion})";

if (!_httpRequest.Headers.Contains(Utilities.RequestHeaders.USER_AGENT_HTTP_HEADER))
_httpRequest.Headers.TryAddWithoutValidation(Utilities.RequestHeaders.USER_AGENT_HTTP_HEADER, string.IsNullOrEmpty(Agent) ? "" : Agent);

if (customHeaders != null)
{
foreach (var _header in customHeaders)
{
if (_httpRequest.Headers.Count() > 0)
if (_httpRequest.Headers.Contains(_header.Key))
{
_httpRequest.Headers.Remove(_header.Key);
}
_httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value);
}

// Add User Agent and request id to send.
string Agent = "Unknown";
if (AppDomain.CurrentDomain != null)
{
Agent = AppDomain.CurrentDomain.FriendlyName;
}
Agent = $"{Agent} (DataverseSvcClient:{Environs.DvSvcClientFileVersion})";


if (!_httpRequest.Headers.Contains(Utilities.RequestHeaders.USER_AGENT_HTTP_HEADER))
_httpRequest.Headers.TryAddWithoutValidation(Utilities.RequestHeaders.USER_AGENT_HTTP_HEADER, string.IsNullOrEmpty(Agent) ? "" : Agent);

if (!_httpRequest.Headers.Contains(Utilities.RequestHeaders.X_MS_CLIENT_REQUEST_ID))
_httpRequest.Headers.TryAddWithoutValidation(Utilities.RequestHeaders.X_MS_CLIENT_REQUEST_ID, RequestId.ToString());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ public object BeforeSendRequest(ref Message request, IClientChannel channel)
}

AddExternalHeaders(httpRequestMessage);
Utilities.CleanUpHeaderKeys(httpRequestMessage.Headers);
if (httpRequestMessageObject == null)
request.Properties.Add(HttpRequestMessageProperty.Name, httpRequestMessage);
}
Expand Down
1 change: 1 addition & 0 deletions src/GeneralTools/DataverseClient/Client/ServiceClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@ internal WhoAmIResponse SystemUser
else
{
WhoAmIResponse resp = Task.Run(async () => await _connectionSvc.GetWhoAmIDetails(this).ConfigureAwait(false)).Result;
//WhoAmIResponse resp = _connectionSvc.GetWhoAmIDetails(this).Result;
_connectionSvc.CurrentUser = resp;
return resp;
}
Expand Down
24 changes: 23 additions & 1 deletion src/GeneralTools/DataverseClient/Client/Utils/Utils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,10 @@ internal static ExpandoObject ToExpandoObject(Entity sourceEntity, MetadataUtili
{
mselectValueString += $"{opt.Value},";
}
value = mselectValueString.Remove(mselectValueString.Length - 1);
if (!string.IsNullOrEmpty(mselectValueString) && mselectValueString.Last().Equals(','))
value = mselectValueString.Remove(mselectValueString.Length - 1);
else
value = null;
}
else if (value is OptionSetValue optionSetValue)
{
Expand Down Expand Up @@ -1212,5 +1215,24 @@ private static Dictionary<string, string> ConvertCookieArraysToCookieDictionary(
}
#endregion

#region HTTPHeaderCleanupSupport
/// <summary>
/// Fix for issue in .net core which is not using proper separators for User-Agent and Server Headers
/// </summary>
/// <param name="headerCollection">Collection to clean up values for</param>
/// <returns></returns>
internal static void CleanUpHeaderKeys(WebHeaderCollection headerCollection)
{
if (headerCollection.AllKeys.Contains(RequestHeaders.USER_AGENT_HTTP_HEADER))
{
string UserAgentValue = headerCollection[RequestHeaders.USER_AGENT_HTTP_HEADER];
if (UserAgentValue.Contains(","))
{
headerCollection[RequestHeaders.USER_AGENT_HTTP_HEADER] = UserAgentValue.Replace(",", " ");
}
}
}
#endregion

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ Notice:
Note: Only AD on FullFramework, OAuth, Certificate, ClientSecret Authentication types are supported at this time.

++CURRENTRELEASEID++
Fixed an issue with Custom User Agent headers incorrectly causing a format error when .net core is used. Proper User-Agent format must be used to send requests including the user agent.
Fixed an issue with an Empty OptionSetValue collection causing an ArgumentOutOfRangeException. Empty OptionSetValue collections will now be mapped to Null. Fixes https://github.com/microsoft/PowerPlatform-DataverseServiceClient/issues/292 Thanks for your report!
Fixed an issue where EntityReference based operations do not propagate RowVersion when using WebAPI protocol. Fixes https://github.com/microsoft/PowerPlatform-DataverseServiceClient/issues/296

1.0.4:
Fixed an issue with External Authentication and Connection and configuration constructor where external auth was not being respected correctly.
Fixed a bug on clone where Ilogger was not being propagated to the cloned connection correctly
Removed a call to WhoAmI during login flow as process of talking to Dataverse to verify the connection is delt with during get environment information call.
Expand Down

0 comments on commit dc278e3

Please sign in to comment.