docusign / docusign-esign-csharp-client

The Official Docusign C# Client Library used to interact with the eSignature REST API. Send, sign, and approve documents using this client.
https://developers.docusign.com/docs/esign-rest-api/sdks/csharp/
MIT License
129 stars 159 forks source link

How should I use EnvelopesApi.UpdateDocument? #357

Open eg-bernardo opened 2 years ago

eg-bernardo commented 2 years ago

I'm talking about this method: https://developers.docusign.com/docs/esign-rest-api/reference/envelopes/envelopedocuments/update/ There it says:

The bytes of the document make up the body of the request

but the signature of the method is:

public EnvelopeDocument UpdateDocument(string accountId, string envelopeId, string documentId)

Calling that method as is, returns:

{
  "errorCode": "INVALID_REQUEST_PARAMETER",
  "message": "The request contained at least one invalid parameter. A filename was not found in the Content-Disposition header ('filename=\"filename.ext\""
}

I've also tried to provide the file by replacing the RestClient, and adding this to the IRestRequest using:

req.AddHeader("Content-Disposition", "filename=\"my_file.docx\"");
req.AddFile("my_file.docx", pathToFile, "application/vnd.openxmlformats-officedocument.wordprocessingml.document");

but then I get:

{
  "errorCode": "FORMAT_CONVERSION_ERROR",
  "message": "The data could not be converted."
}
GlorianaMarinDS commented 2 years ago

Hello, I'm Gloriana from DocuSign Developer Support.

I'll be happy to assist with this, would you be able to provide a complete code snippet (without exposing any sensitive information) so we can have better context for this issue? Thank you.

eg-bernardo commented 2 years ago

The main issue is that EnvelopesApi.UpdateDocuments signature is wrong as far as I understand. As per https://developers.docusign.com/docs/esign-rest-api/reference/envelopes/envelopedocuments/update/, this method is used to update a file, but I cannot see how to provide it using EnvelopesApi.UpdateDocument.

var envelopeApi = new EnvelopesApi(apiClient);
// where do file bytes and name go?
var res = envelopeApi.UpdateDocument(accountId, "<envelope id>", "1");
GlorianaMarinDS commented 2 years ago

Hi @eg-bernardo, you are correct on this, the SDK method is wrong and has been reported internally as a bug. In this case, you will have to add new documents and delete old documents with the SDK method while this is looked into internally.

niramber commented 1 year ago

and update on this?

gchaudhary7472 commented 1 year ago

Hi @GlorianaMarinDS

I debugged this and found that the issue is with UpdateDocumentWithHttpInfo method inside UpdateDocument method call. The value is not set for localVarHttpContentDisposition = "form-data;name="\fileXml\";filename=\"file.xml\";

Not sure if the above is the correct value for a PDF. Please have the correct value in place and update the fix ASAP.

Below is the error we get while making call to UpdateDocument method:- Call - public EnvelopeDocument UpdateDocument(string accountId, string envelopeId, string documentId, byte[] documentFileBytes)

Exception - { "errorCode": "INVALID_REQUEST_PARAMETER", "message": "The request contained at least one invalid parameter. A filename was not found in the Content-Disposition header ('filename=\"filename.ext\"" }

Thanks Gaurav

esukmonica commented 1 year ago

any updates on this?

aaston86 commented 11 months ago

Resolving the bug such that EnvelopesApi.UpdateDocument correctly attempts to set the Content-Disposition header will reveal another far more insidious bug in SystemNetHttpClient.BuildRequestMessage where the line requestMessage.Content.Headers.Add("Content-Disposition", request.ContentDisposition); will fail if the content disposition string contains an equals sign (which it must for update document). The fix is to use Headers.TryAddWithoutValidation instead of Headers.Add.

gchaudhary7472 commented 11 months ago

@aaston86 Sure if that works well and good. @GlorianaMarinDS - any update as to when this will be fixed.

leifjones commented 7 months ago

HT @lukasparsons for the collab...

In case it helps someone else, here is how we are working around this issue:

protected async Task UploadOrReplaceDocument(string envelopeId, string documentId, byte[] bytesToUpload, string fileName)
{
    HttpRequestMessage request;
    try
    {
        request = new HttpRequestMessage(HttpMethod.Put,
            $"{_requestItemsService.ApplicationSession.BasePath}/restapi/v2.1/accounts/{_docuSignJwtSettings.AccountId}/envelopes/{envelopeId}/documents/{documentId}");
        request.Headers.Add("Authorization", $"Bearer {_requestItemsService.ApplicationUser.AccessToken}");
        var content = new ByteArrayContent(bytesToUpload);
        content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/pdf");
        content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment") { FileName = fileName };
        request.Content = content;
        // If or when this GitHub issue is resolved, we may be able to switch to the following single line version of the above.
        // https://github.com/docusign/docusign-esign-csharp-client/issues/357
        //EnvelopeDocument response = await EnvelopesApi.UpdateDocumentAsync(_docuSignJwtSettings.AccountId, envelopeId, documentId, bytesToUpload);
    }
    catch (Exception e)
    {
        Log.Error("Error occurred preparing DocuSign request for uploading replacement pdf", e);
        throw;
    }

    // ... method continues
}