Graeme Wellington
Graeme Wellington

Reputation: 48

Converting Java code to C# httpClient POST custom request to a conversion server

I have an example working solution in Java but I need a solution in C# that can be called from a legacy database system.

So basically create a request with custom headers, load a Word document, and send the request. The server will then convert the Word document and return the PDF which then needs to be saved to disk.

Can someone please assist.

Java Code

    import java.io.*;
    import java.net.HttpURLConnection;
    import java.net.URL;
    public class NewMain {
    public static void main(String[] args) throws IOException {
    String source =  args[0];
    String target =  args[1];
    
    URL url = new URL("http://localhost:9998");
    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
    conn.setDoOutput(true);
    conn.setRequestMethod("POST");
    conn.setRequestProperty("Content-Type", 
    "application/vnd.com.documents4j.any-msword");
    conn.setRequestProperty("Accept", "application/pdf");
    conn.setRequestProperty("Converter-Job-Priority", "1000");
    //        File wordFile = new File("C:/temp2/Sample.doc");
    File wordFile = new File(source);
    InputStream targetStream = new FileInputStream(wordFile);
    OutputStream os = conn.getOutputStream();
    long length = targetStream.transferTo(os);
    os.flush();
    if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
       throw new RuntimeException("Failed : HTTP error code : "
       + conn.getResponseCode());
    }
    InputStream in = conn.getInputStream();
    //        OutputStream out = new FileOutputStream("C:/temp2/Sample-BBB-doc.pdf");
    OutputStream out = new FileOutputStream(target);
    byte[] buffer = new byte[1024];
    int len;
    while ((len = in.read(buffer)) != -1) {
       out.write(buffer, 0, len);
    }
    in.close();
    out.close();
    os.close();
    conn.disconnect();
    }
    }

The following is C# code that I have been progressing with [Note not attempt to save the returned PDF as yet] - below this is the server response:

using System;
using System.Net;
using System.IO;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Net.Http.Headers;

namespace HttpPOST10
{
    class Program
    {
        public static string MyUri { get; private set; }
        static void Main(string[] args)
        {
            string url = "http://localhost:9998";
            Uri myUri = new Uri(url);
            string filePath = @"C:\temp2";
            string srcFilename = @"C:\temp2\Sample.doc";
            string destFileName = @"C:\temp3\Sample.pdf";
            UploadFile(url, filePath, srcFilename, destFileName);
        }
        private static bool UploadFile(string url, string filePath, string srcFilename, string destFileName)
        {
            HttpClient httpClient = new HttpClient();
            using var fileStream = new FileStream(srcFilename, FileMode.Open);
            var fileInfo = new FileInfo(srcFilename);
            var httpRequestMessage = new HttpRequestMessage
            {
                Method = HttpMethod.Post,
                RequestUri = new Uri(url),
                Headers = {
                        { HttpRequestHeader.ContentType.ToString(), "application/vnd.com.documents4j.any-msword" },
                        { HttpRequestHeader.Accept.ToString(), "application/pdf" },
                        {"Converter-Job-Priority", "1000"}
                        },
                Content = new StreamContent(fileStream)
            };
            Console.Write("httpRequestMessage:" + httpRequestMessage);
            var response = httpClient.SendAsync(httpRequestMessage).Result;
            Console.Write("response:" + response);
            return true;
        }
    }
}

Http Response:

httpRequestMessage:Method: POST, RequestUri: 'http://localhost:9998/', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
  ContentType: application/vnd.com.documents4j.any-msword
  Accept: application/pdf
  Converter-Job-Priority: 1000
}response:StatusCode: 500, ReasonPhrase: 'Request failed.', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
  Connection: close
  Content-Length: 1031
  Content-Type: text/html; charset=ISO-8859-1

Alternative Solution restSharp

I have made some progress today and managed to create a basic working solution in restSharp. This was derived from investigating how things work in Postman and starting with the generated code snippet. The challenge was getting the source document recognized so it could be uploaded (seems like a bit of confusion as to what each of the file parameters are used for):

using System;
using System.IO;
using System.Net;
using RestSharp;
using RestSharp.Extensions;

namespace HttpPOST12RestSharp
{
    class Program
    {
        static void Main(string[] args)
        {
            var source = "C:\\temp2\\Sample.doc";
            var target = @"C:\temp3\Sample-HttpPOST12RestSharp.pdf";

            var client = new RestClient("http://localhost:9998");
            client.Timeout = -1;
            var request = new RestRequest(Method.POST);
            request.AddHeader("Content-Type", "application/vnd.com.documents4j.any-msword");
            request.AddHeader("Accept", "application/pdf");
            request.AddHeader("Converter-Job-Priority", " 1000");
            request.AddParameter("application/vnd.com.documents4j.any-msword", File.ReadAllBytes(source), Path.GetFileName(source), ParameterType.RequestBody);
            IRestResponse response = client.Execute(request);

            Console.WriteLine("response.StatusCode: " + response.StatusCode);

            if (response.StatusCode != HttpStatusCode.OK)
            { 
                throw new Exception($"Unable to download file");
            }
            else
            { 
            response.RawBytes.SaveAs(target);
            Console.WriteLine("Target Document: " + target);
            }
        }
    }
}

Upvotes: 1

Views: 350

Answers (1)

Graeme Wellington
Graeme Wellington

Reputation: 48

Alternative Solution HttpClient / HttpRequestMessage

This solution uses HttpClient / HttpRequestMessage with no external libraries and saves the returned PDF response to disk.

using System;
using System.Net;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;

namespace HttpPOST10
{
    class Program
    {
        public static string MyUri { get; private set; }
        static void Main(string[] args)
        {
            string url = "http://localhost:9998";
//            string url = "http://localhost:8888"; // Fiddler
            Uri myUri = new Uri(url);
            string srcFilename = @"C:\temp2\Sample.doc";
            string destFileName = @"C:\temp3\Sample-HttpPOST10.pdf";

            UploadFileAsync(url, srcFilename, destFileName);
        }
        private static async System.Threading.Tasks.Task<bool> UploadFileAsync(string url, string srcFilename, string destFileName)
        {
            HttpClient httpClient = new HttpClient();
            byte[] data;
            data = File.ReadAllBytes(srcFilename);

            HttpContent content = new ByteArrayContent(data);
            content.Headers.Add("Content-Type", "application/vnd.com.documents4j.any-msword");

            var httpRequestMessage = new HttpRequestMessage
            {
                Method = HttpMethod.Post,
                RequestUri = new Uri(url),
                Headers = {
//                    { HttpRequestHeader.ContentType.ToString(), "application/vnd.com.documents4j.any-msword" },
                    { HttpRequestHeader.Accept.ToString(), "application/pdf" },
                    { "Converter-Job-Priority", "1000" },
                },
                Content = content
            };

            Console.Write("httpRequestMessage:" + httpRequestMessage);
            var response = httpClient.SendAsync(httpRequestMessage).Result;
            Console.Write("response:" + response);

            using (var fs = new FileStream(destFileName, FileMode.CreateNew))
            {
                await response.Content.CopyToAsync(fs);
            }

            return true;
        }
    }
}

Request / Response

httpRequestMessage:Method: POST, RequestUri: 'http://localhost:9998/', Version: 1.1, Content: System.Net.Http.ByteArrayContent, Headers: {
Accept: application/pdf Converter-Job-Priority: 1000 Content-Type: application/vnd.com.documents4j.any-msword }response:StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.StreamContent, Headers: { Vary: Accept-Encoding
Transfer-Encoding: chunked Date: Mon, 12 Apr 2021 06:49:45 GMT
Content-Type: application/pdf

Upvotes: 0

Related Questions