0

[OP Comment/edit]

I thought I had this wrapped up, but I saved the PDF after getting this code working (huge thanks to @User9938). I can save the PDF, but when I go to open the file it does not open, but gives an "improperly encoded error"... Here is the code that creates the file (but does not allow me to save it)!! Any thoughts?

using (WebClient wc = new WebClient())
{
    //wc.Headers.Clear(); // Did not help
    wc.Headers.Add("Content-Type", "application/xml");
    wc.Encoding = System.Text.Encoding.UTF8;
            
    //var data = wc.UploadString(URI, QS1);
    //Worked with ASCII & UTF8, but UTF8 is far superior and will save you pain if you have any international symbols (non USA letters)
    Byte[] buffer =  wc.UploadData(URI, "POST", System.Text.Encoding.UTF8.GetBytes(QS1)); 
    //Byte [] buffer = wc.UploadValues(api.BaseURI, myCol);
    if (buffer != null)
    {
        Response.ContentType = "application/pdf";
        Response.AddHeader("content-length", buffer.Length.ToString());
        Response.BinaryWrite(buffer);
    }
}

Encoding Error when I try to reopen the PDF (after saving). enter image description here

[End OP Comment/edit]

My C# (.NET Framework 4.8 Code) API call returns a PDF from a URI.

The company updated their API and now I have to pass the parameters in the body (and not the querystring). This is the current "POST" version and opens the PDF in a new browser tab. How do I pass the parameters in the body (and not the Querystring)? This perfect solution took tons of digging to get it working and is a no go with the new system.

    using (WebClient wc = new WebClient())
    {
        WebClient client = new WebClient();
        Byte[] buffer = client.DownloadData(https://destinationAPI.com/Request?A=Works&B=In&C=OldVersion);
        if (buffer != null)
        {
            Response.ContentType = "application/pdf";
            Response.AddHeader("content-length", buffer.Length.ToString());
            Response.BinaryWrite(buffer);
        }
    }

My attempts: (I put notes next to lines that failed.) Thanks to a comment by @user9938, I tried various versions of this this, but still got 415 Errors.

string QS1 = "A=this&B=is&c=EasyOnceYouGetTheRightAnswer";
Uri URI = "https://Mypost.com/RequestMyPDF";
string strURI = "https://Mypost.com/RequestMyPDF";

using (WebClient wc = new WebClient())
            {
                //These 3 attempts get a 415 Error
                //Byte[] buffer =  wc.UploadData(URI, "POST", System.Text.Encoding.ASCII.GetBytes(QS1)); //415 Error
                //Byte[] buffer = wc.UploadData(URI, "POST", System.Text.Encoding.UTF8.GetBytes(QS1));//415 Error
                Byte[] buffer = wc.UploadData(strURI, "POST",System.Text.Encoding.UTF8.GetBytes(QS1));//415 Error
                if (buffer != null)
                {
                    Response.ContentType = "application/pdf";
                    Response.AddHeader("content-length", buffer.Length.ToString());
                    Response.BinaryWrite(buffer);
                }
            }

Another attempt (original attempt) I have this code that pulls the data into a streamreader, but the "Context-Type" of "text/plain" works ("application/pdf" returns a 415 Error). If I can get the streamreader into a byte[], I think I can use the code above to output my PDF in a new window.

try
{
    System.Net.WebRequest req = System.Net.WebRequest.Create(URI);
    //req.ContentType = "application/pdf" //This generates a 415 Error
    req.ContentType = "text/plain"; //This returns data,  but I don't think it will work with a PDF.
    req.Method = "POST";
    //We need to count how many bytes we're sending. Post'ed Faked Forms should be name=value&
    byte[] bytes = System.Text.Encoding.ASCII.GetBytes(Parameters);
    req.ContentLength = bytes.Length;
    System.IO.Stream os = req.GetRequestStream();
    os.Write(bytes, 0, bytes.Length); //Push it out there
    os.Close();
    System.Net.WebResponse resp = req.GetResponse();
    if (resp == null) return null;
            
    System.IO.StreamReader sr = new System.IO.StreamReader(resp.GetResponseStream());
    //READ to PDF and post in new window

    // Use ANSI encoding -also known as Encoding.GetEncoding(1252)??
    Encoding objEncoding = Encoding.Default;

    //StreamReader objSR = new StreamReader(sr.ReadToEnd().Trim(), objEncoding);
            
    //I want to open the pdf in a new tab, this is just an attempt to get ito to work... 
    //This creates an EMPTY PDF 
    StreamWriter objSW = new StreamWriter(@"c:\temp\Destination123.PDF", false, objEncoding);
    objSW.Write(sr.ReadToEnd().Trim());
    objSW.Close();
   
    //Byte[] buffer = ?? How to convert StreamWriter to BYTE!?!// (Old code was "Byte[] buffer = client.DownloadData(api.URI);")
    //if (buffer != null)
    //{
    //    Response.ContentType = "application/pdf";
    //    Response.AddHeader("content-length", buffer.Length.ToString());
    //    Response.BinaryWrite(buffer);
    //}
            
    return "Have we a PDF?!?!";
}
catch (Exception ex)
{
    return  ex.Message;
}

My stacktrace on the last 415 error:

[WebException: The remote server returned an error: (415) Unsupported Media Type.] System.Net.WebClient.UploadDataInternal(Uri address, String method, Byte[] data, WebRequest& request) +317 System.Net.WebClient.UploadData(Uri address, String method, Byte[] data) +160 System.Net.WebClient.UploadData(String address, String method, Byte[] data) +38 MyApp.Controllers.StatementsController.GetIndividualPDF(List1 model) +5328 lambda_method(Closure , ControllerBase , Object[] ) +103 System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +14 System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary2 parameters) +157 System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary2 parameters) +27 System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(IAsyncResult asyncResult, ActionInvocation innerInvokeState) +22 System.Web.Mvc.Async.WrappedAsyncResult2.CallEndDelegate(IAsyncResult asyncResult) +29 System.Web.Mvc.Async.WrappedAsyncResultBase1.End() +49 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +32 System.Web.Mvc.Async.AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f() +50 System.Web.Mvc.Async.<>c__DisplayClass48.<InvokeActionMethodFilterAsynchronouslyRecursive>b__41() +228 System.Web.Mvc.Async.<>c__DisplayClass33.<BeginInvokeActionMethodWithFilters>b__32(IAsyncResult asyncResult) +10 System.Web.Mvc.Async.WrappedAsyncResult1.CallEndDelegate(IAsyncResult asyncResult) +10 System.Web.Mvc.Async.WrappedAsyncResultBase1.End() +49 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +34 System.Web.Mvc.Async.<>c__DisplayClass2b.<BeginInvokeAction>b__1c() +26 System.Web.Mvc.Async.<>c__DisplayClass21.<BeginInvokeAction>b__1e(IAsyncResult asyncResult) +100 System.Web.Mvc.Async.WrappedAsyncResult1.CallEndDelegate(IAsyncResult asyncResult) +10 System.Web.Mvc.Async.WrappedAsyncResultBase1.End() +49 System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27 System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(IAsyncResult asyncResult, ExecuteCoreState innerState) +13 System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +29 System.Web.Mvc.Async.WrappedAsyncResultBase1.End() +49 System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +36 System.Web.Mvc.Controller.<BeginExecute>b__15(IAsyncResult asyncResult, Controller controller) +12 System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +22 System.Web.Mvc.Async.WrappedAsyncResultBase1.End() +49 System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +26 System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10 System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(IAsyncResult asyncResult, ProcessRequestState innerState) +21 System.Web.Mvc.Async.WrappedAsyncVoid1.CallEndDelegate(IAsyncResult asyncResult) +29 System.Web.Mvc.Async.WrappedAsyncResultBase`1.End() +49 System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +28 System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9836613 System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) +50 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +163

Danimal111
  • 1,976
  • 25
  • 31
  • "How to post data to specific URL using WebClient in C#": https://stackoverflow.com/questions/5401501/how-to-post-data-to-specific-url-using-webclient-in-c-sharp – Tu deschizi eu inchid Feb 11 '21 at 15:05
  • @user9938 - Thanks for that. I still get a 415. I will modify my question to include this. Seems like this should work. I get a good reply on Fiddler, but plain/text (which will not allow me to render a PDF (as far as I know). – Danimal111 Feb 11 '21 at 16:07
  • 1
    You need to specify the encoding: `wc.Encoding = System.Text.Encoding.UTF8;` before calling "UploadData". `See https://learn.microsoft.com/en-us/dotnet/api/system.net.webclient?view=netframework-4.8 – Tu deschizi eu inchid Feb 11 '21 at 17:46
  • Here's another post: https://stackoverflow.com/questions/39010572/use-webclient-to-post-query-and-download-file – Tu deschizi eu inchid Feb 11 '21 at 17:57
  • @user9938 Thanks so much. I'm trying everything in every way I can think to do it and have no idea what I'm missing. These all work for other people. I've double checked and I get data from Fiddler. I can pull data with my last script, but it's text/plain, so like I said... That's not going to work for a PDF (I don't think?) – Danimal111 Feb 11 '21 at 18:59

1 Answers1

0

!!! The following code creates the PDF and it looks perfect. I can save the PDF, but when i try to reopen the saved file, I get the following encoding error !!enter image description here

Hope this saves someone else some trouble. See comments on OP from @User9938 who was a huge help and saved me a lot of time. Thank you! Frankly, now that I have the headers correct, some of my other attempts might work also. I left them in save others from having to look each one up individually.:

using (WebClient wc = new WebClient())
{
    //wc.Headers.Clear(); // Did not help
    wc.Headers.Add("Content-Type", "application/xml");
    wc.Encoding = System.Text.Encoding.UTF8;
                
    //var data = wc.UploadString(URI, QS1);
    //Worked with ASCII & UTF8, but UTF8 is far superior and will save you pain if you have any international symbols (non USA letters)
    Byte[] buffer =  wc.UploadData(URI, "POST", System.Text.Encoding.UTF8.GetBytes(QS1)); 
    //Byte [] buffer = wc.UploadValues(api.BaseURI, myCol);
    if (buffer != null)
    {
        Response.ContentType = "application/pdf";
        Response.AddHeader("content-length", buffer.Length.ToString());
        Response.BinaryWrite(buffer);
    }
}
Danimal111
  • 1,976
  • 25
  • 31