1

Resolved

EditorTemplates and DisplayTemplates are broken due to namespace mangling

description

As addressed in the following discussions
RazorGenerator runs into issues with EditorTemplates and DisplayTemplates where users end up having to fully qualify types in the template files for it to work correctly. The problem is with the way RazorGenerator differs in the generation of names compared to the Asp.Net build provider.

For a file named at ~\Views\Shared\Boolean.cshtml, the build provider generates file names of the format
namespace ASP {
_Page_Views_Shared_Boolean_cshtml : WebViewPage<Boolean?>

}

versus RazorGenerator's output looks like
namespace Views.Shared
{
public class Boolean : WebViewPage<Boolean?>
}

which results in the cs compiler incorrectly inferring the templated Boolean type.

comments

pranavkm wrote Dec 2, 2013 at 11:48 PM

A simple fix might be to prefix the generated type's class name to have a leading underscore if it's located under a folder named DisplayTemplates \ EditorTemplates.

pranavkm wrote Dec 3, 2013 at 12:11 AM

Fixed in changeset 9b78bbf75e334cbc95e86870d00255645ff1cda3

davidebbo wrote Dec 3, 2013 at 12:15 AM

Do we need to re-release the VSIX here?

pranavkm wrote Dec 3, 2013 at 1:12 AM

We probably do, but I think we could wait until we have another bug fix. Not too many folks seem to run into this issue.

notken wrote Jan 9, 2014 at 2:04 PM

It would be great if you could please update the nuget packages to support this. I've run into this issue, and firstly renaming the templates with underscores might create unexpected issues elsewhere, plus even that wasn't a solution when I ran into this.

I have a view called Shared \ EditorTemplates \ Specifications \ FetchCompany but also a class called FetchCompany in a different namespace that this view references. It's using the View class FetchCompany rather than the existing FetchCompany class. I know I could fully qualify the class name, but I've got over 40 errored views like this trying out RazorGenerator, I'm part of a team, and making major view changes is a bit scary. I can't be sure of the knock-on effect, particularly when it was just for evaluation.

Thanks!

pranavkm wrote Jan 9, 2014 at 4:44 PM

@notken, the RazorGenerator.MsBuild package should be fixed for this issue. It's the Vsix we've not released with a fix as yet. Are you still seeing issues with the latest version of the package?

davidebbo wrote Jan 9, 2014 at 5:12 PM

I just uploaded a newer VSIX (1.6.3), so please try updating that as well.

notken wrote Jan 9, 2014 at 5:40 PM

Thanks for the quick reply. I only installed the nuget packages today, but they would have been stable versions. Do I need pre-release?

I'd prefer to keep it to nuget if possible so that other developers pick it up automatically and I don't have to ask them to install a VSIX.

I'll give it another go tomorrow and paste in specifics.

davidebbo wrote Jan 9, 2014 at 6:12 PM

There are no pre-release packages. RazorGenerator is split between design time (VSIX) and runtime (nuget) component, so depending on the specific fix, you'll have to update one or the other.

notken wrote Jan 13, 2014 at 1:36 PM

Sorry, I'm a bit confused. I thought I could use either the VSIX or the nuget. Is that right? Presumably if I use nuget I don't need VSIX. It certainly seems to be generating cs files for my views, and once I include the CodeGen folder in my project it's attempting to compile them.

But I've still got the same problem with templates not compiling because it is assuming class names refer to compiled views with the same name.

For instance, one error is:
"'Paladin3.WebUI.Views.Shared.EditorTemplates.DateTime' does not contain a definition for 'Day' and no extension method 'Day' accepting a first argument of type 'Paladin3.WebUI.Views.Shared.EditorTemplates.DateTime' could be found (are you missing a using directive or an assembly reference?)"

That view has been compiled with this signature:
public partial class Date : Paladin3.WebUI.Infrastructure.PaladinWebViewPage<DateTime>

when it should be:
public partial class Date : Paladin3.WebUI.Infrastructure.PaladinWebViewPage<System.DateTime>

(I have a DateTime template)

I am still able to fix it by fully qualifying the model type in the view, but "System" is in the list of namespaces, so Resharper is actually prompting me to remove "System." from the model type.

To confirm, this is using RazorGenerator.Mvc from nuget, version 2.2.1

Actually, I've run into a similar error that I can't resolve as easily. I have a partial called _UsersChooseFilterButton, and a class called UsersChooseFilterButton. A separate partial, _UsersChooseSelectionPanel, calls Html.Partial on _UsersChooseFilterButton with a new model of UsersChooseFilterButton and 5 parameters. But I'm getting compiled errors that my compiled view doesn't have a constructor that takes 5 parameters, because it's defaulting to the compiled view as the class instead.

davidebbo wrote Jan 13, 2014 at 4:04 PM

The VSIX is always used alongside NuGet packages. But if you are specifically using RazorGenerator.MsBuild, then you indeed don't need the VSIX. Can you clarify that you are using that, and if so which version? I don't see it mentioned anywhere in this issue.

pranavkm wrote Jan 13, 2014 at 5:49 PM

@notken, the fix we made as part of RazorGenerator.MsBuild \ Vsix v2.2.2 was to mangle names for EditorTemplates and DisplayTemplates. Consequently the names we generate are of the format *
Paladin3_WebUI_Infrastructure_PaladinWebViewPage_Date* which avoids the name collision. We don't muck with the generic type parameter since it's the value specified via the @model declaration and prepending System to it all the time would not be the right behavior.

The heuristic I"m using to figure out if something's a display \ editor template is by available here - https://razorgenerator.codeplex.com/SourceControl/changeset/9b78bbf75e334cbc95e86870d00255645ff1cda3#RazorGenerator.Core.v2/MvcViewTransformer.cs. It's likely that it might not be working correctly for your scenario. In which case, would you be able to provide a sample repro so we could fix our heuristic?

notken wrote Jan 13, 2014 at 5:50 PM

Thanks for your help with this. Sorry if it turns out to be my misunderstanding.

I have only used nuget to install RazorGenerator.Mvc which in turn installed RazorGenerator.Mvc 2.2.1 and WebActivatorEx 2.0.4.

It's added the new ViewEngine to my code through App_Start and created the CodeGen folder (and after the first build, cs files of all views got generated in there).

pranavkm wrote Jan 13, 2014 at 5:50 PM

Sorry, it's been a while since I looked at it. The class names we generate are simply prefixed with an underscore. So it would be
public partial class _Date : Paladin3.WebUI.Infrastructure.PaladinWebViewPage<DateTime>

Regardless, it achieves the purpose of distinguishing the generated type from the model.

davidebbo wrote Jan 13, 2014 at 6:10 PM

Ok, to many misunderstandings in this thread. :) Can you share a simple repo (e.g. onGitHub) that demonstrates the problem you are seeing?

As far as I know, you simply cannot use RazorGenerator if you don't use either the VSIX or the msbuild package, so the fact that you have neither is puzzling, and a repro will clarify.

notken wrote Jan 17, 2014 at 9:48 AM

I can't seem to recreate the issue in a new project, so heaven knows what the cause of it is. Sorry I've not been able to help (and maybe there's nothing wrong with RazorGenerator!)

But I have now got it working on my project. In the end I only had to make a couple of changes, to fully qualify a couple of clashing model names.

I actually have my own View Engine for this project (I need to also check some custom locations), so I've amended it to inherit from yours. Is there a way you recommend to test that it is using the code rather than the cshtml files? I've tried renaming or deleting the original, without recompiling, but I still get a "The view 'Index' or its master was not found" error. Is that expected, or should the pre-compiled version existing preclude that check? I just don't know if it's working or not!

Many thanks.

notken wrote Jan 17, 2014 at 10:10 AM

Sorry, ignore the last bit of my last post. A logic fart on my part. It is still finding the view even if I delete it, so I think that's showing it's working! Thanks so much. I'm hoping it'll improve our performance on start-up.