Multipart form data

Bharathwaj

New Member
Hi,

Iam trying to upload documents to an API that uses multipart form data. Still unable to do it.
Need suggestions on how to perform.
 

Rich

Member
You should be able to do this using the Utility-HTTP object. Should just be a case of specifying the correct headers and body. Do you have any more info on the request you're trying to make?
 

Sachin_Kharmale

Active Member
Hi @Bharathwaj ,
If you want to send /upload document over API with the help of blue prism then you need to write bellow code.
In Global Code section of the Blue prism Object

C#:
  private static readonly Encoding encoding = Encoding.UTF8; 
        public static HttpWebResponse  MultipartFormPost(string postUrl, string userAgent, Dictionary<string, object> postParameters, string headerkey, string headervalue) 
        { 
            string formDataBoundary = String.Format("----------{0:N}", Guid.NewGuid()); 
            string contentType = "multipart/form-data; boundary=" + formDataBoundary; 
 
            byte[] formData = GetMultipartFormData(postParameters, formDataBoundary); 
 
            return PostForm(postUrl, userAgent, contentType, formData, headerkey, headervalue); 
        } 
        private static HttpWebResponse PostForm(string postUrl, string userAgent, string contentType, byte[] formData, string headerkey, string headervalue) 
        { 
            HttpWebRequest request = WebRequest.Create(postUrl) as HttpWebRequest; 
 
            if (request == null) 
            { 
                throw new NullReferenceException("request is not a http request"); 
            } 
 
            // Set up the request properties. 
            request.Method = "POST"; 
            request.ContentType = contentType; 
            request.UserAgent = userAgent; 
            request.CookieContainer = new CookieContainer(); 
            request.ContentLength = formData.Length; 
            
            // You could add authentication here as well if needed: 
            // request.PreAuthenticate = true; 
            // request.AuthenticationLevel = System.Net.Security.AuthenticationLevel.MutualAuthRequested; 
 
//Add header if needed 
            request.Headers.Add("isOverlayRequired", "true");
            request.Headers.Add(headerkey, headervalue); 
 
            // Send the form data to the request. 
            using (Stream requestStream = request.GetRequestStream()) 
            { 
                requestStream.Write(formData, 0, formData.Length); 
                requestStream.Close(); 
            } 
 
            return request.GetResponse() as HttpWebResponse; 
        } 
 
        private static byte[] GetMultipartFormData(Dictionary<string, object> postParameters, string boundary) 
        { 
            Stream formDataStream = new System.IO.MemoryStream(); 
            bool needsCLRF = false; 
 
            foreach (var param in postParameters) 
            { 
                  
                if (needsCLRF) 
                    formDataStream.Write(encoding.GetBytes("\r\n"), 0, encoding.GetByteCount("\r\n")); 
 
                needsCLRF = true; 
 
                if (param.Value is FileParameter) // to check if parameter if of file type   
                { 
                    FileParameter fileToUpload = (FileParameter)param.Value; 
 
                    // Add just the first part of this param, since we will write the file data directly to the Stream 
                    string header = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\nContent-Type: {3}\r\n\r\n", 
                        boundary, 
                        param.Key, 
                        fileToUpload.FileName ?? param.Key, 
                        fileToUpload.ContentType ?? "application/octet-stream"); 
 
                    formDataStream.Write(encoding.GetBytes(header), 0, encoding.GetByteCount(header)); 
 
                    // Write the file data directly to the Stream, rather than serializing it to a string. 
                    formDataStream.Write(fileToUpload.File, 0, fileToUpload.File.Length); 
                } 
                else 
                { 
                    string postData = string.Format("--{0}\r\nContent-Disposition: form-data; name=\"{1}\"\r\n\r\n{2}", 
                        boundary, 
                        param.Key, 
                        param.Value); 
                    formDataStream.Write(encoding.GetBytes(postData), 0, encoding.GetByteCount(postData)); 
                } 
            } 
 
            // Add the end of the request.  Start with a newline 
            string footer = "\r\n--" + boundary + "--\r\n"; 
            formDataStream.Write(encoding.GetBytes(footer), 0, encoding.GetByteCount(footer)); 
 
            // Dump the Stream into a byte[] 
            formDataStream.Position = 0; 
            byte[] formData = new byte[formDataStream.Length]; 
            formDataStream.Read(formData, 0, formData.Length); 
            formDataStream.Close(); 
 
            return formData; 
        } 
 
        public class FileParameter 
        { 
            public byte[] File { get; set; } 
            public string FileName { get; set; } 
            public string ContentType { get; set; } 
            public FileParameter(byte[] file) : this(file, null) { } 
            public FileParameter(byte[] file, string filename) : this(file, filename, null) { } 
            public FileParameter(byte[] file, string filename, string contenttype) 
            { 
                File = file; 
                FileName = filename; 
                ContentType = contenttype; 
            } 
        }
View attachment 1584339321838.png

Then Design code stage on object page to send file to API and use bellow code to invoke function which we have written in global code stage with bellow code in code stage.
Code:
string returnResponseText="";
string ErrorMsg="";
bool Error=true;
try { 
    string requestURL ="http://readfromimage.azurewebsites.net/";
    WebClient wc = new WebClient(); 
       byte[] bytes = System.IO.File.ReadAllBytes(fileName);
    Dictionary < string, object > postParameters = new Dictionary < string, object > (); 
    // Add your parameters here 
    postParameters.Add("file", new FileParameter(bytes, Path.GetFileName(fileName), "image/png"));
    postParameters.Add("Content-Type","multipart/form-data"); 
    string userAgent = "Someone"; 
    Dictionary<string,string> Headers=new Dictionary<string,string>();
    Headers.Add("Content-Type", "multipart/form-data");
    string headerkey="IF you want to send some header value in the request";
    string headervalue="any credential Details in Header request";
      HttpWebResponse webResponse = MultipartFormPost(requestURL, userAgent, postParameters, headerkey, headervalue);
      StreamReader responseReader = new StreamReader(webResponse.GetResponseStream()); 
    returnResponseText = responseReader.ReadToEnd(); 
    webResponse.Close(); 
} catch (Exception exp) {
    ErrorMsg=exp.Message;
    Error=false;
}
ErrorMessage = ErrorMsg;
IsError = Error;
Output=returnResponseText;

View attachment 1584339633006.png

Note: change above code as per your requirement.
I hope It will help you...!
 

Bharathwaj

New Member
Hi sachin,

Thanks for the code. Can you please explain where do i pass the file as input in the code. Also do we need to pass as binary or the data item of file path?
 

Bharathwaj

New Member
You should be able to do this using the Utility-HTTP object. Should just be a case of specifying the correct headers and body. Do you have any more info on the request you're trying to make?

Hi rich, iam unable to perform with Utility- HTTP
 

Bharathwaj

New Member
Hi sachin,

Also it would be helpful to know the procedure for using the same code under Web API definition instead of in code stage?

Thanks in advance,
 

Rich

Member
Hi rich, iam unable to perform with Utility- HTTP
Did you resolve this? It is possible just using the Utility HTTP request as I've done it before.

As long as you are:
  • sending a HTTP POST request
  • have the content type and boundary headers set
  • format the body of the API call correctly & include the document data

Here's a basic example of sending a document in raw HTTP format:

POST http://api.endpoint/api HTTP/1.1
Content-Type: multipart/form-data; boundary="123"

--123
Content-Disposition: form-data; name="file"; filename="myfile.txt"

FILE CONTENTS

--123
 

Sudheer Reddy

New Member
Hello Rich,

I am unable to format body for my scenario...Can you help me how to send JSON body along with attachment.

My requirement:
JSON body -

{
"values":{
"Request ID01":"WO0000000378524",
"Attachment Type" : "General",
"Description" : "attachment for WORKORDER:WO0000000378524",
"z2AF Work Log01":"HiTest.xls_161435.xls"
}

Attachment Information -

"key": "attach-z2AF Work Log01",
"contentType": "application/octet-stream",
"type": "file",
"src": "/C:/Users/schauksh/Desktop/HiTest.xls_161435.xls"


And also I am sharing postman screenshot also.
 

Attachments

  • PostMan.PNG
    PostMan.PNG
    9.4 KB · Views: 49
Top