I try to download a ZIP file form my server and need some clarification regarding the client side to use.
Infrastructure:
Client: WPF application written against .NET 4.6.1
Server: .NETCore 2.1 running as Docker container on RHEL / CENTOS 7
My server code looks as follows:
[Route("/v1/reports/invoicetemplates/download/{TenantCode}/{ReportName}", "GET", Summary = "Request to return all report template files compressed to one ZIP file.")]
public class DownloadReportTemplate : IReturn<IHttpResult>
{
public string TenantCode { get; set; }
public string ReportName { get; set; }
}
Implementation:
public object Get(DownloadReportTemplate request)
{
var templatePath = $$"/data/{request.TenantCode}/System/ReportTemplates/BizBusInvoice/{request.ReportName}";
Logger.Debug($$"The report template files should be at: {templatePath}");
if (!Directory.Exists(templatePath))
{
var msg = $$"Could not find any '{request.ReportName}' report files for tenant '{request.TenantCode}'.";
Logger.Error(msg);
throw HttpError.NotFound(msg);
}
// code to retrieve and ZIP files
var fileStream = new FileStream(zippedReportTemplates, FileMode.Open, FileAccess.Read);
var ms = new MemoryStream();
fileStream.CopyTo(ms);
File.Delete(zippedReportTemplates);
var doc4Client = new ServerDocument(ms, "ZIP", $$"{request.ReportName}ReportFiles.zip");
return doc4Client;
}
public class ServerDocument : IHasOptions, IStreamWriterAsync
{
private static readonly ILogger Logger = Log.ForContext<ServerDocument>();
private readonly Stream _responseStream;
public IDictionary<string, string> Options { get; }
public ServerDocument(Stream responseStream, string filetype, string filename)
{
_responseStream = responseStream;
Options = new Dictionary<string, string>
{
{"Content-Type", "application/octet-stream"},
{"X-Api-DocName", filename},
{"X-Api-DocType", filetype},
{"X-Api-DocLength", responseStream.Length.ToString()}
};
}
public Task WriteToAsync(Stream responseStream, CancellationToken token = new CancellationToken())
{
if (_responseStream == null)
return Task.CompletedTask;
_responseStream.WriteTo(responseStream);
responseStream.Flush();
responseStream.Dispose();
return Task.CompletedTask;
}
}
The problem starts on the Client side:
//public JsonHttpClient BizBus4WindowsClient { get; private set; } <===== result is a garbage string
public JsonServiceClient BizBus4WindowsClient { get; private set; } <===== result is OK as expected
private static async Task GetInvoiceReportTemplate(string reportTemplateFile)
{
// some code....
var apiUri = $$"/v1/reports/invoicetemplates/download/{currentApp.ActiveTenant.TenantDto.TenantCode}/Invoice";
Logger.Debug($$"Calling server: ssc.GetAsync<HttpWebResponse>({apiUri})");
HttpWebResponse response;
try
{
var ssc = currentApp.BizBus4WindowsClient;
response = await ssc.GetAsync<HttpWebResponse>(apiUri);
}
catch (WebServiceException we)
{
var msg = $$"Failed to download invoice report templates! Error: {we.ErrorMessage}";
Logger.Error(msg);
throw new BizBusException(msg);
}
catch (Exception ex)
{
var msg = $$"Failed to download invoice report templates! Error: {ex.Message}";
Logger.Error(msg);
throw new BizBusException(msg);
}
// read and process the response stream by creating a new FileStream
using (var stream = response.GetResponseStream())
{
try
{
using (var fs = new FileStream(zippedReportTemplates, FileMode.Create))
{
try
{
fs.Write(stream.ToBytes(), 0, (int)length);
}
catch (Exception exception)
{
Logger.Error($"Failed to write FileStream to file. Error: {exception}");
}
}
}
catch (Exception ex)
{
}
}
}
QUESTIONS
- When should I use
JsonHttpClient
and whenJsonServiceClient
? (With .NETCore on UNIX as the backend) - 99% of my REST calls use simple POCOs and work just fine with
JsonHTTPClient
but seem also to work withJsonServiceClient
. Is it save to useJsonServiceClient
for everything? I use PushMessaging as well… - Is it recommended to create an instance of
JsonServiceClient
in the (rare) cases where I transfer binary data and useJsonHttpClient
for the majority of calls?
What is recommended best practice and most stable implementation?
Thanks a lot for your feedback!