Home > OS >  Add attachment to lead in MS Dynamics using Rest API
Add attachment to lead in MS Dynamics using Rest API

Time:03-23

Does anyone know how to upload an attachment to existing lead entity in MS Dynamics using Rest API? I tried to follow this post using python code, but got an error saying

<Response [400]> b'{"error":{"code":"0x0","message":"An error occurred while validating input parameters: System.ArgumentException: Stream was not readable.\r\n at System.IO.StreamReader..ctor(Stream stream, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize, Boolean leaveOpen)\r\n at System.IO.StreamReader..ctor(Stream stream, Encoding encoding)\r\n at Microsoft.OData.JsonLight.ODataJsonLightInputContext.CreateTextReader(Stream messageStream, Encoding encoding)\r\n at Microsoft.OData.JsonLight.ODataJsonLightInputContext..ctor(ODataMessageInfo messageInfo, ODataMessageReaderSettings messageReaderSettings)\r\n at Microsoft.OData.Json.ODataJsonFormat.CreateInputContext(ODataMessageInfo messageInfo, ODataMessageReaderSettings messageReaderSettings)\r\n at Microsoft.OData.ODataMessageReader.ReadFromInput[T](Func`2 readFunc, ODataPayloadKind[] payloadKinds)\r\n at System.Web.OData.Formatter.Deserialization.ODataResourceDeserializer.Read(ODataMessageReader messageReader, Type type, ODataDeserializerContext readContext)\r\n at System.Web.OData.Formatter.ODataMediaTypeFormatter.ReadFromStream(Type type, Stream readStream, HttpContent content, IFormatterLogger formatterLogger)"}}'

Python Code

def upload_file_to_entity(url, attachment_data, version, file_name, entity_id, auth_token):
file_upload_url = f'{url}/api/data/{version}/annotations'

header_values = {
    'Authorization': auth_token,
    'Content-Type': 'application/json'
}

file_body = {
    'subject': 'Attachment Upload',
    'filename': file_name,
    '[email protected]': f'/leads({entity_id})',
    'documentbody': attachment_data
}

file_upload_res = requests.post(file_upload_url, headers=header_values, data=file_body)
print(file_upload_res)
print(file_upload_res.content)


attachment_object = s3.get_object(Bucket=bucket_name, Key=attachment_file_location)
                attachment_data = attachment_object.get('Body').read()
                attachment_data_base64 = base64.b64encode(attachment_data) 
                base64_string = attachment_data_base64.decode('utf-8')



upload_file_to_entity(f'https://{org}.crm.dynamics.com',base64_string,'v9.2',file_name,lead_id,prm_auth_token)

CodePudding user response:

Important note: documentbody attribute inside annotation entity is a Text so you should put the Base64 encoded value, for example if you want to store a text file containing The quick brown fox jumps over the lazy dog the Base64 value is VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw==

You can generate the request using my tool Dataverse REST Builder, is available as Managed Solution or XrmToolBox tool, inside the repository there are links to a video and a blog post explaining how to use it.

After you create the request and test if it works as expected inside Dataverse REST Builder.

My tool doesn't offer a Python syntax but you can export the collection to Postman. After you imported inside Postman you can generate the Python code from the request (you can see a </> button on the right menu).

Keep in mind that you will need to provide the Bearer Token in order to execute the request with Web API (probably you are already doing that as the error you are receiving it happens after the authentication is validated)

CodePudding user response:

Okay, I got it working.

Everything is correct except for the json parameter in the request object. The correct request is as below

file_upload_res = requests.post(file_upload_url, headers=header_values, json=file_body)
  • Related