I have an image gallery where the images are loaded dynamically from a server, and the paths of each image is saved in MySql. Now, I want to have a "Download all images" button, so it generate a .zip with all images in the gallery.
The project is hosted on Linux, and to test the updates I use Github actions.
To create de .zip I found DotNetZip Nugget package.
When I do git push, on my Github Actions I have this error:
The type or namespace name 'Ionic' could not be found (are you missing
a using directive or an assembly reference?)
The ionic namespace is the namespace that allows me to use Zipfile.
I will show you the code...but Visual Studio has no problems.
Html:
#using(Html.BeginForm("DownloadAll", "Home", new { pedido = ViewBag.pedido}, FormMethod.Post))
{
<div>
<input class="btn btn-primary" value="Descargar Todas las Imagenes" type="submit"/>
</div>
}
Back:
public FileResult DownloadAll()
{
string consulta;
List<PedidoViewModel> listaPedidos;
try
{
listaPedidos = new List<PedidoViewModel>();
consulta = "SELECT DISTINCT p.Pedido, p.Entrega, p.Remito, e.Path, e.Fecha from Pedido p INNER JOIN Entrega e ON p.Entrega = e.Entrega WHERE p.Pedido = " + ViewBag.pedido + " GROUP by e.Path";
listaPedidos = SelectConexionMySql(consulta);
using (ZipFile zip = new ZipFile())
{
foreach (var lista in listaPedidos)
{
var archivo_nombre = lista.getPathImagen();
var archivo_arregloBytes = System.IO.File.ReadAllBytes(lista.getPathImagen());
zip.AddEntry(archivo_nombre, archivo_arregloBytes);
}
var nombreZip = "ImagenesPedido" + ViewBag.pedido;
using (MemoryStream output = new MemoryStream())
{
zip.Save(output);
return File(output.ToArray(), "application/zip", nombreZip);
}
}
}
catch (Exception ex)
{
throw new Exception(ex.ToString());
}
}
I use MySql query so I can recover the path of the images. Then, I use a foreach loop so every path I can save the name and a bytes in the zip.
So, the problem is that Github Actions cannot recognize the Ionic namespace, so, how can I create a .zip from a dinamic image gallery? I have to add something more so Github can recognize Ionic?
Related
I am trying to put all the codes that is needed to create an ASP.NetCore Web Application in a text file and then read it in an ASP.Net Core 3.1 application and compile it using Roslyn and save it as a dll file.
I tried a lot. I could do that for a Console application but not for a web application.
This is what I did
public void Load(string id, string code, IEnumerable<string> allowedAssemblyNames, IEnumerable<Type> allowedTypes, string path)
{
try
{
var _references = new List<MetadataReference>();
foreach (var assemblyName in allowedAssemblyNames)
{
_references.Add(MetadataReference.CreateFromFile(RuntimeEnvironment.GetRuntimeDirectory() + assemblyName + ".dll"));
}
foreach (var type in allowedTypes)
{
_references.Add(MetadataReference.CreateFromFile(type.Assembly.Location));
}
_references.Add(MetadataReference.CreateFromFile(Assembly.Load("netstandard").Location));
var options = new CSharpCompilationOptions(
OutputKind.DynamicallyLinkedLibrary,
reportSuppressedDiagnostics: true,
optimizationLevel: OptimizationLevel.Release,
generalDiagnosticOption: ReportDiagnostic.Error,
allowUnsafe: false);
var syntaxTree = CSharpSyntaxTree.ParseText(code, options: new CSharpParseOptions(LanguageVersion.Latest, kind: SourceCodeKind.Regular));
var compilation = CSharpCompilation.Create(id, new[] { syntaxTree }, _references, options);
assemblyLoadContext = new AssemblyLoadContext(id, true);
using (var ms = new MemoryStream())
{
var result = compilation.Emit(ms);
if (result.Success)
{
ms.Seek(0, SeekOrigin.Begin);
bytes = ms.ToArray();
File.WriteAllBytes(path, bytes);
ms.Seek(0, SeekOrigin.Begin);
assembly = assemblyLoadContext.LoadFromStream(ms);
}
}
}
catch (Exception ex)
{
throw;
}
}
Is that possible at all?
After spending some time on it, based on a discussion on GitHub, it seems it is not possible to do that.
The answer given was:
I believe it's considered unsupported by .NET Core to compile directly
against System.Private.CoreLib.dll. In general, it will probably be
quite difficult to compile an application without using the dotnet
tool and MSBuild, as you will have to effectively replicate all the
logic that goes into picking the appropriate reference assemblies,
then generating the right executing environment for the .NET Core
shared loader.
I'm trying to use Roslyn to do some mass refactoring on my code.
The idea is to remove a specific using and insert them directly in the code.
For example
using My.Awesome.Namespace;
...
var temp = MyType.Prop;
would become
var temp = My.Awesome.Namespace.MyType.Prop;
I already have a working solution for .cs files using MSBuildWorkspace to parse my solution, find the using reference and replace them in the file. But I can't find how to do the same on the cshtml files.
They do not appear in the Documents property of my project.
Any idea?
Here is the code I'm using to parse the solution
public void Process(string solutionPath, string projectName, string baseNamespace)
{
//Force import csharp projects
MSBuildLocator.RegisterDefaults();
var _ = typeof(Microsoft.CodeAnalysis.CSharp.Formatting.CSharpFormattingOption
using (var msWorkspace = MSBuildWorkspace.Create())
{
var solution = msWorkspace.OpenSolutionAsync(solutionPath).Result;
var project = solution.Projects.FirstOrDefault(x => x.Name == projectName)
if (project == null)
throw new InvalidOperationException();
foreach (var document in project.Documents)
{
if (document.SourceCodeKind != SourceCodeKind.Regular)
continue;
Console.WriteLine("Fixing file " + document.Name);
// Remove using of baseNamespace from doc
var newDoc = RemoveUsing(document, baseNamespace);
solution = solution.WithDocumentSyntaxRoot(document.Id, newDoc);
}
msWorkspace.TryApplyChanges(solution);
}
}
Here is a decent solution for scanning, parsing, compiling, and getting the semantic models for a solution's .cshtml files: Getting a SemanticModel of a cshtml file?
I am new here in the forum and I just start to work in a new web application on Visual studio 2013. I need to create an application that copy all the content from one Word Document to another. I had found this plugin that should make the job but I dont know how to put it in my code and make it work. I need to do it in a MVC application, so maybe I am not putting the code in the right place (now it is in the Model). Someone can help me telling me how to make it work? Please see the code that I have:
using Spire.Doc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace DocumentApplication.Models
{
public class HomeModel
{
public string Message { get; set; }
}
public class CopyDocument
{
Document sourceDoc = new Document("source.docx");
Document destinationDoc = new Document("target.docx");
foreach (Section sec in sourceDoc.Sections)
{
foreach (DocumentObject obj in sec.Body.ChildObjects)
{
destinationDoc.Sections[0].Body.ChildObjects.Add(obj.Clone());
}
}
destinationDoc.SaveToFile("target.docx");
System.Diagnostics.Process.Start("target.docx");
}
public class OpenDocument
{
Document document = new Document(#"C:\Users\daniel\Documents\ElAl-DRP.doc");
}
}
I cannot compile this because I have an error on the "foreach" line that says: "Invalid token 'foreach' in class' struct' or interface member declaration".
Please help me.
Thanks in advance
Okay this is pretty rough but it at least works.
I could not make the example from the Spire work, I had to make some changes.
This example will take an uploaded file, save it in to the "AppData/uploads" folder then it will create a copy of that saved file in the "AppData/copies" folder.
My Changes
the way we create the destination Doc in memory then save later.
Create a new section in the "foreach" loop
Add the cloned sections to the new section
List item
Document Format on the SaveDocument Method (This is a huge
assumption)
Controller
using System.IO;
using System.Web;
using System.Web.Mvc;
using Spire.Doc;
using Spire.Doc.Collections;
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(HttpPostedFileBase file)
{
if (file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
file.SaveAs(path);
var outputPath = Path.Combine(Server.MapPath("~/App_Data/copies"), fileName);
var sourceDoc = new Document(path);
var destinationDoc = new Document();
foreach (Section sec in sourceDoc.Sections)
{
var newSection = destinationDoc.AddSection();
foreach (DocumentObject obj in sec.Body.ChildObjects)
{
newSection.Body.ChildObjects.Add(obj.Clone());
}
}
destinationDoc.SaveToFile(outputPath, FileFormat.Docx);
}
return View();
}
}
View
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<input type="file" name="file" id="file"/>
<button type="submit">Save</button>
}
I'd like to use Roslyn to analyze semantic information within the context of a block of C# code inside a Razor View.
Is there any way (within Visual Studio 2015, or even in a unit test) to get the SemanticModel that represents this code?
Razor files contain a C# projection buffer with the generated C# code (including the parts that you don't write yourself). This buffer has full Roslyn services and is exactly what you're looking for.
You need to walk through the TextView's BufferGraph and find the CSharp buffer; you can then get its Document and semantic model.
If you're starting from the cursor location, you need simply need to map that location to a CSharp buffer.
Note that it is perfectly legal for a TextView to contain multiple CSharp buffers. (although the Razor editor will never do that)
If you aren't working in a TextView, you need to do all of this yourself; you need to run the Razor source through the Razor compiler to get the generated C# source, then compile that with Roslyn to get a semantic model.
Extract the code representing the view from the Razor view file using RazorTemplateEngine.GenerateCode and CSharpCodeProvider.GenerateCodeFromCompileUnit (or the VBCodeProvider if you want the intermediate source as VB.NET). You can then use Roslyn to parse the code.
There's an example of using Roslyn with Razor view files here.
Take note that GenerateCode carries a caveat:
This type/member supports the .NET Framework infrastructure and is not intended to be used directly from your code.
Just in case anyone else gets stuck on this, I have mini sample app which may help.
I had a CMS class like this:
public partial class CMS
{
public static string SomeKey
{
get { return (string) ResourceProvider.GetResource("some_key"); }
}
// ... and many more ...
}
... and I wanted to find out which of these were used throughout my solution for a report ... Enter Roslyn!
The following app will print out the count for the used and unused references:
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.FindSymbols;
using Microsoft.CodeAnalysis.MSBuild;
using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Razor;
namespace TranslationSniffer
{
class Program
{
static void Main(string[] args)
{
new Program().Go().Wait();
}
public async Task Go()
{
// Roslyn!
var ws = MSBuildWorkspace.Create();
// Store the translation keys...
List<string> used = new List<string>();
List<string> delete = new List<string>();
string solutionRoot = #"C:\_Code\PathToProject\";
string sln = solutionRoot + "MySolution.sln";
// Load the solution, and find all the cshtml Razor views...
var solution = await ws.OpenSolutionAsync(sln);
var mainProj = solution.Projects.Where(x => x.Name == "ConsumerWeb").Single();
FileInfo[] cshtmls = new DirectoryInfo(solutionRoot).GetFiles("*.cshtml", SearchOption.AllDirectories);
// Go through each Razor View - generate the equivalent CS and add to the project for compilation.
var host = new RazorEngineHost(RazorCodeLanguage.Languages["cshtml"]);
var razor = new RazorTemplateEngine(host);
var cs = new CSharpCodeProvider();
var csOptions = new CodeGeneratorOptions();
foreach (var cshtml in cshtmls)
{
using (StreamReader re = new StreamReader(cshtml.FullName))
{
try
{
// Let Razor do it's thang...
var compileUnit = razor.GenerateCode(re).GeneratedCode;
// Pull the code into a stringbuilder, and append to the main project:
StringBuilder sb = new StringBuilder();
using (StringWriter rw = new StringWriter(sb))
{
cs.GenerateCodeFromCompileUnit(compileUnit, rw, csOptions);
}
// Get the new immutable project
var doc = mainProj.AddDocument(cshtml.Name + ".cs", sb.ToString());
mainProj = doc.Project;
}
catch(Exception ex)
{
Console.WriteLine("Compile fail for: {0}", cshtml.Name);
// throw;
}
continue;
}
}
// We now have a new immutable solution, as we have changed the project instance...
solution = mainProj.Solution;
// Pull out our application translation list (its in a static class called 'CMS'):
var mainCompile = await mainProj.GetCompilationAsync();
var mainModel = mainCompile.GetTypeByMetadataName("Resources.CMS");
var translations = mainModel.GetMembers().Where(x => x.Kind == SymbolKind.Property).ToList();
foreach (var translation in translations)
{
var references = await SymbolFinder.FindReferencesAsync(translation, solution) ;
if (!references.First().Locations.Any())
{
Console.WriteLine("{0} translation is not used!", translation.Name);
delete.Add(translation.Name);
}
else
{
Console.WriteLine("{0} :in: {1}", translation.Name, references.First().Locations.First().Document.Name);
used.Add(translation.Name);
}
}
Console.WriteLine();
Console.WriteLine("Used references {0}. Unused references: {1}", used.Count, delete.Count);
return;
}
}
}
Roslyn only models cshtml files while they are open, but during that time they are similar to every other source file in the Workspace model.
Is there something specific you have tried that isn't working?
I have DefaultSchemaSet.xsd. Now I'm getting FileNotFoundException for the codes below. Give me any suggestion, please? May I know how to solve this?
public static void GetDefaultSchemas(string path, XmlSchemaSet schemas, ValidationEventHandler schemaValidationEventHandler)
{
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(path))
{
if (stream == null)
{
throw new FileNotFoundException("Cannot find the embedded schemas in the assembly!");
}
var schema = XmlSchema.Read(stream, schemaValidationEventHandler);
schemas.Add(schema);
}
}
Check the format of the resource name:
DefaultNamespace[.Subfolder][...MoreSubfolers].FileName[.extension]
You need to set Build Action to Embedded Resource in project's file's properties.
Also, you need to check the namespace you use for your project:
Try to examine the available resources, so you can find if a particular one present:
var executingAssembly = Assembly.GetExecutingAssembly();
var resourceNames = executingAssembly.GetManifestResourceNames();
foreach (var resourceName in resourceNames)
{
Console.WriteLine("Resource: " + resourceName);
Console.WriteLine("Contents:");
using (var sr = new StreamReader(executingAssembly.GetManifestResourceStream(resourceName)))
{
Console.WriteLine(sr.ReadToEnd());
}
}
Output:
Resource: EmbeddingTests.TextFile1.txt
Contents:
Hello
Resource: EmbeddingTests.NewFolder1.TextFile2.txt
Contents:
Hello 2
In order to make sure you can access it from your code you need to ensure that the file's build action is set to "Embedded Resource"
To help further we really need to see where the file lies in your solution (to give you an exact answer), however in the mean time if you ensure that your parameter "path" follows the pattern:
[DefaultNamespace].[AnySubFolders].[filename.fileextension]
note without the square brackets