Skip to content

Commit 598ee95

Browse files
garg-muditroot
andauthored
Version 8.0.1-v2.1-24.2.00.00 release (#455)
Co-authored-by: root <root@devcenteradmin.docusigntest.com>
1 parent 200640f commit 598ee95

File tree

8 files changed

+114
-38
lines changed

8 files changed

+114
-38
lines changed

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# DocuSign C# Client Changelog
22

3+
## [v8.0.1] - eSignature API v2.1-24.2.00.00 - 2024-11-07
4+
### Changed
5+
- Fixed Deadlock issue with UI Apps (E.g. WinForms).
6+
- Fixed deserialization issue of text/csv type response
7+
- Removed the staging base path and OAuth path constant.
8+
- Updated the SDK release version.
9+
310
## [v8.0.0] - eSignature API v2.1-24.2.00.00 - 2024-09-06
411
### Breaking Changes
512

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ This client SDK is provided as open source, which enables you to customize its f
3333
<a id="versionInformation"></a>
3434
### Version Information
3535
- **API version**: v2.1
36-
- **Latest SDK version (Including prerelease)**: 8.0.0
36+
- **Latest SDK version (Including prerelease)**: 8.0.1
3737

3838
<a id="requirements"></a>
3939
### Requirements

sdk/DocuSign.eSign.sln

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@ Microsoft Visual Studio Solution File, Format Version 12.00
22
# Visual Studio 2012
33
VisualStudioVersion = 12.0.0.0
44
MinimumVisualStudioVersion = 10.0.0.1
5-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DocuSign.eSign", "src\DocuSign.eSign\DocuSign.eSign.csproj", "{50784E0B-2997-43AD-88AF-1400998CCD0F}"
5+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DocuSign.eSign", "src\DocuSign.eSign\DocuSign.eSign.csproj", "{54EB3C5C-3432-4E2F-ADEC-DE1DE3934C2B}"
66
EndProject
77
Global
88
GlobalSection(SolutionConfigurationPlatforms) = preSolution
99
Debug|Any CPU = Debug|Any CPU
1010
Release|Any CPU = Release|Any CPU
1111
EndGlobalSection
1212
GlobalSection(ProjectConfigurationPlatforms) = postSolution
13-
{50784E0B-2997-43AD-88AF-1400998CCD0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
14-
{50784E0B-2997-43AD-88AF-1400998CCD0F}.Debug|Any CPU.Build.0 = Debug|Any CPU
15-
{50784E0B-2997-43AD-88AF-1400998CCD0F}.Release|Any CPU.ActiveCfg = Release|Any CPU
16-
{50784E0B-2997-43AD-88AF-1400998CCD0F}.Release|Any CPU.Build.0 = Release|Any CPU
13+
{54EB3C5C-3432-4E2F-ADEC-DE1DE3934C2B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
14+
{54EB3C5C-3432-4E2F-ADEC-DE1DE3934C2B}.Debug|Any CPU.Build.0 = Debug|Any CPU
15+
{54EB3C5C-3432-4E2F-ADEC-DE1DE3934C2B}.Release|Any CPU.ActiveCfg = Release|Any CPU
16+
{54EB3C5C-3432-4E2F-ADEC-DE1DE3934C2B}.Release|Any CPU.Build.0 = Release|Any CPU
1717
EndGlobalSection
1818
GlobalSection(SolutionProperties) = preSolution
1919
HideSolutionNode = FALSE

sdk/src/DocuSign.eSign/Client/Auth/OAuth.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,6 @@ public class OAuth
3737
public static string Demo_OAuth_BasePath = "account-d.docusign.com";
3838
// Production server base path
3939
public static string Production_OAuth_BasePath = "account.docusign.com";
40-
// Stage server base path
41-
public static string Stage_OAuth_BasePath = "account-s.docusign.com";
4240

4341
// OAuth ResponseType constants
4442
// used by public/native client applications.

sdk/src/DocuSign.eSign/Client/Configuration.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public class Configuration
2626
/// Version of the package.
2727
/// </summary>
2828
/// <value>Version of the package.</value>
29-
public const string Version = "8.0.0";
29+
public const string Version = "8.0.1";
3030

3131
/// <summary>
3232
/// Identifier for ISO 8601 DateTime Format

sdk/src/DocuSign.eSign/Client/DocuSignClient.cs

Lines changed: 97 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ public class DocuSignClient
4343
public const string Production_REST_BasePath = "https://www.docusign.net/restapi";
4444
// Sandbox/Demo base path
4545
public const string Demo_REST_BasePath = "https://demo.docusign.net/restapi";
46-
// Stage base path
47-
public const string Stage_REST_BasePath = "https://stage.docusign.net/restapi";
4846

4947
protected string basePath = Demo_REST_BasePath;
5048

@@ -317,6 +315,47 @@ public string ParameterToString(object obj)
317315
return Convert.ToString(obj);
318316
}
319317

318+
/// <summary>
319+
/// Parses a CSV-formatted string and converts it into a list of dictionaries,
320+
/// where each dictionary represents a record with column headers as keys.
321+
/// </summary>
322+
/// <param name="content">The CSV-formatted string to be deserialized.</param>
323+
/// <returns>A list of dictionaries, each containing key-value pairs of column headers and their corresponding values.</returns>
324+
private object DeserializeStringToCsv(string content)
325+
{
326+
var records = new List<Dictionary<string, object>>();
327+
328+
// Split the CSV string into lines
329+
var lines = content.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
330+
331+
// Check if there are any lines
332+
if (lines.Length > 0)
333+
{
334+
// Read the header line
335+
string[] headers = lines[0].Split(',');
336+
337+
// Read the rest of the lines
338+
for (int i = 1; i < lines.Length; i++)
339+
{
340+
string[] values = lines[i].Split(',');
341+
var record = new Dictionary<string, object>();
342+
343+
for (int j = 0; j < headers.Length; j++)
344+
{
345+
// Ensure we don't exceed the number of values
346+
if (j < values.Length)
347+
{
348+
record[headers[j]] = values[j]; // Store the value in the dictionary
349+
}
350+
}
351+
352+
records.Add(record); // Add the record to the list
353+
}
354+
}
355+
356+
return records; // Return the list of records
357+
}
358+
320359
/// <summary>
321360
/// Deserialize the JSON string into a proper object.
322361
/// </summary>
@@ -345,6 +384,11 @@ public object Deserialize(DocuSignResponse response, Type type)
345384
return ConvertType(response.Content, type);
346385
}
347386

387+
if(response.ContentType == "text/csv")
388+
{
389+
return DeserializeStringToCsv(response.Content);
390+
}
391+
348392
// at this point, it must be a model (json)
349393
try
350394
{
@@ -724,10 +768,6 @@ public void SetOAuthBasePath(string oauthBaseUri = null)
724768
{
725769
this.oAuthBasePath = OAuth.Demo_OAuth_BasePath;
726770
}
727-
else if (baseUri.Host.StartsWith("apps-s") || baseUri.Host.StartsWith("stage"))
728-
{
729-
this.oAuthBasePath = OAuth.Stage_OAuth_BasePath;
730-
}
731771
else
732772
{
733773
this.oAuthBasePath = OAuth.Production_OAuth_BasePath;
@@ -774,8 +814,14 @@ private static T TryCatchWrapper<T>(Func<T> func)
774814
/// </returns>
775815
public OAuth.OAuthToken GenerateAccessToken(string clientId, string clientSecret, string code)
776816
{
777-
CancellationTokenSource cts = new CancellationTokenSource();
778-
return TryCatchWrapper(() => GenerateAccessTokenAsync(clientId, clientSecret, code, cts.Token).ConfigureAwait(false).GetAwaiter().GetResult());
817+
using (var cts = new CancellationTokenSource())
818+
{
819+
return TryCatchWrapper(() => {
820+
var task = Task.Run(async () => await GenerateAccessTokenAsync(clientId, clientSecret, code, cts.Token));
821+
task.Wait();
822+
return task.Result;
823+
});
824+
}
779825
}
780826

781827
/// <summary>
@@ -790,7 +836,7 @@ public OAuth.OAuthToken GenerateAccessToken(string clientId, string clientSecret
790836
/// ApiException if the HTTP call status is different than 2xx.
791837
/// IOException if there is a problem while parsing the reponse object.
792838
/// </returns>
793-
public async Task<OAuth.OAuthToken> GenerateAccessTokenAsync(string clientId, string clientSecret, string code, CancellationToken cancellationToken)
839+
public async Task<OAuth.OAuthToken> GenerateAccessTokenAsync(string clientId, string clientSecret, string code, CancellationToken cancellationToken = default)
794840
{
795841
if (string.IsNullOrEmpty(clientId) || string.IsNullOrEmpty(clientSecret) || string.IsNullOrEmpty(code))
796842
{
@@ -840,8 +886,14 @@ public OAuth.OAuthToken GenerateAccessToken(string clientId, string clientSecret
840886
/// <returns>The User Info model.</returns>
841887
public OAuth.UserInfo GetUserInfo(string accessToken)
842888
{
843-
CancellationTokenSource cts = new CancellationTokenSource();
844-
return TryCatchWrapper(() => GetUserInfoAsync(accessToken, cts.Token).ConfigureAwait(false).GetAwaiter().GetResult());
889+
using (var cts = new CancellationTokenSource())
890+
{
891+
return TryCatchWrapper(() => {
892+
var task = Task.Run(async () => await GetUserInfoAsync(accessToken, cts.Token));
893+
task.Wait();
894+
return task.Result;
895+
});
896+
}
845897
}
846898

847899
/// <summary>
@@ -850,7 +902,7 @@ public OAuth.UserInfo GetUserInfo(string accessToken)
850902
/// <param name="accessToken"></param>
851903
/// <param name="cancellationToken">A CancellationToken which can be used to propagate notification that operations should be canceled. </param>
852904
/// <returns>The User Info model.</returns>
853-
public async Task<OAuth.UserInfo> GetUserInfoAsync(string accessToken, CancellationToken cancellationToken)
905+
public async Task<OAuth.UserInfo> GetUserInfoAsync(string accessToken, CancellationToken cancellationToken = default)
854906
{
855907
if (string.IsNullOrEmpty(accessToken))
856908
{
@@ -913,7 +965,7 @@ protected static RSA CreateRSAKeyFromPem(string key)
913965
/// <param name="clientId">Docusign OAuth Client Id(AKA Integrator Key)</param>
914966
/// <param name="userId">Docusign user Id to be impersonated(This is a UUID)</param>
915967
/// <param name="oauthBasePath"> Docusign OAuth base path
916-
/// <see cref="OAuth.Demo_OAuth_BasePath"/> <see cref="OAuth.Production_OAuth_BasePath"/> <see cref="OAuth.Stage_OAuth_BasePath"/>
968+
/// <see cref="OAuth.Demo_OAuth_BasePath"/> <see cref="OAuth.Production_OAuth_BasePath"/>
917969
/// <seealso cref="GetOAuthBasePath()" /> <seealso cref="SetOAuthBasePath(string)"/>
918970
/// </param>
919971
/// <param name="privateKeyStream">The Stream of the RSA private key</param>
@@ -924,8 +976,14 @@ protected static RSA CreateRSAKeyFromPem(string key)
924976
/// <returns>The JWT user token</returns>
925977
public OAuth.OAuthToken RequestJWTUserToken(string clientId, string userId, string oauthBasePath, Stream privateKeyStream, int expiresInHours, List<string> scopes = null)
926978
{
927-
CancellationTokenSource cts = new CancellationTokenSource();
928-
return TryCatchWrapper(() => RequestJWTUserTokenAsync(clientId, userId, oauthBasePath, privateKeyStream, expiresInHours, scopes, cts.Token).ConfigureAwait(false).GetAwaiter().GetResult());
979+
using (var cts = new CancellationTokenSource())
980+
{
981+
return TryCatchWrapper(() => {
982+
var task = Task.Run(async () => await RequestJWTUserTokenAsync(clientId, userId, oauthBasePath, privateKeyStream, expiresInHours, scopes, cts.Token));
983+
task.Wait();
984+
return task.Result;
985+
});
986+
}
929987
}
930988

931989
/// <summary>
@@ -935,7 +993,7 @@ public OAuth.OAuthToken RequestJWTUserToken(string clientId, string userId, stri
935993
/// <param name="clientId">Docusign OAuth Client Id(AKA Integrator Key)</param>
936994
/// <param name="userId">Docusign user Id to be impersonated(This is a UUID)</param>
937995
/// <param name="oauthBasePath"> Docusign OAuth base path
938-
/// <see cref="OAuth.Demo_OAuth_BasePath"/> <see cref="OAuth.Production_OAuth_BasePath"/> <see cref="OAuth.Stage_OAuth_BasePath"/>
996+
/// <see cref="OAuth.Demo_OAuth_BasePath"/> <see cref="OAuth.Production_OAuth_BasePath"/>
939997
/// <seealso cref="GetOAuthBasePath()" /> <seealso cref="SetOAuthBasePath(string)"/>
940998
/// </param>
941999
/// <param name="privateKeyStream">The Stream of the RSA private key</param>
@@ -945,12 +1003,12 @@ public OAuth.OAuthToken RequestJWTUserToken(string clientId, string userId, stri
9451003
/// <see cref="OAuth.Scope_SIGNATURE"/> <see cref="OAuth.Scope_IMPERSONATION"/> <see cref="OAuth.Scope_EXTENDED"/>
9461004
/// </param>
9471005
/// <returns>The JWT user token</returns>
948-
public Task<OAuth.OAuthToken> RequestJWTUserTokenAsync(string clientId, string userId, string oauthBasePath, Stream privateKeyStream, int expiresInHours, List<string> scopes = null, CancellationToken cancellationToken = default)
1006+
public async Task<OAuth.OAuthToken> RequestJWTUserTokenAsync(string clientId, string userId, string oauthBasePath, Stream privateKeyStream, int expiresInHours, List<string> scopes = null, CancellationToken cancellationToken = default)
9491007
{
9501008
if (privateKeyStream != null && privateKeyStream.CanRead && privateKeyStream.Length > 0)
9511009
{
9521010
byte[] privateKeyBytes = ReadAsBytes(privateKeyStream);
953-
return this.RequestJWTUserTokenAsync(clientId, userId, oauthBasePath, privateKeyBytes, expiresInHours, scopes, cancellationToken);
1011+
return await this.RequestJWTUserTokenAsync(clientId, userId, oauthBasePath, privateKeyBytes, expiresInHours, scopes, cancellationToken);
9541012
}
9551013
else
9561014
{
@@ -965,7 +1023,7 @@ public OAuth.OAuthToken RequestJWTUserToken(string clientId, string userId, stri
9651023
/// <param name="clientId">Docusign OAuth Client Id(AKA Integrator Key)</param>
9661024
/// <param name="userId">Docusign user Id to be impersonated(This is a UUID)</param>
9671025
/// <param name="oauthBasePath"> Docusign OAuth base path
968-
/// <see cref="OAuth.Demo_OAuth_BasePath"/> <see cref="OAuth.Production_OAuth_BasePath"/> <see cref="OAuth.Stage_OAuth_BasePath"/>
1026+
/// <see cref="OAuth.Demo_OAuth_BasePath"/> <see cref="OAuth.Production_OAuth_BasePath"/>
9691027
/// <seealso cref="GetOAuthBasePath()" /> <seealso cref="SetOAuthBasePath(string)"/>
9701028
/// </param>
9711029
/// <param name="privateKeyBytes">The byte contents of the RSA private key</param>
@@ -976,8 +1034,15 @@ public OAuth.OAuthToken RequestJWTUserToken(string clientId, string userId, stri
9761034
/// <returns>The JWT user token</returns>
9771035
public OAuth.OAuthToken RequestJWTUserToken(string clientId, string userId, string oauthBasePath, byte[] privateKeyBytes, int expiresInHours, List<string> scopes = null)
9781036
{
979-
CancellationTokenSource cts = new CancellationTokenSource();
980-
return TryCatchWrapper(() => RequestJWTUserTokenAsync(clientId, userId, oauthBasePath, privateKeyBytes, expiresInHours, scopes, cts.Token).ConfigureAwait(false).GetAwaiter().GetResult());
1037+
1038+
using (var cts = new CancellationTokenSource())
1039+
{
1040+
return TryCatchWrapper(() => {
1041+
var task = Task.Run(async () => await RequestJWTUserTokenAsync(clientId, userId, oauthBasePath, privateKeyBytes, expiresInHours, scopes, cts.Token));
1042+
task.Wait();
1043+
return task.Result;
1044+
});
1045+
}
9811046
}
9821047

9831048
/// <summary>
@@ -987,7 +1052,7 @@ public OAuth.OAuthToken RequestJWTUserToken(string clientId, string userId, stri
9871052
/// <param name="clientId">Docusign OAuth Client Id(AKA Integrator Key)</param>
9881053
/// <param name="userId">Docusign user Id to be impersonated(This is a UUID)</param>
9891054
/// <param name="oauthBasePath"> Docusign OAuth base path
990-
/// <see cref="OAuth.Demo_OAuth_BasePath"/> <see cref="OAuth.Production_OAuth_BasePath"/> <see cref="OAuth.Stage_OAuth_BasePath"/>
1055+
/// <see cref="OAuth.Demo_OAuth_BasePath"/> <see cref="OAuth.Production_OAuth_BasePath"/>
9911056
/// <seealso cref="GetOAuthBasePath()" /> <seealso cref="SetOAuthBasePath(string)"/>
9921057
/// </param>
9931058
/// <param name="privateKeyBytes">The byte contents of the RSA private key</param>
@@ -1068,7 +1133,7 @@ public OAuth.OAuthToken RequestJWTUserToken(string clientId, string userId, stri
10681133
/// </summary>
10691134
/// <param name="clientId">Docusign OAuth Client Id(AKA Integrator Key)</param>
10701135
/// <param name="oauthBasePath"> Docusign OAuth base path
1071-
/// <see cref="OAuth.Demo_OAuth_BasePath"/> <see cref="OAuth.Production_OAuth_BasePath"/> <see cref="OAuth.Stage_OAuth_BasePath"/>
1136+
/// <see cref="OAuth.Demo_OAuth_BasePath"/> <see cref="OAuth.Production_OAuth_BasePath"/>
10721137
/// <seealso cref="GetOAuthBasePath()" /> <seealso cref="SetOAuthBasePath(string)"/>
10731138
/// </param>
10741139
/// <param name="privateKeyBytes">The byte contents of the RSA private key</param>
@@ -1079,16 +1144,22 @@ public OAuth.OAuthToken RequestJWTUserToken(string clientId, string userId, stri
10791144
/// <returns>The JWT application token</returns>
10801145
public OAuth.OAuthToken RequestJWTApplicationToken(string clientId, string oauthBasePath, byte[] privateKeyBytes, int expiresInHours, List<string> scopes = null)
10811146
{
1082-
CancellationTokenSource cts = new CancellationTokenSource();
1083-
return TryCatchWrapper(() => RequestJWTApplicationTokenAsync(clientId, oAuthBasePath, privateKeyBytes, expiresInHours, scopes, cts.Token).ConfigureAwait(false).GetAwaiter().GetResult());
1147+
using (var cts = new CancellationTokenSource())
1148+
{
1149+
return TryCatchWrapper(() => {
1150+
var task = Task.Run(async () => await RequestJWTApplicationTokenAsync(clientId, oAuthBasePath, privateKeyBytes, expiresInHours, scopes, cts.Token));
1151+
task.Wait();
1152+
return task.Result;
1153+
});
1154+
}
10841155
}
10851156

10861157
/// <summary>
10871158
/// *RESERVED FOR PARTNERS* RequestJWTApplicationTokenAsync
10881159
/// </summary>
10891160
/// <param name="clientId">Docusign OAuth Client Id(AKA Integrator Key)</param>
10901161
/// <param name="oauthBasePath"> Docusign OAuth base path
1091-
/// <see cref="OAuth.Demo_OAuth_BasePath"/> <see cref="OAuth.Production_OAuth_BasePath"/> <see cref="OAuth.Stage_OAuth_BasePath"/>
1162+
/// <see cref="OAuth.Demo_OAuth_BasePath"/> <see cref="OAuth.Production_OAuth_BasePath"/>
10921163
/// <seealso cref="GetOAuthBasePath()" /> <seealso cref="SetOAuthBasePath(string)"/>
10931164
/// </param>
10941165
/// <param name="privateKeyBytes">The byte contents of the RSA private key</param>

sdk/src/DocuSign.eSign/DocuSign.eSign.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<RootNamespace>DocuSign.eSign</RootNamespace>
1717
<AssemblyName>DocuSign.eSign</AssemblyName>
1818
<NeutralLanguage>en-US</NeutralLanguage>
19-
<VersionPrefix>8.0.0</VersionPrefix>
19+
<VersionPrefix>8.0.1</VersionPrefix>
2020
<VersionSuffix/>
2121
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
2222
<GenerateDocumentationFile>true</GenerateDocumentationFile>
@@ -26,7 +26,7 @@
2626
<PackageLicenseUrl>https://github.com/docusign/docusign-esign-csharp-client/blob/master/LICENSE</PackageLicenseUrl>
2727
<RepositoryUrl>https://github.com/docusign/docusign-esign-csharp-client</RepositoryUrl>
2828
<RepositoryType>git</RepositoryType>
29-
<PackageReleaseNotes>[v8.0.0] - ESignature API v2.1-24.2.00.00 - 9/6/2024</PackageReleaseNotes>
29+
<PackageReleaseNotes>[v8.0.1] - ESignature API v2.1-24.2.00.00 - 11/7/2024</PackageReleaseNotes>
3030
</PropertyGroup>
3131
<PropertyGroup Condition=" '$(TargetFramework)' == 'net462'">
3232
<DefineConstants>NET462</DefineConstants>

sdk/src/DocuSign.eSign/Properties/AssemblyInfo.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,5 @@
2222
// [assembly: AssemblyVersion("1.0.*")]
2323
internal class AssemblyInformation
2424
{
25-
public const string AssemblyInformationalVersion = "8.0.0";
25+
public const string AssemblyInformationalVersion = "8.0.1";
2626
}

0 commit comments

Comments
 (0)