I have byte array for the silverlight XAP . I need to extract all the dll's inside the xap from the byte array. Once I get the dll's I need to extract the assemblies from it.Silverlight XAP is stored in a repository and the repository always return me XAP byte array .Is there any Standard API available in C# to achieve this functionality ?If not how can we achieve this ?
Regards,Abhishek
Create a MemoryStream from your byte array and call this function:
public List<Assembly> ExtractAssembliesFromXap(Stream stream) {
List<Assembly> assemblies = new List<Assembly>();
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));
assemblies.Add(asmPart.Load(streamInfo.Stream));
}
return assemblies;
}
There's no standard API available, but it shouldn't be hard to do. A XAP file is just a ZIP file with a different extension. Use a library like DotNetZip or SharpZipLib to get to its contents (these libraries can accept a stream or byte array, so you should be able to pass your XAP byte array straight into them to extract the files). I'm not sure what you mean by getting the DLLs and extracting the assemblies from them - the DLLs you extract from the XAP file are the assemblies.
Hope this helps...
Chris
Related
Is it possible to render .rdlc reports with ASP.NET Core? Currently this only seems to be possible if I target the .NET Framework as opposed to .NET Core.
I don't need a report viewer I just need to render the results of an .rdlc report as a byte array.
If you want to create pdf/excel/word using rdlc report I recommend you can use AspNetCore.Reporting library. This is open source and comes as a nuget package. you can integrate this in your .NET Core API or .NET Core Azure function. You can generate a byte array convert it to base 64 string and retrieve that to your client side. More on the link in the comment.
You very well can render rdlc into a byte array. Please see a related question I asked a while back. RDLC Local report viewer for ASP.NET Core and Angular(>2.0).
Eventually a creative discussion on that thread resulted in an angular package(https://www.npmjs.com/package/ng2-pdfjs-viewer - Disclosure; I am the author) with consumable rdlc byte array functionality on client side. Of course, instead of this package, you may choose another javascript library to display the byte array.
A simple usage on angular would be like this. Please note, most of the code can be reused even if you are using plain js or another framework.
The below code demonstrates
1. Spitting byte array using RDLC report viewer control on aspnet core action method(on server side) and sending it over wire using http. (Code is in C#)
2. Processing response's byte array into a blob object (Js)
3. Feeding blob object into ng2-pdfjs-viewer.
4. ng2-pdfjs-viewer internally uses Mozilla's PDFJS to accomplish the feat of displaying the PDF on browser.
(FYI.. I took code from samples provided on ng2-pdfjs-viewer package. Replace step 3 and 4 if you are using another library or plain javascript)
<!-- your.component.html -->
<button (click)="showPdf();">Show</button>
<div style="width: 800px; height: 400px">
<ng2-pdfjs-viewer #pdfViewer></ng2-pdfjs-viewer>
</div>
export class MyComponent implements OnInit {
#ViewChild('pdfViewer') pdfViewer
...
private downloadFile(url: string): any {
return this.http.get(url, { responseType: ResponseContentType.Blob }).map(
(res) => {
return new Blob([res.blob()], { type: "application/pdf" });
});
}
public showPdf() {
let url = "http://localhost/api/GetMyPdf";
this.downloadFile(url).subscribe(
(res) => {
this.pdfViewer.pdfSrc = res; // <---- pdfSrc can be Blob or Uint8Array
this.pdfViewer.refresh(); // Ask pdf viewer to load/reresh pdf
}
);
}
[HttpGet]
[Route("MyReport")]
public IActionResult GetReport()
{
var reportViewer = new ReportViewer {ProcessingMode = ProcessingMode.Local};
reportViewer.LocalReport.ReportPath = "Reports/MyReport.rdlc";
reportViewer.LocalReport.DataSources.Add(new ReportDataSource("NameOfDataSource1", reportObjectList1));
reportViewer.LocalReport.DataSources.Add(new ReportDataSource("NameOfDataSource2", reportObjectList1));
Warning[] warnings;
string[] streamids;
string mimeType;
string encoding;
string extension;
var bytes = reportViewer.LocalReport.Render("application/pdf", null, out mimeType, out encoding, out extension, out streamids, out warnings);
return File(bytes, "application/pdf")
}
In case anyone is still looking for a similar solution, I would recommend using "ReportViewerCore.NETCore".
Here is the nuGet reference - https://www.nuget.org/packages/ReportViewerCore.NETCore/
Here is the github link to the repo - https://github.com/lkosson/reportviewercore/
Basic usage
Stream reportDefinition; // your RDLC from file or resource
IEnumerable dataSource; // your datasource for the report
LocalReport report = new LocalReport();
report.LoadReportDefinition(reportDefinition);
report.DataSources.Add(new ReportDataSource("source", dataSource));
report.SetParameters(new[] { new ReportParameter("Parameter1", "Parameter value") });
byte[] pdf = report.Render("PDF");
You can not render .rdlc reports in .NET Core, using .rdlc as a byte array.
Rendering RDLC reports relies on WinForms and WebForms and is currently only supported on .NET Framework. Hopefully Microsoft will make a (slimmed down) version available (just rendering the reports for starters) on .NET Core or .NET 5, but no word as of yet.
As an alternative, you could go for a solution where you run report rendering as a separate ASP.NET 2 app targeting .NET Framework, while the rest of your app could target .NET Core 3 or later. That way, you can call the reporting endpoints with the appropriate data, and it returns a rendered report.
This is what I've done, creating a sort of microservices architecture where multiple .Net Core 3.1 apps can post both the XML RDLC report definition and data to an endpoint running on net48, which uses the LocalReport class to render the report to the desired format, returning it as a byte array.
Angular app | ----> | APIs (.Net Core 3.1) | ----> | API (.Net Framework 4.8)
I have a mvc 4.5 application where I show a grid. The first column of the grid is a document name. The document name is an hyper link to the actual document that is hosted on our site and is available via a url. The documents can be pdf or doc or ppt. I can access these documents only via url and I do not have access to the actual physical document on our server.
I am providing users an option to select one or many of these documents from the grid and then they can download them. What I am trying to achieve is read each of the selected documents via the url and write it to a zip file and make the zip file downloadable. So users will be downloading one file instead of multiple files.
I have tried to stream the documents via url in memory and then add it to the zip file using ZipArchive Library from Microsoft. This is not working for me.
I was able to add documents that was on disk to zip file using Zip Archive and it works great. But I do not have access to the physical document as I can access the documents only through URL. My next option is to download each of these documents into a temp location on server and then add it to zip file using Zip Archive.But I am trying to avoid downloading files into a temp location
Please suggest how I can achieve reading documents via url in memory and adding each of these document to zip file and make zip file downloadable.
Any help will be appreciated.
Thank you Cbroe for commenting. I figured the answer. The problem was I was reading the pdf from the url and convert it to a memory stream and then was trying to add the memory stream to ZipArchive which was not working but instead I extracted the byte array out of the memory stream and then added it to the zip archive and it worked.
Here is the code snippet that might be useful for some one. My first contribution to Stack OverFlow.
public FileResult DownloadZip()
{
MemoryStream memoryStream = new MemoryStream();
using (var archive = new ZipArchive(memoryStream, ZipArchiveMode.Create, true))
{
var demoFile = archive.CreateEntry("Pdf123.pdf");
var convertedStream = ConvertTobyte("http://www.example.com/Pdf123.pdf");
using (var entryStream = demoFile.Open())
{
entryStream.Write(convertedStream, 0, convertedStream.Length);
}
demoFile = archive.CreateEntry("Pdf456.pdf");
convertedStream = ConvertTobyte("http://www.example.com/Pdf456.pdf");
using (var entryStream = demoFile.Open())
{
entryStream.Write(convertedStream, 0, convertedStream.Length);
}
}
//This option is to write the zip to your local disk
using (var fileStream = new FileStream(#"C:\Temp\test.zip", FileMode.Create))
{
memoryStream.Seek(0, SeekOrigin.Begin);
memoryStream.CopyTo(fileStream);
}
//This option is to donload the zip via browser
memoryStream.Seek(0, SeekOrigin.Begin);
return new FileStreamResult(memoryStream, "application/zip")
{
FileDownloadName = "Archive.zip"
};
}
private static byte[] ConvertTobyte(string fileUrl)
{
byte[] imageData = null;
using (var wc = new System.Net.WebClient())
imageData = wc.DownloadData(fileUrl);
return imageData;
}
all examples show how to read an xml from an local file. But how do I read a xml from a url or a stream and process it further?
Example: http://www.oreillynet.com/xml/blog/2006/03/hello_saxon_on_net_an_aspnet_i.html
thanks in advance
Look for XsltExamples.cs in the saxon-resources download available on both Sourceforge and www.saxonica.com. The very first example seems to do what you are asking for.
public static void ExampleSimple1(String sourceUri, String xsltUri) {
// Create a Processor instance.
Processor processor = new Processor();
// Load the source document
XdmNode input = processor.NewDocumentBuilder().Build(new Uri(sourceUri));
// Create a transformer for the stylesheet.
XsltTransformer transformer = processor.NewXsltCompiler().Compile(new Uri(xsltUri)).Load();
// Set the root node of the source document to be the initial context node
transformer.InitialContextNode = input;
// Create a serializer
Serializer serializer = new Serializer();
serializer.SetOutputWriter(Console.Out);
// Transform the source XML to System.out.
transformer.Run(serializer);
}
Are you using an XmlDocument object for reading the XML? If so, you'll want XMLDocument.Load() method, which can take a file path or URL, TextReader or Stream as input.
Likewise, XDocument.Load()(msdn.microsoft.com/en-us/library/system.xml.linq.xdocument.load(v=vs.110).aspx) has a similar set of overloads.
I'm trying to return a stream in WCF 3.5 using a REST-Style URL instead of SOAP. The idea is to read a file from SharePoint 2010, then pass it back to the client. (We have reasons for doing it this way instead of using SharePoint services, but I digress.) It appears as though the only way to send the file is by writing it to the filesystem using one FileStream, then using File.OpenRead to return the stream back to the client. Using a MemoryStream doesn't seem to work. IE prompts for the file save, but the file comes down as like 2KB and then can't be read of course because it's not all there. Any ideas?
SPListItemCollection lookupFld2 = docLibrary.GetItems(spQuery2);
if (lookupFld2.Count > 0)
{
WebOperationContext.Current.OutgoingResponse.ContentType =
"application/octet-stream";
WebOperationContext.Current.OutgoingResponse.Headers.Add(
"Content-Disposition","attachment; filename=" + lookupFld2[0].File.Name);
MemoryStream memoryStream =
(MemoryStream)lookupFld2[0].File.OpenBinaryStream();
memoryStream.Position = 0;
return memoryStream;
}
Technically, OpenBinaryStream only returns a general Stream instance NOT a MemoryStream (http://msdn.microsoft.com/en-us/library/ms470901.aspx). If you want a MemoryStream you need to create a new one and copy the contents from the BinaryStream into the MemoryStream then reset the position and return it.
I've been searching for it and I've not been able to find it. I wanted to know if it is possible to Zip a folder without any external dll nor any external references - just with native features.
I've been able to Zip files with System.IO.Packaging, but it does not include folders and I cannot tell it to Zip the parent folder.
I know there are external dll and so, but I'd like to know if it's possible to make it from a native way.
Thank you.
Your best bet is to use a 3rd party library. But if you can't I found this blog post that describes how to do it using System.IO.Packaging. Note this is c# not vb, but the example use of the framework is all you should need.
http://weblogs.asp.net/albertpascual/archive/2009/05/18/creating-a-folder-inside-the-zip-file-with-system-io-packaging.aspx
private static void AddFileToZip(string zipFilename, string fileToAdd, string sDirectory)
{
using (Package zip = System.IO.Packaging.Package.Open(zipFilename, FileMode.OpenOrCreate))
{
string destFilename = ".\\" + sDirectory + "\\" + Path.GetFileName(fileToAdd);
Uri uri = PackUriHelper.CreatePartUri(new Uri(destFilename, UriKind.Relative));
if (zip.PartExists(uri))
{
zip.DeletePart(uri);
}
PackagePart part = zip.CreatePart(uri, "", CompressionOption.Normal);
using (FileStream fileStream = new FileStream(fileToAdd, FileMode.Open, FileAccess.Read))
{
using (Stream dest = part.GetStream())
{
CopyStream(fileStream, dest);
}
}
}
}
That post references another post by Jon Galloway that talks about 3rd party libraries and doing it manually. That is a good reference as well.