C # (.Net 4.8 Framework) Как изменить параметры строки запроса в вызове API POST из заголовка в тело и открыть PDF в новой вкладке

[Комментарий / редактирование OP]

Я думал, что все это упаковано, но я сохранил PDF-файл после того, как этот код заработал (огромное спасибо @ User9938). Я могу сохранить PDF-файл, но когда я открываю файл, он не открывается, но выдает неправильно закодированную ошибку ... Вот код, который создает файл (но не позволяет мне его сохранить) !! Есть предположения?

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);
    }
}

Ошибка кодирования при попытке повторно открыть PDF (после сохранения). введите описание изображения здесь

[Конец комментария / редактирования OP]

Мой вызов API C # (код .NET Framework 4.8) возвращает PDF-файл из URI.

Компания обновила свой API, и теперь мне нужно передавать параметры в теле (а не в строке запроса). Это текущая версия POST, которая открывает PDF-файл в новой вкладке браузера. Как передать параметры в теле (а не в строке запроса)? Это идеальное решение потребовало огромных усилий для того, чтобы заставить его работать, и с новой системой его не пойдут.

    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);
        }
    }

Мои попытки: (Я помещаю заметки рядом с неудачными строками.) Благодаря комментарию @ user9938 я пробовал различные версии этого this, но по-прежнему обнаружено 415 ошибок.

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);
                }
            }

Еще одна попытка (исходная попытка). У меня есть этот код, который извлекает данные в средство чтения потоков, но работает Context-Type text / plain (application / pdf возвращает ошибку 415). Если мне удастся поместить средство чтения в byte [], я думаю, что смогу использовать приведенный выше код для вывода моего PDF-файла в новом окне.

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;
}

Моя трассировка стека на последней ошибке 415:

[WebException: удаленный сервер возвратил ошибку: (415) Неподдерживаемый тип носителя.] System.Net.WebClient.UploadDataInternal (адрес Uri, метод String, данные Byte [], WebRequest и запрос) +317 System.Net.WebClient.UploadData ( Адрес Uri, метод String, данные Byte []) +160 System.Net.WebClient.UploadData (адрес String, метод String, данные Byte []) +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) +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. ystem.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. .Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest (результат IAsyncResult) +9 System.Web.CallHandlerExecutionStep.System.Web.HttpApplication. +50 System.Web.HttpApplication.ExecuteStep (шаг IExecutionStep, логическое значение и завершено синхронно) +163


person Danimal111    schedule 11.02.2021    source источник
comment
Как отправлять данные по определенному URL-адресу с помощью WebClient в C #: stackoverflow.com/questions/5401501/   -  person user9938    schedule 11.02.2021
comment
@ user9938 - Спасибо за это. Я все еще получаю 415. Я изменю свой вопрос, чтобы включить это. Похоже, это должно сработать. Я получаю хороший ответ на Fiddler, но простой / текстовый (который не позволяет мне отображать PDF-файл (насколько я знаю).   -  person Danimal111    schedule 11.02.2021
comment
Вам необходимо указать кодировку: wc.Encoding = System.Text.Encoding.UTF8; перед вызовом UploadData. `См. docs.microsoft.com/ en-us / dotnet / api /   -  person user9938    schedule 11.02.2021
comment
Вот еще одно сообщение: stackoverflow.com/questions/39010572/   -  person user9938    schedule 11.02.2021
comment
@ user9938 Большое спасибо. Я пытаюсь сделать все, что только могу, и понятия не имею, что мне не хватает. Все это работает на других людей. Я дважды проверил и получил данные от Fiddler. Я могу извлекать данные с помощью моего последнего скрипта, но он текстовый / простой, поэтому, как я уже сказал ... Это не сработает для PDF (я не думаю?)   -  person Danimal111    schedule 11.02.2021


Ответы (1)


!!! Следующий код создает PDF-файл, и он выглядит идеально. Я могу сохранить PDF-файл, но когда я пытаюсь снова открыть сохраненный файл, я получаю следующую ошибку кодирования !! введите изображение  описание здесь

Надеюсь, это избавит кого-то от неприятностей. См. Комментарии к OP от @ User9938, который очень помог мне и сэкономил мне много времени. Спасибо! Честно говоря, теперь, когда у меня есть правильные заголовки, некоторые из моих других попыток также могут сработать. Я оставил их, чтобы другим не приходилось искать каждого в отдельности.

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);
    }
}
person Danimal111    schedule 11.02.2021