"'iso-8859-1' is not a supported encoding name" exception while Decompress compressed string in Silverlight 5 using DotNetZip (Ionic.Zlib) - silverlight

I have WCF Service, consumed by Silverlight client. In the service I create a string (which is representing a .csv file) and I compress it. When I try to decompress it on the client I get the following exception:
System.ArgumentException: 'iso-8859-1' is not a supported encoding name.
Parameter name: name
at System.Globalization.EncodingTable.internalGetCodePageFromName(String name)
at System.Globalization.EncodingTable.GetCodePageFromName(String name)
at System.Text.Encoding.GetEncoding(String name)
at Ionic.Zlib.GZipStream..cctor()}
I didn't manage to find any info about what is causing this and how to be avoided. I'll be grateful for any help!
The code used is the following:
Service:
private static byte[] Zip(string str)
{
var bytes = Encoding.UTF8.GetBytes(str);
using (var msInput = new MemoryStream(bytes))
using (var msOutput = new MemoryStream())
{
using (var gs = new GZipStream(msOutput, CompressionMode.Compress))
{
msInput.CopyTo(gs);
}
return msOutput.ToArray();
}
}
Silverlight client:
private void UnzipToTheExportStream(byte[] bytes)
{
using (var msi = new MemoryStream(bytes))
using (_exportStream)
{
using (var gs = new GZipStream(msi, CompressionMode.Decompress))
{
gs.CopyTo(_exportStream);
}
}
}
The exception is happening upon the initialization of the GZipStream. For decompression I use DotNetZip (Ionic.Zlib). For compression I tried both DotNetZip and System.IO.Compression (which is not available in Silverlight) but with same result

Problem solved! At least for my case.
I have noticed that the nuget package contained 3 DLLs (Ionic.BZip2.dll/Ionic.Zip.dll/Ionic.Zlib.dll).
I have compared Ionic.Zip and Ionic.Zlib in Assemply Explorer.
The problem was solved by replacing the reference that I had from Ionic.Zlib to Ionic.Zip
Also, if you decompile "GZipStream" using ReSharper in the code above when you have reference to Ionic.Zlib and when you have reference to Ionic.Zip you will notice some difference in "usings". The first one does not have
using Ionic.Encoding;
which explains everything :)

Related

Could you use Microsoft Print to PDF printer to convert an XPS to a PDF file?

I am trying to use the Microsoft Print to PDF printer to convert an XPS to a PDF.
I Tried converting my XPS Files via commandline with GhostReader and also tried to use PdfSharp.Xps. Both of these were too slow, Taking more then 30 seconds for a 10 page XPS file. Now my question is if it is possible to set an input and output File/Path for printing when i use Microsoft print to PDF
string fileGuid = Guid.NewGuid().ToString();
string xpsFile = System.IO.Path.Combine(System.IO.Path.GetTempPath(), $"{fileGuid}.Print.xps");
string pdfFile = System.IO.Path.Combine(System.IO.Path.GetTempPath(), $"{fileGuid}.Print.pdf");
PrintDocument doc = new PrintDocument()
{
DocumentName = xpsFile,
PrinterSettings = new PrinterSettings()
{
PrinterName = "Microsoft Print to PDF",
PrintToFile = true,
PrintFileName = pdfFile,
}
};
doc.Print();
This is what i have tried. But this creates an empty .PDF file that i can't use
You can check out the LEADTOOLS SDK (disclaimer: I am an employee of this vendor) which actually supports loading and saving XPS files in C# so you do not need to use a printer to do the conversion, you can simply do it directly in your application: https://www.leadtools.com/sdk/formats#document
So you could use the toolkit to simply load an XPS and save it out as a PDF quite easily with the following code and nuget package:
Install-Package Leadtools.Document.Sdk -Version 21.0.0.2
using (DocumentConverter documentConverter = new DocumentConverter())
{
documentConverter.SetDocumentWriterInstance(new DocumentWriter();
foreach (var filename in inputFiles)
{
var jobData = new DocumentConverterJobData();
jobData.InputDocumentFileName = "input.xps";
jobData.DocumentFormat = DocumentFormat.Pdf;
jobData.OutputDocumentFileName = "output.pdf");
var job = documentConverter.Jobs.CreateJob(jobData);
documentConverter.Jobs.RunJobAsync(job);
}
}
Here is a complete tutorial on how to achieve this here: https://test.leadtools.com/help/sdk/v21/tutorials/documents/cross-platform/dotnet-core/convert-files-with-the-document-converter.html
If you would rather use a printer to do the functionality, there is the Virtual Printer Driver that supports the XPS -> PDF conversion as well:
https://www.leadtools.com/help/sdk/v21/tutorials/virtual-printer/windows/dotnet/print-to-file-using-the-virtual-printer-driver.html

Sharepoint 2010 Upload file using Silverlight 4.0

I am trying to do a file upload from Silverlight(Client Object Model) to Sharepoint 2010 library.. Please see the code below..
try{
context = new ClientContext("http://deepu-pc/");
web = context.Web;
context.Load(web);
OpenFileDialog oFileDialog = new OpenFileDialog();
oFileDialog.FilterIndex = 1;
oFileDialog.Multiselect = false;
if (oFileDialog.ShowDialog().Value == true)
{
var localFile = new FileCreationInformation();
localFile.Content = System.IO.File.ReadAllBytes(oFileDialog.File.FullName);
localFile.Url = System.IO.Path.GetFileName(oFileDialog.File.Name);
List docs = web.Lists.GetByTitle("Gallery");
context.Load(docs);
File file = docs.RootFolder.Files.Add(localFile);
context.Load(file);
context.ExecuteQueryAsync(OnSiteLoadSuccess, OnSiteLoadFailure);
}
}
catch (Exception exp)
{
MessageBox.Show(exp.ToString());
}
But I am getting the following error
System.Security.SecurityException: File operation not permitted. Access to path '' is denied.
at System.IO.FileSecurityState.EnsureState()
at System.IO.FileSystemInfo.get_FullName()
at ImageUploadSilverlight.MainPage.FileUpload_Click(Object sender, RoutedEventArgs e)
Any help would be appreciated
Thanks
Deepu
Silverlight runs with very restricted access to the client user's filesystem. When using an open-file dialog, you can get the name of the selected file within its parent folder, the length of the file, and a stream from which to read the data in the file, but not much more than that. You can't read the full path of the file selected, and you are getting the exception because you are attempting to do precisely that.
If you want to read the entire content of the file into a byte array, you'll have to replace the line
localFile.Content = System.IO.File.ReadAllBytes(oFileDialog.File.FullName);
with something like
localFile.content = ReadFully(oFileDialog.File.OpenRead());
The ReadFully method reads the entire content of a stream into a byte array. It's not a standard Silverlight method; instead it
is taken from this answer. (I gave this method a quick test on Silverlight, and it appears to work.)

WP7: Encoding.Default

I'm trying to get results from SO api in a WP7 app. I was able to get it working in a console app when I used the following code
static void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
Console.Clear();
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(RootObject));
var stream = new MemoryStream(Encoding.Default.GetBytes(e.Result));
var gzstream = new GZipInputStream(stream);
RootObject qs = ser.ReadObject(gzstream) as RootObject;
foreach (Question q in qs.questions)
{
Console.WriteLine(q.title);
}
}
the important part was Encoding.Default. If I chose anything else it would come back with Error GZIP header, first magic byte doesn't match' or something similar.
WP7 doesnt have default, it only has Unicode and UTF8 which neither of them work.
Ideas?
Don't use WebClient.DownloadString, use DownloadData. This way you'll receive the GZip-encoded bytes (which can't really be converted to string), and you can pass it directly to the GZupInputStream.
use WebRequest.BeginGetResponse instead. This way you can get the bytes as #carlosfigueria suggested but since webclient only has getstring this is a work around.

silverlight 4, dynamically loading xap modules

I know that it is possible to load xap modules dynamically using Prism or MEF framework. However, I'd like not to use those frameworks; instead load my xap files manually. So, I created the following class (adapted from internet):
public class XapLoader
{
public event XapLoadedEventHandler Completed;
private string _xapName;
public XapLoader(string xapName)
{
if (string.IsNullOrWhiteSpace(xapName))
throw new ArgumentException("Invalid module name!");
else
_xapName = xapName;
}
public void Begin()
{
Uri uri = new Uri(_xapName, UriKind.Relative);
if (uri != null)
{
WebClient wc = new WebClient();
wc.OpenReadCompleted += onXapLoadingResponse;
wc.OpenReadAsync(uri);
}
}
private void onXapLoadingResponse(object sender, OpenReadCompletedEventArgs e)
{
if ((e.Error == null) && (e.Cancelled == false))
initXap(e.Result);
if (Completed != null)
{
XapLoadedEventArgs args = new XapLoadedEventArgs();
args.Error = e.Error;
args.Cancelled = e.Cancelled;
Completed(this, args);
}
}
private void initXap(Stream stream)
{
string appManifest = new StreamReader(Application.GetResourceStream(
new StreamResourceInfo(stream, null), new Uri("AppManifest.xaml",
UriKind.Relative)).Stream).ReadToEnd();
XElement deploy = XDocument.Parse(appManifest).Root;
List<XElement> parts = (from assemblyParts in deploy.Elements().Elements()
select assemblyParts).ToList();
foreach (XElement xe in parts)
{
string source = xe.Attribute("Source").Value;
AssemblyPart asmPart = new AssemblyPart();
StreamResourceInfo streamInfo = Application.GetResourceStream(
new StreamResourceInfo(stream, "application/binary"),
new Uri(source, UriKind.Relative));
asmPart.Load(streamInfo.Stream);
}
}
}
public delegate void XapLoadedEventHandler(object sender, XapLoadedEventArgs e);
public class XapLoadedEventArgs : EventArgs
{
public Exception Error { get; set; }
public bool Cancelled { get; set; }
}
The above code works fine; I can load any xap the following way:
XapLoader xapLoader = new XapLoader("Sales.xap");
xapLoader.Completed += new XapLoadedEventHandler(xapLoader_Completed);
xapLoader.Begin();
Now, I have a UserControl called InvoiceView in the Sales.xap project, so I would like to instantiate the class. In the current project (Main.xap) I added reference to Sales.xap project, however, since I load it manually I set "Copy Local = False". But when executed, the following code throws TypeLoadException:
Sales.InvoiceView view = new Sales.InvoiceView();
It seems the code can't find InvoiceView class. But I checked that XapLoader's initXap() method was successfully executed. So why the code can't find InvoiceView class? Can someone help me with this problem?
This is based on the asker's self-answer below, rather than the question.
If you delete a project/module the output DLLs/XAP files do hang around. If you click the "show all files" button you will see some these left-over output files in your clientbin, bin and obj folders of related projects.
You can delete them individually from the project, or, when in doubt, search for all BIN and OBJ (e.g. using desktop explorer) and delete all those folders. The BIN/CLIENTBIN/OBJ folders will be recreated when needed (this the job that the "clean" option in Visual Studio should have done!)
Hope this helps.
Ok, I found the cause. The above code works. After creating a new silverlight project (Sales.xap) I happened to compile my solution once. Then I deleted App class in the Sales.xap and renamed default MainPage class to SalesView. However, no matter how many times I compile my solution, Visual Studio's development web server was loading the first version of Sales.xap (where from?), so my code couldn't find SalesView. In my host Asp.Net project I set development server's port to a different port number, and the problem gone. So the problem was with Visual Studio's development server. Apparently it is keeping compiled xap files in some temporary folder, and doesn't always update those xap files when source code changed.
What I do to avoid such problems when executing freshly compiled Silverlight is clear the browser cache, chrome even has a clear silverlight cache ;)
this XAP Cache phenomena is often due to the visual studio embedded web server (ASP.NET Development Server).
Just stop the occurence of this server and the cache will be cleared.
Start again your project and the latest build of your xap is called.

deploying winform application with embedded sqlite

I'm deploying a winform application built with vs 2008 0n XP sp3.
I created a database with empty schema which i dropped in the root folder of the project and in properties i choosed Build Action: Embedded Resources and Copy to Output directory : Copy always. Now instead of having connectionstring in the app.config connectionString section, i put an entry in appSetting: key="database";value="mydb.db;Version=3".
So to create my connectionString i used :
SQLiteConnection con = new SQLiteConnection("Data Source=" + Path.Combine(Application.StartupPath, ConfigurationManager.AppSettings["database"]));
Everything works fine and i packaged the app with a setup project.Now after i installed the app the database could not be found and i was obliged to copy the database to the Application Folder in the setup project for it to work.
what i thought is that db is supposed to be in the app dll because of copy always .but i can't access it.So what exactly did i do wrong?
i'm suspecting i should have just connected to the root db meaning not using Application.StartupPath
But i'm here asking for the best practices cause what i did is working but still looking like workaround so please can anyone share his experience with me?
thanks for reading
Embedded Resource means the database gets embedded in your dll. The Copy to output directory setting doesn't apply in this case, that's used for Build Action: Content.
With the database embedded, you basically have to un-embed it on first use. To do this read it out of the Assembly and store it to a file.
class EmbeddedResourceTest
{
public static void Test()
{
string path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Test.db");
using(var resourceStream = typeof(EmbeddedResourceTest).Assembly.GetManifestResourceStream("Test.db"))
{
using(var fileStream = File.OpenWrite(path))
{
CopyStream(resourceStream, fileStream);
}
}
// now access database using 'path'
}
public static void CopyStream(Stream inputStream, Stream outputStream)
{
CopyStream(inputStream, outputStream, 4096);
}
public static void CopyStream(Stream inputStream, Stream outputStream, int bufferLength)
{
var buffer = new byte[bufferLength];
int bytesRead;
while ((bytesRead = inputStream.Read(buffer, 0, bufferLength)) > 0)
{
outputStream.Write(buffer, 0, bytesRead);
}
}
}

Resources