Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation update to improve usage experience: @Inherits directive #13

Closed
AndyMDoyle opened this issue Apr 8, 2020 · 11 comments
Closed

Comments

@AndyMDoyle
Copy link

Firstly thank you for this project. I have battled with various other packages and couldn't get them to work reliably with .NET Core 3.1 running in an Azure Function. Yours works perfectly.

Here's something I feel would improve the user experience if it was documented...

For anyone who is storing their templates in CSHTML files either in the file system or as an embedded resource, the lack of the @model and @using statements mean you can't benefit from Visual Studio's IntelliSense when editing the files. You end up with lots of warnings in the code whereever you reference @Model.Property, or @include (if you are implementing the @include support from your wiki).

I have found that when using a strongly typed model, adding an @inherits directive to the file greatly improves this.

@inherits RazorEngineCore.RazorEngineTemplateBase<MyModel>

Or in my case where I'm using a custom template base to implement the include functionality, I'm using:

@inherits FunctionsApp1.Email.CustomRazorEngineTemplateBase<MyClassLib.EmailModels.WelcomeModel>

I hope this helps.

@adoconnection
Copy link
Owner

Thank you for the kind words. Im surprised RazorEngine dont mind to see several @include directives :)

https://github.com/adoconnection/RazorEngineCore/wiki/Switch-from-RazorEngine-cshtml-templates

@Sushi21
Copy link

Sushi21 commented Apr 8, 2021

@AndyMDoyle

Im trying to run few tests before deciding to use or not that library for our future pdf engine

I'm having some compile error when Im adding that line at the top of my template

image
Do I miss any nuget other that RazorEngineCore?

I'm using Core3.1 API

@jackhamby
Copy link

can we get this opened up again. the linked issue is completely separate. im having the same issue running in net5.0
error

@adoconnection
Copy link
Owner

I have attached sample ConsoleApp48 that runs on NET5

  • dont forget to put full namespace in inherits: @inherits RazorEngineCore.RazorEngineTemplateBase<ConsoleApp48.EmailModel>
  • Autocomplete works in VS2019 but not in VS2022 preview

ConsoleApp48.zip

using RazorEngineCore;
using System;
using System.IO;

namespace ConsoleApp48
{
    class Program
    {
        static void Main(string[] args)
        {
            RazorEngine razorEngine = new RazorEngine();
            string templateText = File.ReadAllText("Template.cshtml");

            IRazorEngineCompiledTemplate<RazorEngineTemplateBase<EmailModel>> compiledTemplate = razorEngine.Compile<RazorEngineTemplateBase<EmailModel>>(templateText);

            string result = compiledTemplate.Run(instance => {
                instance.Model = new EmailModel
                {
                    Email = "mail@example.com",
                    FirstName = "Jack"
                };
            });

            Console.WriteLine(result);

            Console.ReadKey();
        }
    }
}
namespace ConsoleApp48
{
    public class EmailModel
    {
        public string Email { get; set; }
        public string FirstName { get; set; }
    }
}
@inherits RazorEngineCore.RazorEngineTemplateBase<ConsoleApp48.EmailModel>

<html>
    <body>
        <h1>Hello @Model.FirstName</h1>
    </body>
</html>

@jackhamby
Copy link

thanks for taking a look. i ran your stuff locally and it does work perfectly.

the code you have for the template and compiling is nearly exactly the same as what we have.

main difference i see is this is a console app whereas we have ASP.NET core MVC app.

i spun up an mvc app that tries to compile a single template with the @inherits directive and return an OK result with the resulting string. it blows up in the same way as our actual application (which is during the build with the same errors i posted above)

if you clone this repo and try to build it, you should see the same
https://github.com/jackhamby/RazorEngineCoreError

again thanks for looking, any advice is greatly appreciated

@wdcossey
Copy link
Contributor

wdcossey commented Jul 16, 2021

The most likely scenario is that the .cshtml is being compiled automatically during the build process (i.e via Sdk.Razor.CurrentVersion.props.
Basically you are building an MVC app so it will try compile all the .cshtml files it finds.

A simple workaround is to rename the file extension or change the way the file is handled in the .csproj

@jackhamby
Copy link

thanks @wdcossey.
changing the extension does work, i did .cshtml -> .mcshtml and i was able to compile successfully.
do you know how to handle this in the .csproj instead? it would be nice to keep .cshtml extention so at least VS recognizes the extension.

@wdcossey
Copy link
Contributor

@jackhamby something like the following.

<Project Sdk="Microsoft.NET.Sdk.Web">

    <PropertyGroup>
        <TargetFramework>netcoreapp3.1</TargetFramework>
        <EnableDefaultContentItems>false</EnableDefaultContentItems>
    </PropertyGroup>

    <ItemGroup Condition="'$(EnableDefaultItems)' == 'true' And '$(EnableDefaultContentItems)' == 'false'">
        <Content Include="**\*.cshtml" 
                 ExcludeFromSingleFile="true" 
                 CopyToPublishDirectory="PreserveNewest" 
                 Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder);$(DefaultWebContentItemExcludes);Templates\**\*.cshtml" />
        <None Remove="**\*.cshtml" />
        <Content Include="Templates\Template.cshtml">
            <CopyToOutputDirectory>Always</CopyToOutputDirectory>
        </Content>
    </ItemGroup>
</Project>

@wdcossey
Copy link
Contributor

wdcossey commented Jul 17, 2021

EnableDefaultContentItems is from Sdk.Razor.CurrentVersion.props, I just changed the logic slightly.

    <!--
    Set to true to automatically include certain file types, such as .cshtml files, as content in the project.
    When referenced via Microsoft.NET.Sdk.Web, this additionally includes all files under wwwroot, and any config files.
    -->
    <EnableDefaultContentItems Condition="'$(EnableDefaultContentItems)'==''">true</EnableDefaultContentItems>

Default code:

  <ItemGroup Condition="'$(EnableDefaultItems)' == 'true' And '$(EnableDefaultContentItems)' == 'true'">
    <Content Include="**\*.cshtml" ExcludeFromSingleFile="true" CopyToPublishDirectory="PreserveNewest" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder);$(DefaultWebContentItemExcludes)" />
    <Content Include="**\*.razor" ExcludeFromSingleFile="true" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder);$(DefaultWebContentItemExcludes)" />
    <None Remove="**\*.cshtml" />
    <None Remove="**\*.razor" />
  </ItemGroup>

I updated the Exclude property in my .csproj to exclude Templates\**\*.cshtml

@jackhamby
Copy link

thanks for all this. i played around with those snippets you sent but kept having the same issue. this weekend i finally got something to work. i changed the BuildAction property on the .cshtml file itself, from Content to EmbeddedResource.

image

once i got that switched over i could build and run. compilation works great as well as the intellisense provided by @inherits directive. thanks again for the help in this.

@vukasinpetrovic
Copy link

@jackhamby Man, you saved me. That's what I needed. Thank you very much!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants