Reputation: 7
I am facing problem for download ing pdf file from api via c# code.I have already asked this questions in stackoverflow and I have get the answer from stackoverflow with below source code. This source code works fine only in visual Studio 2012 and above version. But I am using visual Studio 2010 with .Net framework 4.0 version. The below code is not working in visual Studio 2010 due compatibility issue (asynch and await keyword not supported). My question is what is the alternate source code for working in visual Studio 2010.
static string url = "https://einvoicing.internal.cleartax.co/v2/eInvoice/download?irns=7b46fb61d6e0883bdfdfb997ca25c4b5629d3062241532f6e8e6fcdfc0a95c9a";
static HttpClient client = new HttpClient();
static async Task DownloadCurrentAsync(string StrInvoiceNo)
{
client.DefaultRequestHeaders.Add("owner_id", "78c6beda-54a2-11ea-b064-0af3f8b02c24");
client.DefaultRequestHeaders.Add("gstin", "29AAFCD5862R000");
HttpResponseMessage response = await client.GetAsync(url);
response.EnsureSuccessStatusCode(); // <= Will throw if unsuccessful
using (FileStream fileStream = new FileStream(StrInvoiceNo.Replace("/","-") + ".pdf", FileMode.Create, FileAccess.Write, FileShare.None))
{
//copy the content from response to filestream
await response.Content.CopyToAsync(fileStream);
System.Diagnostics.Process.Start(StrInvoiceNo.Replace("/", "-") + ".pdf");
}
}
Upvotes: 0
Views: 384
Reputation:
You can use WebClient
that is supported by Visual Studio 2010 (since .NET Framework 2.0):
using System.Net
using ( var client = new WebClient() )
{
client.Headers.Add("owner_id", "78c6beda-54a2-11ea-b064-0af3f8b02c24");
client.Headers.Add("gstin", "29AAFCD5862R000");
client.DownloadFile(url, destPath);
}
There is also this supported method: DownloadFileAsync
.
That you can use like that:
using System.Net
using System.ComponentModel;
using ( var client = new WebClient() )
{
Exception ex = null;
bool finished = false;
client.Headers.Add("owner_id", "78c6beda-54a2-11ea-b064-0af3f8b02c24");
client.Headers.Add("gstin", "29AAFCD5862R000");
client.DownloadProgressChanged += progress;
client.DownloadFileCompleted += completed;
client.DownloadFileAsync(new Uri(url), destPath);
while ( !finished )
{
Thread.Sleep(100);
//Application.DoEvents();
}
if ( ex != null ) throw ex;
// Do progress
void progress(object sender, DownloadProgressChangedEventArgs e)
{
//
}
// Download completed
void completed(object sender, AsyncCompletedEventArgs e)
{
finished = true;
if ( e.Error == null ) return;
HttpStatusCode code = 0;
WebExceptionStatus status = 0;
if ( e.Error is WebException we )
{
status = we.Status;
if ( we.Response is HttpWebResponse response )
code = response.StatusCode;
}
ex = new WebException(e.Error.Message + Environment.NewLine + Environment.NewLine +
url + Environment.NewLine + Environment.NewLine +
status.ToString() + Environment.NewLine +
code.ToString());
}
}
Instead of creating and throwing a new exception after error information extracted, as we can put to trash the e.Error
exception, you can use a boolean and check it for the result and use a string message to show if needed.
At the top instead of Exception ex = null;
:
bool isSuccess = true;
At the end instead of ex = new WebException(...)
:
isSuccess = false;
string errorMessage = e.Error.Message + Environment.NewLine + Environment.NewLine +
url + Environment.NewLine + Environment.NewLine +
status.ToString() + Environment.NewLine +
code.ToString());
Hence instead of if ( ex != null ) throw ex;
:
if ( !isSuccess ) ...
Also, I see that when we don't provide user info, the file is successfully downloaded but it is not a PDF, it is a text file, JSon it seems:
{"error_code":"102","error_message":"Invoice with the selected Input is not present in the Database","error_source":"CLEARTAX"}
So after download you can check if the file if a PDF (first line starting with some header like %PDF), or manage this result.
Upvotes: 3