Skip to content
This repository was archived by the owner on Dec 19, 2018. It is now read-only.

Asp.net core 2.1.0 RazorTemplateEngine not working #2422

Closed
eguzelkucuk opened this issue Jun 20, 2018 · 6 comments
Closed

Asp.net core 2.1.0 RazorTemplateEngine not working #2422

eguzelkucuk opened this issue Jun 20, 2018 · 6 comments
Assignees
Labels
cost: XS Will take up to half a day to complete investigate

Comments

@eguzelkucuk
Copy link

I am doing html minify on razortemplate engine on compiletime on asp.net core, but razortemplate engine does not work after updating project asp.net core 2.1.0.

It does not call CreateCodeDocument method. sample code below.

public class CustomRazorTemplateEngine : RazorTemplateEngine
{
private HtmlMinifier _htmlMinifier = new HtmlMinifier();

public CustomRazorTemplateEngine(RazorEngine engine, RazorProject project) : base(engine, project)
{
    Options.ImportsFileName = "_ViewImports.cshtml";
}

public override RazorCodeDocument CreateCodeDocument(RazorProjectItem projectItem)
{
    using (var inputStream = projectItem.Read())
    {
        using (var reader = new StreamReader(inputStream))
        {
            var text = reader.ReadToEnd();

            var markupStart = text.IndexOf("<!DOCTYPE");
            var directives = text.Substring(0, markupStart);
            var markup = text.Substring(markupStart);
            text = directives + Minify(markup);
            var byteArray = Encoding.UTF8.GetBytes(text);
            var minifiedInputStream = new MemoryStream(byteArray);

            var source = RazorSourceDocument.ReadFrom(minifiedInputStream, projectItem.PhysicalPath);
            var imports = GetImports(projectItem);

            return RazorCodeDocument.Create(source, imports);
        }
    }
}

private string Minify(string markup)
{
    MarkupMinificationResult result = _htmlMinifier.Minify(markup, string.Empty, Encoding.UTF8, true);

    if (result.Errors.Count == 0)
    {
        MinificationStatistics statistics = result.Statistics;
        if (statistics != null)
        {
            Console.WriteLine();
            Console.WriteLine($"Original size: {statistics.OriginalSize:N0} Bytes | Minified size: {statistics.MinifiedSize:N0} Bytes | Saved: {statistics.SavedInPercent:N2}%");
        }
        //Console.WriteLine($"{Environment.NewLine}Minified content:{Environment.NewLine}{Environment.NewLine}{result.MinifiedContent}");

        return result.MinifiedContent;
    }
    else
    {
        IList<MinificationErrorInfo> errors = result.Errors;

        Console.WriteLine();
        Console.WriteLine($"Found {errors.Count:N0} error(s):");

        foreach (var error in errors)
        {
            Console.WriteLine($" - Line {error.LineNumber}, Column {error.ColumnNumber}: {error.Message}");
        }

        return markup;
    }
}
}

startup.cs
services.AddSingleton<RazorTemplateEngine, CustomRazorTemplateEngine>();

@mkArtakMSFT
Copy link
Contributor

Thanks for contacting us, @eguzelkucuk.
Can you please share the complete sample for investigation?

@mkArtakMSFT
Copy link
Contributor

@ajaybhargavb, can you please look into this? The referenced thread has some info too

@ajaybhargavb
Copy link
Contributor

@eguzelkucuk, we changed the way we initialize Razor and it's extensions recently. To achieve what you are trying to do you now need to implement a custom RazorProjectFileSystem instead that returns modified RazorProjectItems. Something like below,

    public class MyRazorProjectFileSystem : RazorProjectFileSystem
    {
        private readonly RazorProjectFileSystem _inner;

        public MyRazorProjectFileSystem(RazorProjectFileSystem inner)
        {
            _inner = inner;
        }

        public override IEnumerable<RazorProjectItem> EnumerateItems(string basePath)
        {
            var items = _inner.EnumerateItems(basePath);
            return items.Select(i => new MinifiedRazorProjectItem(i));
        }

        public override RazorProjectItem GetItem(string path)
        {
            var item = _inner.GetItem(path);

            return new MinifiedRazorProjectItem(item);
        }

        private class MinifiedRazorProjectItem : RazorProjectItem
        {
            private readonly RazorProjectItem _inner;

            public MinifiedRazorProjectItem(RazorProjectItem inner)
            {
                _inner = inner;
            }

            public override string BasePath => _inner.BasePath;

            public override string FilePath => _inner.FilePath;

            public override string PhysicalPath => _inner.PhysicalPath;

            public override bool Exists => _inner.Exists;

            public override Stream Read()
            {
                return Minify(_inner.Read());
            }

            private Stream Minify(Stream markup)
            {
                // Your minification logic

                return markup;
            }
        }
    }

And then you register it in ConfigureServices like,

        // After the call to services.AddMvc()
        var descriptor = services.Single(s => s.ServiceType == typeof(RazorProjectFileSystem));
        services.AddSingleton<RazorProjectFileSystem>(s =>
        {
            var existingFileSystem = (RazorProjectFileSystem)ActivatorUtilities.GetServiceOrCreateInstance(s, descriptor.ImplementationType);
            return new MyRazorProjectFileSystem(existingFileSystem);
        });

@ajaybhargavb ajaybhargavb added the cost: XS Will take up to half a day to complete label Jul 10, 2018
@mkArtakMSFT
Copy link
Contributor

Thanks for contacting us. We believe that the question you've raised have been answered. If you still feel a need to continue the discussion, feel free to reopen it and add your comments.

@panost
Copy link

panost commented Jul 14, 2018

The RazorTemplateEngine should be removed?
I think, it is no longer used...

@NTaylorMullen
Copy link

NTaylorMullen commented Jul 16, 2018

@panost good point. We should at the very least obsolete it. Filed an issue to remove it for 3.0.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
cost: XS Will take up to half a day to complete investigate
Projects
None yet
Development

No branches or pull requests

5 participants