NancyFx / Nancy

Lightweight, low-ceremony, framework for building HTTP based services on .Net and Mono
http://nancyfx.org
MIT License
7.15k stars 1.47k forks source link

Intellisense with Nancy.ViewEngines.Razor only works partially #2937

Open nthalpy opened 5 years ago

nthalpy commented 5 years ago

Prerequisites

Description

This is very similar issue with https://github.com/NancyFx/Nancy/issues/2010.

I can use intellisense features to @Model, @Html, or @ViewBag. This works very nice. But when I try to use some fields, or properties which type is defined in Nancy assembly, for example, @Context which type is Nancy.NancyContext, Intellisense says: NancyContext type is defined in an assembly that is not referenced. You must add a reference to assembly 'Nancy, version=1.4.2.0, Culture=neutral, PublicKeyToken=null'

I tried to found some example which using Context property or Request property in NancyRazorViewBase<TModel> class, but there was no sample which using this properties. So, if we can use Intellisense with this properties, I hope someone add sample which uses Context or Request property with intellisense. Or if we can't use with Intellisense, I hope someone write this to wiki.

I am currently using Nancy.ViewEngines.Razor assembly with 1.4.3 version, and Nancy assembly with version 1.4.3. Also, I found that there was an very similar issue on 2015, but since there was no information about solution or progress, I posted this.

Steps to Reproduce

This cshtml file will make Intellisense error, but will compile very well.

@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase

@section body
{
   <p>@Context.CurrentUser.UserName</p>
}

System Configuration

nthalpy commented 5 years ago

I did some researches and tests about this issue, and found some way to suppress this error message without disable IntelliSense. If we add Nancy to GAC, IntelliSense no more makes error.

But now IntelliSense makes another error: CS1061 'NancyContext' does not contain a definition for 'ApplicationInstance' and no extension method 'ApplicationInstance' accepting a first argument of type 'NancyContext' could be found (are you missing a using directive or an assembly reference?).

EDIT: I think CS1061 is occured from different code generation logic between IntelliSense and Nancy; On auto generated code with IntelliSense, there are following getter:

protected System.Web.HttpApplication ApplicationInstance
{
    get
    {
        ((System.Web.HttpApplication)(Context.ApplicationInstance));
    }
}
nthalpy commented 5 years ago

After some more tests, I found that if we put Nancy.dll file to bin folder, this issue also resolves. Since this way does not need strong name, so it will be much better than putting Nancy.dll to GAC.

Steinblock commented 5 years ago

@nthalpy

Did you solve the error CS1061 'NancyContext' does not contain a definition for 'ApplicationInstance' and no extension method 'ApplicationInstance' accepting a first argument of type 'NancyContext' could be found (are you missing a using directive or an assembly reference?).

marcbarry commented 5 years ago

Also experiencing this Intellisense issue :+1:

In my view file I have both @inherits Nancy.ViewEngines.Razor.NancyRazorViewBase<dynamic> and @Context.CurrentUser.UserName

However, Context. provides Intellisense, and the .cshtml compiles and works as expected. The syntax highlighting is frustrating. It would be good to know if there's a fix or work around available?

Visual Studio 2017 (15.7.4) Nancy (1.4.5) Nancy.Viewengines.Razor (1.4.3)

Ps. love Nancy, it's a pleasure to use, thank you for working on it :)

Steinblock commented 5 years ago

@marcbarry

The type 'NancyContext' is defined in an assembly that is not referenced".

I just solved this.

The issue was the following.

copying the Nancy.dll to the bin dir solved this issue. I added a Post Build Event xcopy /y $(TargetDir)Nancy.dll $(ProjectDir)bin\ to solve this.

I am not what was the exact step to solve the dynamic error, but I got rid of this, too. Notice in my app.config I have two entries for <add assembly="System.Core... I believe this may be the cause.

  <configSections>
    <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
      <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
      <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
    </sectionGroup>
    <section name="razor" type="Nancy.ViewEngines.Razor.RazorConfigurationSection, Nancy.ViewEngines.Razor" />
  </configSections>

  <system.web>
    <compilation debug="true" targetFramework="4.5.0">
      <assemblies>
        <add assembly="System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
      </assemblies>
      <buildProviders>
        <add extension=".cshtml" type="Nancy.ViewEngines.Razor.BuildProviders.NancyCSharpRazorBuildProvider, Nancy.ViewEngines.Razor.BuildProviders" />
        <add extension=".vbhtml" type="Nancy.ViewEngines.Razor.BuildProviders.NancyVisualBasicRazorBuildProvider, Nancy.ViewEngines.Razor.BuildProviders" />
      </buildProviders>
    </compilation>
    <httpRuntime targetFramework="4.5.0" />
  </system.web>

  <system.web.webPages.razor>
    <pages pageBaseType="Nancy.ViewEngines.Razor.NancyRazorViewBase`1[[System.Object]]">
      <namespaces>
        <add namespace="Nancy" />
        <add namespace="Nancy.ViewEngines.Razor" />
      </namespaces>
    </pages>
  </system.web.webPages.razor>

  <razor disableAutoIncludeModelNamespace="false">
    <assemblies>
      <add assembly="System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
      <add assembly="System.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
    </assemblies>
    <namespaces>
      <add namespace="Nancy" />
      <add namespace="Nancy.ViewEngines.Razor" />
    </namespaces>
  </razor>
nthalpy commented 5 years ago

@Steinblock Sorry for late response. Not yet, I think that error CS1061 is caused by getter named ApplicationInstance, which exist in System.Web.HttpContext but not in Nancy.NancyContext. I think this needs some change on Nancy code. Since only VS intellisense uses this getter, I think we just need to insert some dummy getter like

protected System.Web.HttpApplication ApplicationInstance
{
    get
    {
        throw new NotImplementedException();
    }
}

But, anyway, this error seems no effect on VS lint, I just disabled intellisense errors.

marcbarry commented 5 years ago

Just to say thanks @Steinblock, making a second copy of Nancy.dll (from bin\debug\ in bin\) does indeed fix the Intellisense issue I had.

Guessing as long as this issue is open, I'll want to re-copy the latest Nancy.dll into \bin again each time I update Nancy to the latest version via nuget?

Thank you

Steinblock commented 5 years ago

@marcbarry

That does not only apply to the Nancy.dll but to every other assembly you are using as well. The real solution would be for Nancy.ViewEngines.Razor to build inside the TargetDir.

You can either use a post build event

xcopy /y $(TargetDir)Nancy.dll $(ProjectDir)bin\
xcopy /y $(TargetDir)System.Web.*.dll $(ProjectDir)bin\

Or change your Build |> Outputpath to bin.

Thats the default for web project anyways, which explains why Nancy.ViewEngines.Razor builds insidebin`

I use the output path approach because for production I do clean builds on a build server anyway.