Search code examples
c#asp.net-mvcrazorengine

What is the best way to create multiple xml files and export it as one zip file


My Project is in ASP.NET MVC, Right now I am using Razor Engine Service (RazorEngineService.RunCompile) to create multiple XML files and making it as a single Zip file and exporting it.

But the problem is that when we pass the model object each time to process the template and return it as separate XML files and completing the whole operation it takes more time to complete (Almost ~40 Seconds for 10 objects) for whole content to export.

Is there anything wrong with my current approach or am I doing it correctly right now? Please guide me If I am doing any mistakes in this approach.

private FileInfo Export(List<Model> modelList)
  {
        string timeStr = Datetime.Now.ToString();
        string archiveFileName = "Main.zip";
        string archivePath = Path.Combine(_reportFolderPath, archiveFileName);

        using (ZipArchive archive = ZipFile.Open(archivePath, ZipArchiveMode.Create))
    {
        foreach (var list in modelList)
        {
            string fileName = model.name + model.Id;
            string filePath = GetModelExport(list, fileName, timeStr);
            archive.CreateEntryFromFile(filePath, fileName + ".xml");
        }
        archive.Dispose();
    }
    return new FileInfo(archivePath);
}

private string GetModelExport(Model model, string fileName, string timeStr)
{
    var processedTemplate = ProcessTemplate(model, TemplateName, TemplateKey);
    string reportFilelName = fileName + "_" + timeStr + ".xml";
    string filePath = Path.Combine(_reportFolderPath, reportFilelName);

    using (var file = new StreamWriter(filePath))
    {
        file.Write(processedTemplate);
    }
    return filePath;
}

private string ProcessTemplate(Model model, string templateName, string templateKey)
    {
        var templateFilePath = Path.Combine(_reportTemplateFolder, templateName);
        return ReportUtils.ProcessTemplate(templateFilePath, templateKey, model);
    }
public static string ProcessTemplate(string templatePath, string templateKey, object model = null)
{
    var templateService = RazorEngineService.Create();
    var result = templateService.RunCompile(File.ReadAllText(templatePath), templateKey, null, model);

    return result;
}

Solution

  • some of your code is missing so i cant see the whole picture, this is what i would start with..... gd luck.

    
    public class HolderTempName 
    {
        private TemplateService _templateService;
        private Dictionary<string, string> _templateContainer;
        
        public HolderTempName()
        {
            //this will save creating this everytime
            _templateService = RazorEngineService.Create();
            
            //this will hold the template so it does not have to fetch on each loop,
            //if the same template is used.
            _templateContainer = new Dictionary<string, string>();
        }
    
    
        //you will need to tweeek this to get the type out 
        private string GetTemplate(string templateName, templatePath)
        {
            if(!_templateContainer.Conatains(templateName))
            {
                var text = File.ReadAllText(templatePath);
                _templateContainer[templateName]  = text;
            }
            return _templateContainer[templateName];
        }
    
    
        private FileInfo Export(List<Model> modelList)
        {
            string timeStr = Datetime.Now;
            string archiveFileName = "Main.zip";
            string archivePath = Path.Combine(_reportFolderPath, archiveFileName);
    
    
            using (ZipArchive archive = ZipFile.Open(archivePath, ZipArchiveMode.Create))
            {
                foreach (var item in modelList)
                {
                    var templateFilePath = Path.Combine(_reportTemplateFolder, TemplateName); //<--TemplateName seems like a local private
                    //these should come from where cant see where...
                    var template = GetTemplate( TemplateName, templateFilePath)
                    
                    string modelResponse  = ProcessModel(item,template,TemplateKey ); //<-- why is not passing in the template
                    //step 2; 
                    //making this above done in parrell and then add aync, but before all that measure what is taking time
                    
                    string pathname = MakeFileName(_reportFolderPath, reportFilelName, timeStr);
                    SaveToDisk(pathname, modelResponse);
                    
                    string fileName = model.name + model.Id;
                    archive.CreateEntryFromFile(filePath, fileName + ".xml");
                }
                archive.Dispose();
            }
            return new FileInfo(archivePath);
        }
    
        private string MakeFileName(string path ,string filename, string tStamp)
        {
            string reportFilelName = fileName + "_" + timeStr + ".xml";
            string filePath = Path.Combine(_reportFolderPath, reportFilelName);
            return filePath;
        }
    
        private void SaveToDisk(string filePath, string content)
        {
            using (var file = new StreamWriter(filePath))
            {
                file.Write(processedTemplate);
            }
        }
        
        public static string ProcessTemplate(object model, string template, templateKey)
        {
            var result = templateService.RunCompile(template, templateKey, null, model);
            return result;
        }
    }