diff --git a/Nancy.Next.sln b/Nancy.Next.sln index aa2b1e6ec4..0aa2ffafdc 100644 --- a/Nancy.Next.sln +++ b/Nancy.Next.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 -VisualStudioVersion = 14.0.24720.0 +VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{5734E9DC-CF67-4337-B28E-695280598B88}" EndProject @@ -44,8 +44,6 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Nancy.ViewEngines.Nustache" EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Nancy.ViewEngines.Razor", "src\Nancy.ViewEngines.Razor\Nancy.ViewEngines.Razor.xproj", "{3A376B78-DD7D-4450-9FDE-F7236FAA6E63}" EndProject -Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Nancy.ViewEngines.Razor.BuildProviders", "src\Nancy.ViewEngines.Razor.BuildProviders\Nancy.ViewEngines.Razor.BuildProviders.xproj", "{26DF3BE0-146B-43A6-B230-D5B33355F415}" -EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Nancy.ViewEngines.Spark", "src\Nancy.ViewEngines.Spark\Nancy.ViewEngines.Spark.xproj", "{25E3AB38-D95E-4D11-B0F0-0F60571A97A0}" EndProject Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Nancy.Tests", "test\Nancy.Tests\Nancy.Tests.xproj", "{3BA7D452-98E5-47B0-BD1E-DC348E13A72A}" @@ -162,10 +160,6 @@ Global {3A376B78-DD7D-4450-9FDE-F7236FAA6E63}.Debug|Any CPU.Build.0 = Debug|Any CPU {3A376B78-DD7D-4450-9FDE-F7236FAA6E63}.Release|Any CPU.ActiveCfg = Release|Any CPU {3A376B78-DD7D-4450-9FDE-F7236FAA6E63}.Release|Any CPU.Build.0 = Release|Any CPU - {26DF3BE0-146B-43A6-B230-D5B33355F415}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {26DF3BE0-146B-43A6-B230-D5B33355F415}.Debug|Any CPU.Build.0 = Debug|Any CPU - {26DF3BE0-146B-43A6-B230-D5B33355F415}.Release|Any CPU.ActiveCfg = Release|Any CPU - {26DF3BE0-146B-43A6-B230-D5B33355F415}.Release|Any CPU.Build.0 = Release|Any CPU {25E3AB38-D95E-4D11-B0F0-0F60571A97A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {25E3AB38-D95E-4D11-B0F0-0F60571A97A0}.Debug|Any CPU.Build.0 = Debug|Any CPU {25E3AB38-D95E-4D11-B0F0-0F60571A97A0}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -264,7 +258,6 @@ Global {CFA5BBCB-B41B-47C0-A4D2-FA243FC6ECC6} = {5734E9DC-CF67-4337-B28E-695280598B88} {32E22782-7A5E-4546-B2DB-F3628EA36361} = {5734E9DC-CF67-4337-B28E-695280598B88} {3A376B78-DD7D-4450-9FDE-F7236FAA6E63} = {5734E9DC-CF67-4337-B28E-695280598B88} - {26DF3BE0-146B-43A6-B230-D5B33355F415} = {5734E9DC-CF67-4337-B28E-695280598B88} {25E3AB38-D95E-4D11-B0F0-0F60571A97A0} = {5734E9DC-CF67-4337-B28E-695280598B88} {3BA7D452-98E5-47B0-BD1E-DC348E13A72A} = {F44224E5-8E58-4D52-A0F0-BCBA2ADC0A0B} {51494B38-0D18-4B9D-AB75-39E804747D5F} = {F44224E5-8E58-4D52-A0F0-BCBA2ADC0A0B} diff --git a/Nancy.sln b/Nancy.sln index 5a1e80256b..8c929d5b9e 100644 --- a/Nancy.sln +++ b/Nancy.sln @@ -80,8 +80,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nancy.Validation.FluentVali EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nancy.ViewEngines.Razor.Tests.Models", "test\Nancy.ViewEngines.Razor.Tests.Models.MSBuild\Nancy.ViewEngines.Razor.Tests.Models.csproj", "{3F18F5DA-93E0-4513-8BF4-BC8EE5C4117C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nancy.ViewEngines.Razor.BuildProviders", "src\Nancy.ViewEngines.Razor.BuildProviders.MSBuild\Nancy.ViewEngines.Razor.BuildProviders.csproj", "{EDF3E264-2D0F-4440-99FF-45D279A598A9}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nancy.Hosting.Self.Tests", "test\Nancy.Hosting.Self.Tests.MSBuild\Nancy.Hosting.Self.Tests.csproj", "{CA24ED85-DD68-4C10-B80A-D81C6745FCB8}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nancy.Authentication.Stateless", "src\Nancy.Authentication.Stateless.MSBuild\Nancy.Authentication.Stateless.csproj", "{211560C3-FDDF-46D6-AB0C-F3BC04B173B5}" diff --git a/samples/Nancy.Demo.Hosting.Aspnet/Nancy.Demo.Hosting.Aspnet.csproj b/samples/Nancy.Demo.Hosting.Aspnet/Nancy.Demo.Hosting.Aspnet.csproj index 403ea5ac66..ddef6aef00 100644 --- a/samples/Nancy.Demo.Hosting.Aspnet/Nancy.Demo.Hosting.Aspnet.csproj +++ b/samples/Nancy.Demo.Hosting.Aspnet/Nancy.Demo.Hosting.Aspnet.csproj @@ -1,5 +1,5 @@  - + Debug @@ -11,7 +11,7 @@ Properties Nancy.Demo.Hosting.Aspnet Nancy.Demo.Hosting.Aspnet - v4.5 + v4.5.1 true 4.0 enabled @@ -19,6 +19,7 @@ false + true @@ -90,12 +91,17 @@ True + ..\..\packages\System.Reflection.Metadata.1.1.0\lib\dotnet5.2\System.Reflection.Metadata.dll True + + + + diff --git a/samples/Nancy.Demo.Hosting.Aspnet/Resources/Menu.Designer.cs b/samples/Nancy.Demo.Hosting.Aspnet/Resources/Menu.Designer.cs index a49d560513..09712e2acf 100644 --- a/samples/Nancy.Demo.Hosting.Aspnet/Resources/Menu.Designer.cs +++ b/samples/Nancy.Demo.Hosting.Aspnet/Resources/Menu.Designer.cs @@ -1,7 +1,7 @@ //------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.0 +// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -9,14 +9,9 @@ //------------------------------------------------------------------------------ namespace Nancy.Demo.Hosting.Aspnet.Resources { - using System.CodeDom.Compiler; - using System.ComponentModel; - using System.Diagnostics; - using System.Diagnostics.CodeAnalysis; - using System.Globalization; - using System.Resources; - using System.Runtime.CompilerServices; - + using System; + + /// /// A strongly-typed resource class, for looking up localized strings, etc. /// @@ -24,27 +19,27 @@ namespace Nancy.Demo.Hosting.Aspnet.Resources { // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. - [GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] - [DebuggerNonUserCode()] - [CompilerGenerated()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Menu { - private static ResourceManager resourceMan; + private static global::System.Resources.ResourceManager resourceMan; - private static CultureInfo resourceCulture; + private static global::System.Globalization.CultureInfo resourceCulture; - [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Menu() { } /// /// Returns the cached ResourceManager instance used by this class. /// - [EditorBrowsable(EditorBrowsableState.Advanced)] - internal static ResourceManager ResourceManager { + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { get { - if (ReferenceEquals(resourceMan, null)) { - ResourceManager temp = new ResourceManager("Nancy.Demo.Hosting.Aspnet.Resources.Menu", typeof(Menu).Assembly); + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Nancy.Demo.Hosting.Aspnet.Resources.Menu", typeof(Menu).Assembly); resourceMan = temp; } return resourceMan; @@ -55,8 +50,8 @@ internal static ResourceManager ResourceManager { /// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// - [EditorBrowsable(EditorBrowsableState.Advanced)] - internal static CultureInfo Culture { + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } diff --git a/samples/Nancy.Demo.Hosting.Aspnet/Web.config b/samples/Nancy.Demo.Hosting.Aspnet/Web.config index 8002c46e08..cdb08bf7c0 100644 --- a/samples/Nancy.Demo.Hosting.Aspnet/Web.config +++ b/samples/Nancy.Demo.Hosting.Aspnet/Web.config @@ -1,17 +1,14 @@  -
- - @@ -20,14 +17,20 @@ + - + - @@ -35,13 +38,24 @@ - + + + + + + + + + + + + - + \ No newline at end of file diff --git a/src/Nancy.Testing.MSBuild/Nancy.Testing.csproj b/src/Nancy.Testing.MSBuild/Nancy.Testing.csproj index 87bae49575..799b421fab 100644 --- a/src/Nancy.Testing.MSBuild/Nancy.Testing.csproj +++ b/src/Nancy.Testing.MSBuild/Nancy.Testing.csproj @@ -89,8 +89,8 @@ false - - $(SolutionDir)packages\AngleSharp.0.9.5\lib\net45\AngleSharp.dll + + $(SolutionDir)packages\AngleSharp.0.9.8.1\lib\net45\AngleSharp.dll True diff --git a/src/Nancy.ViewEngines.Razor.BuildProviders.MSBuild/Nancy.ViewEngines.Razor.BuildProviders.csproj b/src/Nancy.ViewEngines.Razor.BuildProviders.MSBuild/Nancy.ViewEngines.Razor.BuildProviders.csproj deleted file mode 100644 index e8f137986c..0000000000 --- a/src/Nancy.ViewEngines.Razor.BuildProviders.MSBuild/Nancy.ViewEngines.Razor.BuildProviders.csproj +++ /dev/null @@ -1,133 +0,0 @@ - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {EDF3E264-2D0F-4440-99FF-45D279A598A9} - Library - Properties - Nancy.ViewEngines.Razor.BuildProviders - Nancy.ViewEngines.Razor.BuildProviders - v4.5 - 512 - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - AllRules.ruleset - bin\Debug\Nancy.ViewEngines.Razor.BuildProviders.XML - false - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - AllRules.ruleset - bin\Release\Nancy.ViewEngines.Razor.BuildProviders.XML - false - - - true - bin\MonoDebug\ - DEBUG;TRACE - full - AnyCPU - bin\Debug\Nancy.ViewEngines.Razor.BuildProviders.xml - true - GlobalSuppressions.cs - prompt - AllRules.ruleset - ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets - false - ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules - false - 4 - false - bin\MonoDebug\Nancy.ViewEngines.Razor.BuildProviders.XML - false - - - bin\MonoRelease\ - TRACE - true - pdbonly - AnyCPU - bin\Release\Nancy.ViewEngines.Razor.BuildProviders.xml - true - GlobalSuppressions.cs - prompt - AllRules.ruleset - ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets - false - ;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules - false - 4 - bin\MonoRelease\Nancy.ViewEngines.Razor.BuildProviders.XML - false - - - - - - - - - True - ..\..\packages\Microsoft.AspNet.Razor.2.0.30506.0\lib\net40\System.Web.Razor.dll - - - - - Properties\SharedAssemblyInfo.cs - - - NancyCSharpRazorBuildProvider.cs - - - - - {2C6F51DF-015C-4DB6-B44C-0E5E4F25E2A9} - Nancy.ViewEngines.Razor - - - {34576216-0DCA-4B0F-A0DC-9075E75A676F} - Nancy - - - - - - - - \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor.BuildProviders.MSBuild/packages.config b/src/Nancy.ViewEngines.Razor.BuildProviders.MSBuild/packages.config deleted file mode 100644 index 039dbcc583..0000000000 --- a/src/Nancy.ViewEngines.Razor.BuildProviders.MSBuild/packages.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor.BuildProviders/Nancy.ViewEngines.Razor.BuildProviders.xproj b/src/Nancy.ViewEngines.Razor.BuildProviders/Nancy.ViewEngines.Razor.BuildProviders.xproj deleted file mode 100644 index ff0b8dd0ed..0000000000 --- a/src/Nancy.ViewEngines.Razor.BuildProviders/Nancy.ViewEngines.Razor.BuildProviders.xproj +++ /dev/null @@ -1,21 +0,0 @@ - - - - 14.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - 26df3be0-146b-43a6-b230-d5b33355f415 - Nancy.ViewEngines.Razor.BuildProviders - .\obj - .\bin\ - - - Nancy.ViewEngines.Razor.BuildProviders - - - 2.0 - - - diff --git a/src/Nancy.ViewEngines.Razor.BuildProviders/NancyCSharpRazorBuildProvider.cs b/src/Nancy.ViewEngines.Razor.BuildProviders/NancyCSharpRazorBuildProvider.cs deleted file mode 100644 index 44040bb02e..0000000000 --- a/src/Nancy.ViewEngines.Razor.BuildProviders/NancyCSharpRazorBuildProvider.cs +++ /dev/null @@ -1,82 +0,0 @@ -namespace Nancy.ViewEngines.Razor.BuildProviders -{ - using System; - using System.CodeDom; - using System.CodeDom.Compiler; - using System.Globalization; - using System.Web.Compilation; - using System.Web.Razor; - - [BuildProviderAppliesTo(BuildProviderAppliesTo.Code | BuildProviderAppliesTo.Web)] - public class NancyCSharpRazorBuildProvider : BuildProvider - { - private readonly RazorEngineHost host; - - private readonly CompilerType compilerType; - - private CodeCompileUnit generatedCode; - - /// - /// Initializes a new instance of the class. - /// - /// An instance. - public NancyCSharpRazorBuildProvider(RazorAssemblyProvider razorAssemblyProvider) - { - this.compilerType = this.GetDefaultCompilerTypeForLanguage("C#"); - - this.host = new NancyRazorEngineHost(new CSharpRazorCodeLanguage(), razorAssemblyProvider); - } - - /// - /// Represents the compiler type used by a build provider to generate source code for a custom file type. - /// - /// A read-only representing the code generator, code compiler, and compiler settings used to build source code for the virtual path. The base class returns null. - public override CompilerType CodeCompilerType - { - get { return this.compilerType; } - } - - /// - /// Generates source code for the virtual path of the build provider, and adds the source code to a specified assembly builder. - /// - /// The assembly builder that references the source code generated by the build provider. - public override void GenerateCode(AssemblyBuilder assemblyBuilder) - { - assemblyBuilder.AddCodeCompileUnit(this, this.GetGeneratedCode()); - - assemblyBuilder.GenerateTypeFactory(string.Format(CultureInfo.InvariantCulture, "{0}.{1}", new object[] { this.host.DefaultNamespace, this.host.DefaultClassName })); - } - - /// - /// Returns a type generated by the build provider from the virtual path. - /// - /// The type that is generated by the build provider for the virtual path. The base class returns null. - /// The compilation results for the build provider's virtual path. - public override Type GetGeneratedType(CompilerResults results) - { - return results.CompiledAssembly.GetType(string.Format(CultureInfo.CurrentCulture, "{0}.{1}", new object[] { this.host.DefaultNamespace, this.host.DefaultClassName })); - } - - private CodeCompileUnit GetGeneratedCode() - { - if (this.generatedCode == null) - { - var engine = new RazorTemplateEngine(this.host); - GeneratorResults results; - using (var reader = this.OpenReader()) - { - results = engine.GenerateCode(reader); - } - - if (!results.Success) - { - throw new InvalidOperationException(results.ToString()); - } - - this.generatedCode = results.GeneratedCode; - } - - return this.generatedCode; - } - } -} \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor.BuildProviders/project.json b/src/Nancy.ViewEngines.Razor.BuildProviders/project.json deleted file mode 100644 index 7a54597cb0..0000000000 --- a/src/Nancy.ViewEngines.Razor.BuildProviders/project.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "version": "2.0.0-barneyrubble", - - "dependencies": { - "Nancy": { "target": "project" }, - "Nancy.ViewEngines.Razor": { "target": "project" } - }, - - "buildOptions": { - "xmlDoc": true - }, - - "frameworks": { - "net452": { - "frameworkAssemblies": { - "System.Web": { "type": "build" } - } - } - } -} diff --git a/src/Nancy.ViewEngines.Razor.MSBuild/Nancy.ViewEngines.Razor.csproj b/src/Nancy.ViewEngines.Razor.MSBuild/Nancy.ViewEngines.Razor.csproj index dca386bf8d..48ecd6f0de 100644 --- a/src/Nancy.ViewEngines.Razor.MSBuild/Nancy.ViewEngines.Razor.csproj +++ b/src/Nancy.ViewEngines.Razor.MSBuild/Nancy.ViewEngines.Razor.csproj @@ -1,7 +1,5 @@  - - - + Debug AnyCPU @@ -12,7 +10,7 @@ Properties Nancy.ViewEngines.Razor Nancy.ViewEngines.Razor - v4.5 + v4.5.1 512 publish\ true @@ -31,6 +29,7 @@ true + true @@ -93,118 +92,265 @@ false - - ..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.1\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll + + ..\..\packages\Microsoft.AspNetCore.Antiforgery.1.0.1\lib\net451\Microsoft.AspNetCore.Antiforgery.dll True - - ..\..\packages\Microsoft.CodeAnalysis.Common.1.1.1\lib\net45\Microsoft.CodeAnalysis.dll + + ..\..\packages\Microsoft.AspNetCore.Authorization.1.0.0\lib\net451\Microsoft.AspNetCore.Authorization.dll True - - ..\..\packages\Microsoft.CodeAnalysis.CSharp.1.1.1\lib\net45\Microsoft.CodeAnalysis.CSharp.dll + + ..\..\packages\Microsoft.AspNetCore.Cryptography.Internal.1.0.0\lib\net451\Microsoft.AspNetCore.Cryptography.Internal.dll + True + + + ..\..\packages\Microsoft.AspNetCore.DataProtection.1.0.0\lib\net451\Microsoft.AspNetCore.DataProtection.dll + True + + + ..\..\packages\Microsoft.AspNetCore.DataProtection.Abstractions.1.0.0\lib\net451\Microsoft.AspNetCore.DataProtection.Abstractions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Diagnostics.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.AspNetCore.Diagnostics.Abstractions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Hosting.Abstractions.1.0.0\lib\net451\Microsoft.AspNetCore.Hosting.Abstractions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Hosting.Server.Abstractions.1.0.0\lib\net451\Microsoft.AspNetCore.Hosting.Server.Abstractions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Html.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.AspNetCore.Html.Abstractions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Http.1.0.0\lib\net451\Microsoft.AspNetCore.Http.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Http.Abstractions.1.0.0\lib\net451\Microsoft.AspNetCore.Http.Abstractions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Http.Extensions.1.0.0\lib\net451\Microsoft.AspNetCore.Http.Extensions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Http.Features.1.0.0\lib\net451\Microsoft.AspNetCore.Http.Features.dll + True + + + ..\..\packages\Microsoft.AspNetCore.JsonPatch.1.0.0\lib\netstandard1.1\Microsoft.AspNetCore.JsonPatch.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Mvc.Abstractions.1.0.1\lib\net451\Microsoft.AspNetCore.Mvc.Abstractions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Mvc.Core.1.0.1\lib\net451\Microsoft.AspNetCore.Mvc.Core.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Mvc.DataAnnotations.1.0.1\lib\net451\Microsoft.AspNetCore.Mvc.DataAnnotations.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Mvc.Formatters.Json.1.0.1\lib\net451\Microsoft.AspNetCore.Mvc.Formatters.Json.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Mvc.Razor.1.0.1\lib\net451\Microsoft.AspNetCore.Mvc.Razor.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Mvc.Razor.Host.1.0.1\lib\net451\Microsoft.AspNetCore.Mvc.Razor.Host.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Mvc.ViewFeatures.1.0.1\lib\net451\Microsoft.AspNetCore.Mvc.ViewFeatures.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Razor.1.0.0\lib\net451\Microsoft.AspNetCore.Razor.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Razor.Runtime.1.0.0\lib\net451\Microsoft.AspNetCore.Razor.Runtime.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Routing.1.0.0\lib\net451\Microsoft.AspNetCore.Routing.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Routing.Abstractions.1.0.0\lib\net451\Microsoft.AspNetCore.Routing.Abstractions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.WebUtilities.1.0.0\lib\net451\Microsoft.AspNetCore.WebUtilities.dll + True + + + ..\..\packages\Microsoft.CodeAnalysis.Common.1.3.0\lib\net45\Microsoft.CodeAnalysis.dll + True + + + ..\..\packages\Microsoft.CodeAnalysis.CSharp.1.3.0\lib\net45\Microsoft.CodeAnalysis.CSharp.dll + True + + + ..\..\packages\Microsoft.DotNet.InternalAbstractions.1.0.0\lib\net451\Microsoft.DotNet.InternalAbstractions.dll + True + + + ..\..\packages\Microsoft.Extensions.Caching.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.Extensions.Caching.Abstractions.dll + True + + + ..\..\packages\Microsoft.Extensions.Caching.Memory.1.0.0\lib\net451\Microsoft.Extensions.Caching.Memory.dll + True + + + ..\..\packages\Microsoft.Extensions.Configuration.1.0.0\lib\netstandard1.1\Microsoft.Extensions.Configuration.dll + True + + + ..\..\packages\Microsoft.Extensions.Configuration.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.Extensions.Configuration.Abstractions.dll + True + + + ..\..\packages\Microsoft.Extensions.Configuration.Binder.1.0.0\lib\netstandard1.1\Microsoft.Extensions.Configuration.Binder.dll + True + + + ..\..\packages\Microsoft.Extensions.Configuration.EnvironmentVariables.1.0.0\lib\net451\Microsoft.Extensions.Configuration.EnvironmentVariables.dll + True + + + ..\..\packages\Microsoft.Extensions.Configuration.FileExtensions.1.0.0\lib\net451\Microsoft.Extensions.Configuration.FileExtensions.dll + True + + + ..\..\packages\Microsoft.Extensions.Configuration.Json.1.0.0\lib\net451\Microsoft.Extensions.Configuration.Json.dll + True + + + ..\..\packages\Microsoft.Extensions.DependencyInjection.1.0.0\lib\netstandard1.1\Microsoft.Extensions.DependencyInjection.dll + True + + + ..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + True + + + ..\..\packages\Microsoft.Extensions.DependencyModel.1.0.0\lib\net451\Microsoft.Extensions.DependencyModel.dll + True + + + ..\..\packages\Microsoft.Extensions.FileProviders.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.Extensions.FileProviders.Abstractions.dll + True + + + ..\..\packages\Microsoft.Extensions.FileProviders.Composite.1.0.0\lib\netstandard1.0\Microsoft.Extensions.FileProviders.Composite.dll + True + + + ..\..\packages\Microsoft.Extensions.FileProviders.Physical.1.0.0\lib\net451\Microsoft.Extensions.FileProviders.Physical.dll + True + + + ..\..\packages\Microsoft.Extensions.FileSystemGlobbing.1.0.0\lib\net451\Microsoft.Extensions.FileSystemGlobbing.dll + True + + + ..\..\packages\Microsoft.Extensions.Localization.1.0.0\lib\net451\Microsoft.Extensions.Localization.dll + True + + + ..\..\packages\Microsoft.Extensions.Localization.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.Extensions.Localization.Abstractions.dll + True + + + ..\..\packages\Microsoft.Extensions.Logging.Abstractions.1.0.0\lib\netstandard1.1\Microsoft.Extensions.Logging.Abstractions.dll + True + + + ..\..\packages\Microsoft.Extensions.ObjectPool.1.0.0\lib\net451\Microsoft.Extensions.ObjectPool.dll + True + + + ..\..\packages\Microsoft.Extensions.Options.1.0.0\lib\netstandard1.0\Microsoft.Extensions.Options.dll + True + + + ..\..\packages\Microsoft.Extensions.Options.ConfigurationExtensions.1.0.0\lib\netstandard1.1\Microsoft.Extensions.Options.ConfigurationExtensions.dll + True + + + ..\..\packages\Microsoft.Extensions.PlatformAbstractions.1.0.0\lib\net451\Microsoft.Extensions.PlatformAbstractions.dll + True + + + ..\..\packages\Microsoft.Extensions.Primitives.1.0.0\lib\netstandard1.0\Microsoft.Extensions.Primitives.dll + True + + + ..\..\packages\Microsoft.Extensions.WebEncoders.1.0.0\lib\netstandard1.0\Microsoft.Extensions.WebEncoders.dll + True + + + ..\..\packages\Microsoft.Net.Http.Headers.1.0.0\lib\netstandard1.1\Microsoft.Net.Http.Headers.dll + True + + + ..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll True + + ..\..\packages\System.Buffers.4.0.0\lib\netstandard1.1\System.Buffers.dll + True + ..\..\packages\System.Collections.Immutable.1.1.37\lib\dotnet\System.Collections.Immutable.dll True - + + + + ..\..\packages\System.ComponentModel.Primitives.4.1.0\lib\net45\System.ComponentModel.Primitives.dll + True + + + ..\..\packages\System.ComponentModel.TypeConverter.4.1.0\lib\net45\System.ComponentModel.TypeConverter.dll + True + - - ..\..\packages\System.Reflection.Metadata.1.1.0\lib\dotnet5.2\System.Reflection.Metadata.dll + + ..\..\packages\System.Diagnostics.DiagnosticSource.4.0.0\lib\portable-net45+win8+wpa81\System.Diagnostics.DiagnosticSource.dll True - + + ..\..\packages\System.Reflection.Metadata.1.2.0\lib\portable-net45+win8\System.Reflection.Metadata.dll + True + + + + + ..\..\packages\System.Text.Encodings.Web.4.0.0\lib\netstandard1.0\System.Text.Encodings.Web.dll True - ..\..\packages\Microsoft.AspNet.Razor.2.0.30506.0\lib\net40\System.Web.Razor.dll - - - Properties\SharedAssemblyInfo.cs - - - AttributeValue.cs - - - ClrTypeResolver.cs - - - CodeParserHelper.cs - - - CSharp\CSharpClrTypeResolver.cs - - - CSharp\CSharpRazorViewRenderer.cs - - - DefaultRazorConfiguration.cs - - - HelperResult.cs - - - HtmlHelpers.cs - - - HtmlHelpersExtensions.cs - - - IHtmlString.cs - - - INancyRazorView.cs - - - IRazorConfiguration.cs - - - IRazorViewRenderer.cs - - - CSharp\NancyCSharpRazorCodeParser.cs - - - ModelCodeGenerator.cs - - - NancyRazorEngineHost.cs - - - NancyRazorErrorView.cs - - - NancyRazorViewBase.cs - - - NonEncodedHtmlString.cs - - - RazorAssemblyProvider.cs - - - RazorConfigurationSection.cs - - - RazorViewEngine.cs - - - RazorViewEngineApplicationStartupRegistrations.cs - - - UrlHelpers.cs - - - EncodedHtmlString.cs - - Resources\CompilationError.html @@ -229,15 +375,73 @@ Designer - - - This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - - - + + + DefaultRazorConfiguration.cs + + + EmptyChangeToken.cs + + + EmptyDisposable.cs + + + HostingEnvironment.cs + + + IRazorConfiguration.cs + + + LocationProviderDirectoryContents.cs + + + MetadataReferenceFeatureProvider.cs + + + NancyRazorHost.cs + + + NancyRazorPage.cs + + + NancyViewContext.cs + + + RazorViewEngine.cs + + + RazorViewEngineRegistrations.cs + + + RazorViewRenderer.cs + + + SilentDiagnosticSource.cs + + + SilentLogger.cs + + + SilentLoggerFactory.cs + + + TextReaderStream.cs + + + ViewLocationExpander.cs + + + ViewLocationFileInfo.cs + + + ViewLocationFileProvider.cs + + + NancyRazorErrorView.cs + + \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor.MSBuild/packages.config b/src/Nancy.ViewEngines.Razor.MSBuild/packages.config index 8bbe35c48b..f0c87b8b8f 100644 --- a/src/Nancy.ViewEngines.Razor.MSBuild/packages.config +++ b/src/Nancy.ViewEngines.Razor.MSBuild/packages.config @@ -1,26 +1,87 @@  - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/AttributeValue.cs b/src/Nancy.ViewEngines.Razor/AttributeValue.cs deleted file mode 100644 index 3519fa6b49..0000000000 --- a/src/Nancy.ViewEngines.Razor/AttributeValue.cs +++ /dev/null @@ -1,35 +0,0 @@ -namespace Nancy.ViewEngines.Razor -{ - using System; - - /// - /// Class to represent attribute values and, more importantly, - /// decipher them from tuple madness slightly. - /// - public class AttributeValue - { - public Tuple Prefix { get; private set; } - - public Tuple Value { get; private set; } - - public bool IsLiteral { get; private set; } - - public AttributeValue(Tuple prefix, Tuple value, bool isLiteral) - { - this.Prefix = prefix; - this.Value = value; - this.IsLiteral = isLiteral; - } - - public static implicit operator AttributeValue(Tuple, Tuple, bool> value) - { - return new AttributeValue(value.Item1, value.Item2, value.Item3); - } - - public static implicit operator AttributeValue(Tuple, Tuple, bool> value) - { - return new AttributeValue( - value.Item1, new Tuple(value.Item2.Item1, value.Item2.Item2), value.Item3); - } - } -} \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/CSharp/CSharpClrTypeResolver.cs b/src/Nancy.ViewEngines.Razor/CSharp/CSharpClrTypeResolver.cs deleted file mode 100644 index 856bddd35d..0000000000 --- a/src/Nancy.ViewEngines.Razor/CSharp/CSharpClrTypeResolver.cs +++ /dev/null @@ -1,90 +0,0 @@ -namespace Nancy.ViewEngines.Razor.CSharp -{ - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web.Razor.Tokenizer.Symbols; - - /// - /// Resolves C# type name to CLR type - /// - internal class CSharpClrTypeResolver : ClrTypeResolver - { - public CSharpClrTypeResolver(RazorAssemblyProvider razorAssemblyProvider) - : base(razorAssemblyProvider, CSharpSymbolType.Identifier, CSharpSymbolType.Keyword, CSharpSymbolType.Dot, CSharpSymbolType.WhiteSpace, CSharpSymbolType.LeftBracket, CSharpSymbolType.RightBracket) - { - } - - /// - /// Dequeues symbols '>' representing end of generic arguments - /// - /// Returns true if move was successful - protected override bool MoveOutOfGenericArguments() - { - if (this.Symbols.Peek().Type == CSharpSymbolType.GreaterThan) - { - this.Symbols.Dequeue(); - - return true; - } - - return false; - } - - /// - /// Dequeues symbol ',' and whitespace representing separator between generic arguments - /// - protected override void MoveToNextGenericArgument() - { - while (this.Symbols.Peek().Type == CSharpSymbolType.WhiteSpace || this.Symbols.Peek().Type == CSharpSymbolType.Comma) - { - this.Symbols.Dequeue(); - } - } - - /// - /// equeues symbol '<' representing begin of generic arguments - /// - /// Returns true if move was successful - protected override bool MoveToGenericArguments() - { - if (this.Symbols.Peek().Type != CSharpSymbolType.LessThan) - { - return false; - } - - this.Symbols.Dequeue(); - - return true; - } - - /// - /// Gets CLR from name (keyword) used by C# - /// - /// Type name to resolve - /// CLR type - protected override Type ResolvePrimitiveType(string typeName) - { - var primitives = new Dictionary - { - {"string", typeof (string)}, - {"byte", typeof (byte)}, - {"sbyte", typeof (sbyte)}, - {"short", typeof (short)}, - {"ushort", typeof (ushort)}, - {"int", typeof (int)}, - {"uint", typeof (uint)}, - {"long", typeof (long)}, - {"ulong", typeof (ulong)}, - {"float", typeof (float)}, - {"double", typeof (double)}, - {"decimal", typeof (decimal)}, - {"char", typeof (char)}, - {"bool", typeof (bool)}, - {"object", typeof (object)}, - }; - - return (primitives.ContainsKey(typeName) ? primitives[typeName] : null); - } - } -} \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/CSharp/CSharpRazorViewRenderer.cs b/src/Nancy.ViewEngines.Razor/CSharp/CSharpRazorViewRenderer.cs deleted file mode 100644 index f0cafe75e0..0000000000 --- a/src/Nancy.ViewEngines.Razor/CSharp/CSharpRazorViewRenderer.cs +++ /dev/null @@ -1,72 +0,0 @@ -namespace Nancy.ViewEngines.Razor.CSharp -{ - using System; - using System.CodeDom.Compiler; - using System.Collections.Generic; - using System.Web.Razor; - using Microsoft.CSharp.RuntimeBinder; - - /// - /// Renderer for CSharp razor files. - /// - public class CSharpRazorViewRenderer : IRazorViewRenderer, IDisposable - { - /// - /// Gets the assemblies. - /// - public IEnumerable Assemblies { get; private set; } - - /// - /// Gets the extension this view renderer supports. - /// - public string Extension - { - get { return "cshtml"; } - } - - /// - /// Gets the that should be used with the renderer. - /// - public Type ModelCodeGenerator { get; private set; } - - /// - /// Gets the host. - /// - public RazorEngineHost Host { get; private set; } - - /// - /// Gets the provider that is used to generate code. - /// - public CodeDomProvider Provider { get; private set; } - - /// - /// Initializes a new instance of the class. - /// - public CSharpRazorViewRenderer(RazorAssemblyProvider razorAssemblyProvider) - { - this.Assemblies = new List - { - typeof(Binder).Assembly.Location - }; - - this.ModelCodeGenerator = typeof(ModelCodeGenerator); - - this.Provider = new Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider(); - - this.Host = new NancyRazorEngineHost(new CSharpRazorCodeLanguage(), razorAssemblyProvider); - - this.Host.NamespaceImports.Add("Microsoft.CSharp.RuntimeBinder"); - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - if (this.Provider != null) - { - this.Provider.Dispose(); - } - } - } -} diff --git a/src/Nancy.ViewEngines.Razor/CSharp/NancyCSharpRazorCodeParser.cs b/src/Nancy.ViewEngines.Razor/CSharp/NancyCSharpRazorCodeParser.cs deleted file mode 100644 index 98a89dede2..0000000000 --- a/src/Nancy.ViewEngines.Razor/CSharp/NancyCSharpRazorCodeParser.cs +++ /dev/null @@ -1,81 +0,0 @@ -namespace Nancy.ViewEngines.Razor.CSharp -{ - using System.Globalization; - using System.Linq; - using System.Web.Razor.Parser; - using System.Web.Razor.Text; - using System.Web.Razor.Tokenizer.Symbols; - - /// - /// Nancy razor parser for csharp files. - /// - public class NancyCSharpRazorCodeParser : CSharpCodeParser - { - private readonly RazorAssemblyProvider razorAssemblyProvider; - private bool modelStatementFound; - private SourceLocation? endInheritsLocation; - private readonly ClrTypeResolver clrTypeResolver; - - /// - /// Initializes a new instance of the class. - /// - /// An instance. - public NancyCSharpRazorCodeParser(RazorAssemblyProvider razorAssemblyProvider) - { - this.razorAssemblyProvider = razorAssemblyProvider; - this.MapDirectives(this.ModelDirective, "model"); - - this.clrTypeResolver = new CSharpClrTypeResolver(this.razorAssemblyProvider); - } - - protected virtual void ModelDirective() - { - this.AssertDirective("model"); - - this.AcceptAndMoveNext(); - - var endModelLocation = this.CurrentLocation; - - this.BaseTypeDirective("The 'model' keyword must be followed by a type name on the same line.", s => - { - var symbols = this.Language.TokenizeString(s); - var modelType = this.clrTypeResolver.Resolve(symbols.ToList()); - - if (modelType == null) - { - CodeParserHelper.ThrowTypeNotFound(this.razorAssemblyProvider, s); - } - - return new ModelCodeGenerator(modelType, modelType.FullName); - }); - - if (this.modelStatementFound) - { - this.Context.OnError(endModelLocation, string.Format(CultureInfo.CurrentCulture, "Cannot have more than one @model statement.")); - } - - this.modelStatementFound = true; - this.CheckForInheritsAndModelStatements(); - } - - protected override void InheritsDirective() - { - this.AssertDirective("inherits"); - this.AcceptAndMoveNext(); - - this.endInheritsLocation = this.CurrentLocation; - - base.InheritsDirective(); - - this.CheckForInheritsAndModelStatements(); - } - - private void CheckForInheritsAndModelStatements() - { - if (this.modelStatementFound && this.endInheritsLocation.HasValue) - { - this.Context.OnError(this.endInheritsLocation.Value, string.Format(CultureInfo.CurrentCulture, "Cannot have both an @inherits statement and an @model statement.")); - } - } - } -} diff --git a/src/Nancy.ViewEngines.Razor/ClrTypeResolver.cs b/src/Nancy.ViewEngines.Razor/ClrTypeResolver.cs deleted file mode 100644 index 0c464b1a0e..0000000000 --- a/src/Nancy.ViewEngines.Razor/ClrTypeResolver.cs +++ /dev/null @@ -1,244 +0,0 @@ -namespace Nancy.ViewEngines.Razor -{ - using System; - using System.Collections.Generic; - using System.Diagnostics; - using System.Linq; - using System.Text; - using System.Web.Razor.Tokenizer.Symbols; - - using Nancy.Bootstrapper; - - /// - /// Converts language-specific type name into CRL Type - /// - /// Symbol type enum - /// Symbol class - internal abstract class ClrTypeResolver - where TSymbol : SymbolBase - { - private readonly RazorAssemblyProvider razorAssemblyProvider; - - private readonly TSymbolType identifier; - private readonly TSymbolType keyword; - private readonly TSymbolType dot; - private readonly TSymbolType whiteSpace; - private readonly TSymbolType arrayBegin; - private readonly TSymbolType arrayEnd; - - /// - /// Gets remaining symbols that need to be parsed - /// - protected Queue Symbols { get; private set; } - - /// - /// Initializes new instance of ClrTypeResolver class. - /// Provided parameters are used to recognized specific symbols in particular language - /// - /// An used to resolve model types from the available assemblies. - /// Symbol type for identifier - /// Symbol type for keyword - /// Symbol type for dot ('.') - /// Symbol type for whitespace - /// Type of symbol that begins array - /// Type of symbol that ends array - protected ClrTypeResolver(RazorAssemblyProvider razorAssemblyProvider, TSymbolType identifier, TSymbolType keyword, TSymbolType dot, TSymbolType whiteSpace, TSymbolType arrayBegin, TSymbolType arrayEnd) - { - this.razorAssemblyProvider = razorAssemblyProvider; - this.identifier = identifier; - this.keyword = keyword; - this.dot = dot; - this.whiteSpace = whiteSpace; - this.arrayBegin = arrayBegin; - this.arrayEnd = arrayEnd; - } - - /// - /// Parses given list of symbols in order to get CLR type - /// - /// List of symbols - /// CLR type - public Type Resolve(List symbols) - { - this.Symbols = new Queue(symbols); - - var type = this.ResolveType(); - - return type.Resolve(ResolveTypeByName); - } - - /// - /// Dequeues symbols until first symbol of first generic argument - /// - /// Returns true if move was successful - protected abstract bool MoveToGenericArguments(); - - /// - /// Dequeues symbols representing separator between generic arguments - /// - protected abstract void MoveToNextGenericArgument(); - - /// - /// Dequeues symbols representing end of generic arguments - /// - /// Returns true if move was successful - protected abstract bool MoveOutOfGenericArguments(); - - /// - /// Gets CLR from name (keyword) used by specific language - /// - /// Type name to resolve - /// CLR type - protected abstract Type ResolvePrimitiveType(string typeName); - - private TypeNameParserStep ResolveType() - { - var identifier = this.PopFullIdentifier(); - - var step = new TypeNameParserStep(identifier); - - if (!this.Symbols.Any()) - { - return step; - } - - step.GenericArguments.AddRange(this.ReadGenericArguments()); - - step.ArrayExpression = this.ReadArrayExpression(); - - return step; - } - - private List ReadGenericArguments() - { - var genericArgs = new List(); - - if (this.MoveToGenericArguments()) - { - while (!MoveOutOfGenericArguments()) - { - genericArgs.Add(this.ResolveType()); - - this.MoveToNextGenericArgument(); - } - } - - return genericArgs; - } - - private string PopFullIdentifier() - { - var builder = new StringBuilder(); - - while (this.Symbols.Any()) - { - var peekType = this.Symbols.Peek().Type; - - if (peekType.Equals(this.keyword)) - { - return this.Symbols.Dequeue().Content; - } - else if (peekType.Equals(this.identifier)) - { - builder.Append(this.Symbols.Dequeue().Content); - } - else if (peekType.Equals(this.dot)) - { - this.Symbols.Dequeue(); - builder.Append("."); - } - else if (peekType.Equals(this.whiteSpace)) - { - this.Symbols.Dequeue(); - } - else - { - return builder.ToString(); - } - } - - return builder.ToString(); - } - - private string ReadArrayExpression() - { - var arrayExpr = ""; - - while (this.Symbols.Any() && this.Symbols.Peek().Type.Equals(this.arrayBegin)) - { - this.Symbols.Dequeue(); - - arrayExpr += "["; - - while (!(this.Symbols.Peek().Type.Equals(this.arrayEnd))) - { - arrayExpr += this.Symbols.Dequeue().Content; - } - - arrayExpr += "]"; - this.Symbols.Dequeue(); - } - - return arrayExpr; - } - - private Type ResolveTypeByName(string typeName) - { - return Type.GetType(typeName) - ?? this.ResolvePrimitiveType(typeName) - ?? this.ResolveTypeFromAssemblyCatalog(typeName); - } - - private Type ResolveTypeFromAssemblyCatalog(string typeName) - { - return this.razorAssemblyProvider.GetAssemblies().Select(assembly => assembly.GetType(typeName)).FirstOrDefault(type => type != null); - } - - [DebuggerDisplay("{GenericTypeName}`{GenericArguments.Count}")] - private class TypeNameParserStep - { - public string GenericTypeName { get; set; } - public List GenericArguments { get; private set; } - public string ArrayExpression { get; set; } - - public TypeNameParserStep(string name) - { - this.GenericTypeName = name; - this.GenericArguments = new List(); - this.ArrayExpression = string.Empty; - } - - /// - /// Resolves CLR type that is represented by this instance - /// - /// Function that allows resolving any simple (like int or MyNamespace.SuperClass) type name to CLR type - /// Resolved CLR type - public Type Resolve(Func resolveType) - { - var effectiveArguments = this.GenericArguments.Where(x => x.GenericTypeName != string.Empty).ToArray(); - - Type resultType = null; - - if (effectiveArguments.Length == 0) - { - resultType = resolveType(this.GenericTypeName); - } - else - { - var genericArguments = effectiveArguments.Select(x => x.Resolve(resolveType)).ToArray(); - - var genericType = resolveType(string.Format("{0}`{1}", this.GenericTypeName, effectiveArguments.Length)); - - resultType = genericType.MakeGenericType(genericArguments); - } - - if (this.ArrayExpression != "") - { - resultType = resolveType(resultType.FullName + this.ArrayExpression); - } - - return resultType; - } - } - } -} diff --git a/src/Nancy.ViewEngines.Razor/CodeParserHelper.cs b/src/Nancy.ViewEngines.Razor/CodeParserHelper.cs deleted file mode 100644 index 85eed0dc1e..0000000000 --- a/src/Nancy.ViewEngines.Razor/CodeParserHelper.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace Nancy.ViewEngines.Razor -{ - using System; - using System.Linq; - - internal static class CodeParserHelper - { - /// - /// Throws exception says that given type was not found in any accessible assembly - /// - /// An instance. - /// Type that was not found - public static void ThrowTypeNotFound(RazorAssemblyProvider razorAssemblyProvider, string type) - { - throw new NotSupportedException(string.Format( - "Unable to discover CLR Type for model by the name of {0}.\n\nTry using a fully qualified type name and ensure that the assembly is added to the configuration file.\n\nCurrent RazorAssemblyProvider assemblies:\n\t{1}.", - type, - razorAssemblyProvider.GetAssemblies().Select(a => a.FullName).Aggregate((n1, n2) => n1 + "\n\t" + n2))); - } - } -} diff --git a/src/Nancy.ViewEngines.Razor/DefaultRazorConfiguration.cs b/src/Nancy.ViewEngines.Razor/DefaultRazorConfiguration.cs index 7b5a2c23e0..4dc382ba54 100644 --- a/src/Nancy.ViewEngines.Razor/DefaultRazorConfiguration.cs +++ b/src/Nancy.ViewEngines.Razor/DefaultRazorConfiguration.cs @@ -1,46 +1,38 @@ -namespace Nancy.ViewEngines.Razor +using System; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; + +namespace Nancy.ViewEngines.Razor { using System.Collections.Generic; - using System.Configuration; using System.Linq; + using Microsoft.Extensions.Configuration; /// /// /// - public class DefaultRazorConfiguration : IRazorConfiguration + public class DefaultRazorConfiguration : IRazorConfiguration { - private readonly RazorConfigurationSection razorConfigurationSection; + private readonly IConfigurationSection razorSection; /// /// Initializes a new instance of the class. /// public DefaultRazorConfiguration() { - this.razorConfigurationSection = ConfigurationManager.GetSection("razor") as RazorConfigurationSection; + var configurationBuilder = new ConfigurationBuilder() + .AddJsonFile("appsettings.json", true) + .AddEnvironmentVariables(); + var configuration = configurationBuilder.Build(); + this.razorSection = configuration.GetSection("Razor"); } - /// - /// Gets a value indicating whether to automatically include the model's namespace in the generated code. - /// - /// - /// true if the model's namespace should be automatically included in the generated code; otherwise, false. - /// - public bool AutoIncludeModelNamespace - { - get { return (this.razorConfigurationSection == null || (!this.razorConfigurationSection.DisableAutoIncludeModelNamespace)); } - } - /// /// Gets the assembly names to include in the generated assembly. /// public IEnumerable GetAssemblyNames() { - if (this.razorConfigurationSection == null || this.razorConfigurationSection.Assemblies == null) - { - return Enumerable.Empty(); - } - - return this.razorConfigurationSection.Assemblies.Select(a => a.AssemblyName); + return razorSection?.GetValue("Assemblies") ?? Enumerable.Empty(); } /// @@ -48,12 +40,7 @@ public IEnumerable GetAssemblyNames() /// public IEnumerable GetDefaultNamespaces() { - if (this.razorConfigurationSection == null || this.razorConfigurationSection.Namespaces == null) - { - return Enumerable.Empty(); - } - - return this.razorConfigurationSection.Namespaces.Select(n=>n.NamespaceName); + return razorSection?.GetValue("Namespaces") ?? Enumerable.Empty(); } } } \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/EmptyChangeToken.cs b/src/Nancy.ViewEngines.Razor/EmptyChangeToken.cs new file mode 100644 index 0000000000..5a2fa2c45c --- /dev/null +++ b/src/Nancy.ViewEngines.Razor/EmptyChangeToken.cs @@ -0,0 +1,14 @@ +using System; +using Microsoft.Extensions.Primitives; + +namespace Nancy.ViewEngines.Razor +{ + public class EmptyChangeToken : IChangeToken + { + public IDisposable RegisterChangeCallback(Action callback, object state) => + new EmptyDisposable(); + + public bool HasChanged => false; + public bool ActiveChangeCallbacks => false; + } +} \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/EmptyDisposable.cs b/src/Nancy.ViewEngines.Razor/EmptyDisposable.cs new file mode 100644 index 0000000000..09709f9554 --- /dev/null +++ b/src/Nancy.ViewEngines.Razor/EmptyDisposable.cs @@ -0,0 +1,12 @@ +using System; + +namespace Nancy.ViewEngines.Razor +{ + public class EmptyDisposable : IDisposable + { + public void Dispose() + { + // Do nothing + } + } +} \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/EncodedHtmlString.cs b/src/Nancy.ViewEngines.Razor/EncodedHtmlString.cs deleted file mode 100644 index 1185f089c0..0000000000 --- a/src/Nancy.ViewEngines.Razor/EncodedHtmlString.cs +++ /dev/null @@ -1,55 +0,0 @@ -namespace Nancy.ViewEngines.Razor -{ - using Nancy.Helpers; - - /// - /// An html string that is encoded. - /// - public class EncodedHtmlString : IHtmlString - { - /// - /// Represents the empty . This field is readonly. - /// - public static readonly EncodedHtmlString Empty = new EncodedHtmlString(string.Empty); - - private readonly string encodedValue; - - /// - /// Initializes a new instance of the class. - /// - /// The encoded value. - public EncodedHtmlString(string value) - { - this.encodedValue = HttpUtility.HtmlEncode(value); - } - - /// - /// Returns an HTML-encoded string. - /// - /// An HTML-encoded string. - public string ToHtmlString() - { - return this.encodedValue; - } - - /// - /// Implicitly cast a string to an instance. - /// - /// The string that should be encoded. - /// An instance - public static implicit operator EncodedHtmlString(string value) - { - return new EncodedHtmlString(value); - } - - /// - /// Implicitly cast an instance to a string. - /// - /// The instance. - /// A string containing the encoded value. - public static implicit operator string(EncodedHtmlString encoded) - { - return encoded.encodedValue; - } - } -} diff --git a/src/Nancy.ViewEngines.Razor/HelperResult.cs b/src/Nancy.ViewEngines.Razor/HelperResult.cs deleted file mode 100644 index d2dad735c4..0000000000 --- a/src/Nancy.ViewEngines.Razor/HelperResult.cs +++ /dev/null @@ -1,60 +0,0 @@ -namespace Nancy.ViewEngines.Razor -{ - using System; - using System.Globalization; - using System.IO; - - /// - /// Helped class used by Razor to render generated code. - /// - public class HelperResult : IHtmlString - { - private readonly Action action; - - /// - /// Initializes a new instance of the class, - /// with the provided . - /// - /// The action that should be used to produce the result. - public HelperResult(Action action) - { - if (action == null) - { - throw new ArgumentNullException("action", "The action parameter cannot be null."); - } - - this.action = action; - } - - /// - /// Returns a HTML formatted that represents the current . - /// - /// A HTML formatted that represents the current . - public string ToHtmlString() - { - return this.ToString(); - } - - /// - /// Returns a that represents the current . - /// - /// A that represents the current . - public override string ToString() - { - using (var stringWriter = new StringWriter(CultureInfo.InvariantCulture)) - { - this.action(stringWriter); - return stringWriter.ToString(); - } - } - - /// - /// Writes the output of the to the provided . - /// - /// A instance that the output should be written to. - public void WriteTo(TextWriter writer) - { - this.action(writer); - } - } -} \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/HostingEnvironment.cs b/src/Nancy.ViewEngines.Razor/HostingEnvironment.cs new file mode 100644 index 0000000000..43f36c0eff --- /dev/null +++ b/src/Nancy.ViewEngines.Razor/HostingEnvironment.cs @@ -0,0 +1,48 @@ +using System; +using System.Reflection; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.FileProviders; + +namespace Nancy.ViewEngines.Razor +{ + public class HostingEnvironment : IHostingEnvironment + { + public HostingEnvironment() + { + // TODO: Why is this getting constructed more than once when it's scoped? + } + + public string EnvironmentName + { + get { return "Nancy"; } + set { throw new NotSupportedException(); } + } + + // This gets used to load dependencies and is passed to Assembly.Load() + public string ApplicationName + { + get { return typeof(HostingEnvironment).GetTypeInfo().Assembly.FullName; } + set { throw new NotSupportedException(); } + } + + public IFileProvider WebRootFileProvider { get; set; } + + public string WebRootPath + { + get { return "/"; } + set { throw new NotSupportedException(); } + } + + public string ContentRootPath + { + get { return WebRootPath; } + set { WebRootPath = value; } + } + + public IFileProvider ContentRootFileProvider + { + get { return WebRootFileProvider; } + set { WebRootFileProvider = value; } + } + } +} \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/HtmlHelpers.cs b/src/Nancy.ViewEngines.Razor/HtmlHelpers.cs deleted file mode 100644 index 3ee9874eaf..0000000000 --- a/src/Nancy.ViewEngines.Razor/HtmlHelpers.cs +++ /dev/null @@ -1,142 +0,0 @@ -namespace Nancy.ViewEngines.Razor -{ - using System; - using System.IO; - using System.Linq; - using System.Security.Claims; - - /// - /// Helpers to generate html content. - /// - /// The type of the model. - public class HtmlHelpers : HtmlHelpers - { - /// - /// Initializes a new instance of the class. - /// - /// The razor view engine instance that the helpers are being used by. - /// The that the helper are being used by. - /// The model that is used by the page where the helpers are invoked. - public HtmlHelpers(RazorViewEngine engine, IRenderContext renderContext, TModel model) : base(engine, renderContext) - { - this.Model = model; - } - - /// - /// The model that is being used by the current view. - /// - /// An instance of the view model. - public TModel Model { get; set; } - } - - /// - /// Base helpers to generate html content. - /// - public abstract class HtmlHelpers - { - /// - /// Initializes a new instance of the class. - /// - /// The razor view engine instance that the helpers are being used by. - /// The that the helper are being used by. - protected HtmlHelpers(RazorViewEngine engine, IRenderContext renderContext) - { - this.Engine = engine; - this.RenderContext = renderContext; - } - - /// - /// The engine that is currently rendering the view. - /// - /// A instance. - public RazorViewEngine Engine { get; set; } - - /// - /// The context of the current render operation. - /// - /// An instance. - public IRenderContext RenderContext { get; set; } - - /// - /// Renders a partial with the given view name. - /// - /// Name of the view. - /// An representation of the partial. - public IHtmlString Partial(string viewName) - { - return this.Partial(viewName, null); - } - - /// - /// Renders a partial with the given view name. - /// - /// Name of the partial view. - /// The model that is passed to the partial. - /// An representation of the partial. - public IHtmlString Partial(string viewName, dynamic modelForPartial) - { - var view = this.RenderContext.LocateView(viewName, modelForPartial); - if (view == null) - { - throw new ViewNotFoundException(viewName, this.Engine.Extensions.ToArray()); - } - - var response = this.Engine.RenderView(view, modelForPartial, this.RenderContext, true); - Action action = response.Contents; - var mem = new MemoryStream(); - - action.Invoke(mem); - mem.Position = 0; - - var reader = new StreamReader(mem); - - return new NonEncodedHtmlString(reader.ReadToEnd()); - } - - /// - /// Returns an html string composed of raw, non-encoded text. - /// - /// The text. - /// An representation of the raw text. - public IHtmlString Raw(string text) - { - return new NonEncodedHtmlString(text); - } - - /// - /// Creates an anti-forgery token. - /// - /// An representation of the anti forgery token. - public IHtmlString AntiForgeryToken() - { - var tokenKeyValue = - this.RenderContext.GetCsrfToken(); - - return new NonEncodedHtmlString(String.Format("", tokenKeyValue.Key, tokenKeyValue.Value)); - } - - /// - /// Returns current culture name - /// - public string CurrentLocale - { - get { return this.RenderContext.Context.Culture.Name; } - } - - /// - /// Returns current authenticated user name - /// - public ClaimsPrincipal CurrentUser - { - get { return this.RenderContext.Context.CurrentUser; } - } - - /// - /// Determines if current user is authenticated - /// - public bool IsAuthenticated - { - get { return this.RenderContext.Context.CurrentUser != null; } - } - } -} diff --git a/src/Nancy.ViewEngines.Razor/HtmlHelpersExtensions.cs b/src/Nancy.ViewEngines.Razor/HtmlHelpersExtensions.cs deleted file mode 100644 index caabc0decc..0000000000 --- a/src/Nancy.ViewEngines.Razor/HtmlHelpersExtensions.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace Nancy.ViewEngines.Razor -{ - /// - /// Razor HTML Helper Extensions - /// - public static class HtmlHelpersExtensions - { - /// - /// Create a hidden input field called X-HTTP-Method-Override for the specified - /// - /// The model type. - /// A reference to the instance. - /// The HTTP method to use. - /// A string representation of the input field. - public static IHtmlString HttpMethodOverride(this HtmlHelpers helpers, string method) - { - var tag = - string.Format("", method); - - return new NonEncodedHtmlString(tag); - } - } -} \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/IHtmlString.cs b/src/Nancy.ViewEngines.Razor/IHtmlString.cs deleted file mode 100644 index 5ece868a58..0000000000 --- a/src/Nancy.ViewEngines.Razor/IHtmlString.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace Nancy.ViewEngines.Razor -{ - public interface IHtmlString - { - /// - /// Returns an HTML-encoded string. - /// - /// An HTML-encoded string. - string ToHtmlString(); - } -} \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/INancyRazorView.cs b/src/Nancy.ViewEngines.Razor/INancyRazorView.cs deleted file mode 100644 index 59383c4ba3..0000000000 --- a/src/Nancy.ViewEngines.Razor/INancyRazorView.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Nancy.ViewEngines.Razor -{ - public interface INancyRazorView - { - } -} \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/IRazorConfiguration.cs b/src/Nancy.ViewEngines.Razor/IRazorConfiguration.cs index 3563fa76c6..55b924da65 100644 --- a/src/Nancy.ViewEngines.Razor/IRazorConfiguration.cs +++ b/src/Nancy.ViewEngines.Razor/IRazorConfiguration.cs @@ -7,14 +7,6 @@ /// public interface IRazorConfiguration { - /// - /// Gets a value indicating whether to automatically include the model's namespace in the generated code. - /// - /// - /// true if the model's namespace should be automatically included in the generated code; otherwise, false. - /// - bool AutoIncludeModelNamespace { get; } - /// /// Gets the assembly names. /// diff --git a/src/Nancy.ViewEngines.Razor/IRazorViewRenderer.cs b/src/Nancy.ViewEngines.Razor/IRazorViewRenderer.cs deleted file mode 100644 index 7d2326ddaf..0000000000 --- a/src/Nancy.ViewEngines.Razor/IRazorViewRenderer.cs +++ /dev/null @@ -1,39 +0,0 @@ -namespace Nancy.ViewEngines.Razor -{ - using System; - using System.CodeDom.Compiler; - using System.Collections.Generic; - using System.Web.Razor; - using System.Web.Razor.Generator; - - /// - /// Renders a view. - /// - public interface IRazorViewRenderer - { - /// - /// Gets the assemblies. - /// - IEnumerable Assemblies { get; } - - /// - /// Gets the that should be used with the renderer. - /// - Type ModelCodeGenerator { get; } - - /// - /// Gets the extension this view renderer supports. - /// - string Extension { get; } - - /// - /// Gets the host. - /// - RazorEngineHost Host { get; } - - /// - /// Gets the provider that is used to generate code. - /// - CodeDomProvider Provider { get; } - } -} diff --git a/src/Nancy.ViewEngines.Razor/LocationProviderDirectoryContents.cs b/src/Nancy.ViewEngines.Razor/LocationProviderDirectoryContents.cs new file mode 100644 index 0000000000..779b557f3f --- /dev/null +++ b/src/Nancy.ViewEngines.Razor/LocationProviderDirectoryContents.cs @@ -0,0 +1,38 @@ +namespace Nancy.ViewEngines.Razor +{ + using System.Collections; + using System.Collections.Generic; + using System.Linq; + using Microsoft.Extensions.FileProviders; + + public class LocationProviderDirectoryContents : IDirectoryContents + { + private readonly IViewLocationProvider locationProvider; + private readonly string subpath; + + public LocationProviderDirectoryContents(IViewLocationProvider locationProvider, string subpath) + { + this.locationProvider = locationProvider; + this.subpath = subpath; + } + + public IEnumerator GetEnumerator() + { + return this.locationProvider + .GetLocatedViews(RazorViewEngine.SupportedExtensions) + .Where(viewLocation => viewLocation.Location == this.subpath) + .Select(viewLocation => new ViewLocationFileInfo(viewLocation)) + .GetEnumerator(); + } + + IEnumerator IEnumerable.GetEnumerator() + { + return this.GetEnumerator(); + } + + public bool Exists + { + get { return this.Any(); } + } + } +} \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/MetadataReferenceFeatureProvider.cs b/src/Nancy.ViewEngines.Razor/MetadataReferenceFeatureProvider.cs new file mode 100644 index 0000000000..254220d2cc --- /dev/null +++ b/src/Nancy.ViewEngines.Razor/MetadataReferenceFeatureProvider.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using Microsoft.AspNetCore.Mvc.ApplicationParts; +using Microsoft.AspNetCore.Mvc.Razor.Compilation; +using Microsoft.CodeAnalysis; +using Microsoft.Extensions.DependencyModel; + +namespace Nancy.ViewEngines.Razor +{ + public class MetadataReferenceFeatureProvider : IApplicationFeatureProvider + { + private readonly IRazorConfiguration configuration; + private readonly IAssemblyCatalog assemblyCatalog; + private readonly string[] defaultAssemblyDefinitions = { + "mscorlib", + "System.Private.CoreLib" + }; + + /// + /// Initializes a new instance of the class. + /// + /// An instance. + /// An instance. + public MetadataReferenceFeatureProvider(IRazorConfiguration configuration, IAssemblyCatalog assemblyCatalog) + { + this.configuration = configuration; + this.assemblyCatalog = assemblyCatalog; + } + + public void PopulateFeature(IEnumerable parts, MetadataReferenceFeature feature) + { + if (parts == null) + { + throw new ArgumentNullException(nameof(parts)); + } + + if (feature == null) + { + throw new ArgumentNullException(nameof(feature)); + } + + foreach (Assembly assembly in GetAllAssemblies().Where(assembly => !assembly.IsDynamic && !string.IsNullOrEmpty(assembly.Location))) + { + feature.MetadataReferences.Add(MetadataReference.CreateFromFile(assembly.Location)); + } + } + + private IReadOnlyCollection GetAllAssemblies() + { + return this.assemblyCatalog.GetAssemblies() + .Union(this.LoadAssembliesInConfiguration()) + .Union(this.LoadDefaultAssemblies()) + .Union(this.LoadReferencedAssemblies()) + .ToArray(); + } + + private IEnumerable LoadAssembliesInConfiguration() + { + var loadedAssemblies = new HashSet(); + + var validAssemblyDefinitions = this.configuration + .GetAssemblyNames() + .Where(definition => !string.IsNullOrEmpty(definition)); + + foreach (var assemblyDefinition in validAssemblyDefinitions) + { + try + { + loadedAssemblies.Add(Assembly.Load(new AssemblyName(assemblyDefinition))); + } + catch + { + } + } + + return loadedAssemblies; + } + + private IEnumerable LoadDefaultAssemblies() + { + var loadedAssemblies = new HashSet(); + + foreach (var assemblyDefinition in this.defaultAssemblyDefinitions) + { + try + { + loadedAssemblies.Add(Assembly.Load(new AssemblyName(assemblyDefinition))); + } + catch + { + } + } + + return loadedAssemblies; + } + + private IEnumerable LoadReferencedAssemblies() + { + var loadedAssemblies = new HashSet(); + +#if CORE + foreach (var library in DependencyContext.Default.RuntimeLibraries) + { + try + { + loadedAssemblies.Add(Assembly.Load(new AssemblyName(library.Name))); + } + catch + { + } + } +#else + foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) + { + loadedAssemblies.Add(assembly); + } +#endif + + return loadedAssemblies; + } + } +} \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/ModelCodeGenerator.cs b/src/Nancy.ViewEngines.Razor/ModelCodeGenerator.cs deleted file mode 100644 index 52f309c820..0000000000 --- a/src/Nancy.ViewEngines.Razor/ModelCodeGenerator.cs +++ /dev/null @@ -1,35 +0,0 @@ -namespace Nancy.ViewEngines.Razor -{ - using System; - using System.CodeDom; - using System.Web.Razor.Generator; - using System.Web.Razor.Parser.SyntaxTree; - - /// - /// Adds base type with model type as generic argument for Razor view class - /// - public class ModelCodeGenerator : SetBaseTypeCodeGenerator - { - private readonly Type modelType; - - public ModelCodeGenerator(Type modelType, string typeFullname) - : base(typeFullname) - { - this.modelType = modelType; - } - - protected override string ResolveType(CodeGeneratorContext context, string baseType) - { - return typeof(object).FullName; - } - - public override void GenerateCode(Span target, CodeGeneratorContext context) - { - base.GenerateCode(target, context); - - context.GeneratedClass.UserData.Add("ModelType", this.modelType); - context.GeneratedClass.BaseTypes.Clear(); - context.GeneratedClass.BaseTypes.Add(new CodeTypeReference(context.Host.DefaultBaseClass, new CodeTypeReference(this.modelType))); - } - } -} \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/Nancy.ViewEngines.Razor.xproj b/src/Nancy.ViewEngines.Razor/Nancy.ViewEngines.Razor.xproj index c5e6b12d3b..72efa55785 100644 --- a/src/Nancy.ViewEngines.Razor/Nancy.ViewEngines.Razor.xproj +++ b/src/Nancy.ViewEngines.Razor/Nancy.ViewEngines.Razor.xproj @@ -1,21 +1,19 @@ - + 14.0 $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - + 3a376b78-dd7d-4450-9fde-f7236faa6e63 Nancy.ViewEngines.Razor .\obj .\bin\ - - - Nancy.ViewEngines.Razor + v4.6 2.0 - + \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/NancyRazorEngineHost.cs b/src/Nancy.ViewEngines.Razor/NancyRazorEngineHost.cs deleted file mode 100644 index b9be20e631..0000000000 --- a/src/Nancy.ViewEngines.Razor/NancyRazorEngineHost.cs +++ /dev/null @@ -1,48 +0,0 @@ -namespace Nancy.ViewEngines.Razor -{ - using System.Web.Razor; - using System.Web.Razor.Generator; - using System.Web.Razor.Parser; - using Nancy.ViewEngines.Razor.CSharp; - - /// - /// A custom razor engine host responsible for decorating the existing code generators with nancy versions. - /// - public class NancyRazorEngineHost : RazorEngineHost - { - private readonly RazorAssemblyProvider razorAssemblyProvider; - - /// - /// Initializes a new instance of the class. - /// - public NancyRazorEngineHost(RazorCodeLanguage language, RazorAssemblyProvider razorAssemblyProvider) - : base(language) - { - this.razorAssemblyProvider = razorAssemblyProvider; - this.DefaultBaseClass = typeof (NancyRazorViewBase).FullName; - this.DefaultNamespace = "RazorOutput"; - this.DefaultClassName = "RazorView"; - - var context = new GeneratedClassContext("Execute", "Write", "WriteLiteral", "WriteTo", "WriteLiteralTo", - typeof (HelperResult).FullName, "DefineSection"); - context.ResolveUrlMethodName = "ResolveUrl"; - - this.GeneratedClassContext = context; - } - - /// - /// Decorates the code parser. - /// - /// The incoming code parser. - /// - public override ParserBase DecorateCodeParser(ParserBase incomingCodeParser) - { - if (incomingCodeParser is CSharpCodeParser) - { - return new NancyCSharpRazorCodeParser(this.razorAssemblyProvider); - } - - return base.DecorateCodeParser(incomingCodeParser); - } - } -} \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/NancyRazorErrorView.cs b/src/Nancy.ViewEngines.Razor/NancyRazorErrorView.cs index 1b4e132916..ec623ab258 100644 --- a/src/Nancy.ViewEngines.Razor/NancyRazorErrorView.cs +++ b/src/Nancy.ViewEngines.Razor/NancyRazorErrorView.cs @@ -2,11 +2,13 @@ { using System; using System.IO; + using System.Reflection; + using System.Threading.Tasks; /// /// Razor view used when compilation of the view fails. /// - public class NancyRazorErrorView : NancyRazorViewBase + public class NancyRazorErrorView : NancyRazorPage { private readonly TraceConfiguration traceConfiguration; @@ -44,14 +46,14 @@ public NancyRazorErrorView(string message, TraceConfiguration traceConfiguration /// /// Executes this instance. /// - public override void Execute() + public override async Task ExecuteAsync() { base.WriteLiteral(Template.Replace("[DETAILS]", this.traceConfiguration.DisplayErrorTraces ? this.Message : DisplayErrorTracesFalseMessage)); } private static string LoadResource(string filename) { - var resourceStream = typeof(NancyRazorErrorView).Assembly.GetManifestResourceStream(String.Format("Nancy.ViewEngines.Razor.Resources.{0}", filename)); + var resourceStream = typeof(NancyRazorErrorView).GetTypeInfo().Assembly.GetManifestResourceStream(String.Format("Nancy.ViewEngines.Razor.Resources.{0}", filename)); if (resourceStream == null) { diff --git a/src/Nancy.ViewEngines.Razor/NancyRazorHost.cs b/src/Nancy.ViewEngines.Razor/NancyRazorHost.cs new file mode 100644 index 0000000000..a7870a7e95 --- /dev/null +++ b/src/Nancy.ViewEngines.Razor/NancyRazorHost.cs @@ -0,0 +1,26 @@ +using System.Linq; +using Microsoft.AspNetCore.Mvc.Razor; +using Microsoft.AspNetCore.Mvc.Razor.Directives; +using Microsoft.AspNetCore.Razor.Chunks; +using Microsoft.AspNetCore.Razor.Compilation.TagHelpers; + +namespace Nancy.ViewEngines.Razor +{ + public class NancyRazorHost : MvcRazorHost + { + private const string BaseType = "Nancy.ViewEngines.Razor.NancyRazorPage"; + + public NancyRazorHost(IRazorConfiguration configuration, IChunkTreeCache chunkTreeCache, ITagHelperDescriptorResolver resolver) : base(chunkTreeCache, resolver) + { + DefaultBaseClass = $"{BaseType}<{ChunkHelper.TModelToken}>"; + DefaultInheritedChunks.OfType().First().TypeName = DefaultBaseClass; // The chunk is actually what injects the base name into the view + EnableInstrumentation = false; + + // Add additional default namespaces from the execution context + foreach (string ns in configuration.GetDefaultNamespaces()) + { + NamespaceImports.Add(ns); + } + } + } +} \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/NancyRazorPage.cs b/src/Nancy.ViewEngines.Razor/NancyRazorPage.cs new file mode 100644 index 0000000000..9981b5bb00 --- /dev/null +++ b/src/Nancy.ViewEngines.Razor/NancyRazorPage.cs @@ -0,0 +1,46 @@ +using Microsoft.AspNetCore.Mvc.Razor; + +namespace Nancy.ViewEngines.Razor +{ + using Microsoft.AspNetCore.Mvc.Razor.Internal; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + + /// + /// Default base class for Nancy razor views + /// + public abstract class NancyRazorPage : RazorPage + { + public new dynamic ViewBag + { + get + { + var viewContext = this.ViewContext as NancyViewContext; + return viewContext == null ? null : viewContext.RenderContext.Context.ViewBag; + } + } + } + + /// + /// Default base class for Nancy Razor views with typed models. + /// Copied from ASP.NET MVC Core . + /// + public abstract class NancyRazorPage : NancyRazorPage + { + /// + /// Gets the Model property of the property. + /// + public TModel Model + { + get + { + if (this.ViewData != null) + return this.ViewData.Model; + return default(TModel); + } + } + + /// Gets or sets the dictionary for view data. + [RazorInject] + public ViewDataDictionary ViewData { get; set; } + } +} \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/NancyRazorViewBase.cs b/src/Nancy.ViewEngines.Razor/NancyRazorViewBase.cs deleted file mode 100644 index 66cb905db0..0000000000 --- a/src/Nancy.ViewEngines.Razor/NancyRazorViewBase.cs +++ /dev/null @@ -1,446 +0,0 @@ -namespace Nancy.ViewEngines.Razor -{ - using System; - using System.Collections.Generic; - using System.Globalization; - using System.IO; - using System.Text; - - using Nancy.Helpers; - - /// - /// Default base class for nancy razor views - /// - public abstract class NancyRazorViewBase : NancyRazorViewBase - { - } - - /// - /// Base class for nancy razor views. - /// - /// Model type - public abstract class NancyRazorViewBase : INancyRazorView - { - private readonly StringBuilder contents; - private string childBody; - private IDictionary childSections; - - /// - /// Gets the Html helper. - /// - public HtmlHelpers Html { get; private set; } - - /// - /// Gets the model. - /// - public TModel Model { get; private set; } - - /// - /// Gets the Url helper. - /// - public UrlHelpers Url { get; private set; } - - /// - /// Non-model specific data for rendering in the response - /// - public dynamic ViewBag { get; private set; } - - /// - /// Gets the body. - /// - public String Body { get; private set; } - - /// - /// Gets or sets the section contents. - /// - /// - /// The section contents. - /// - public IDictionary SectionContents { get; set; } - - /// - /// Gets or sets the layout. - /// - /// - /// The layout. - /// - public string Layout { get; set; } - - /// - /// Gets a value indicating whether this instance has layout. - /// - /// - /// true if this instance has layout; otherwise, false. - /// - public bool HasLayout - { - get { return !string.IsNullOrEmpty(this.Layout); } - } - - /// - /// Gets or sets the code. - /// - /// - /// The code. - /// - public string Code { get; set; } - - /// - /// Gets or sets the path. - /// - /// - /// The path. - /// - public string Path { get; set; } - - /// - /// Gets or sets the sections. - /// - /// - /// The sections. - /// - public IDictionary Sections { get; set; } - - /// - /// Used to return text resources - /// - public dynamic Text - { - get - { - return this.RenderContext.TextResourceFinder; - } - } - - /// - /// Executes the view. - /// - public abstract void Execute(); - - /// - /// Initializes the specified engine. - /// - /// The engine. - /// The render context. - /// The model. - public virtual void Initialize(RazorViewEngine engine, IRenderContext renderContext, object model) - { - var castedModel = default(TModel); - - if (model != null) - { - castedModel = (TModel)model; - } - - this.RenderContext = renderContext; - this.Html = new HtmlHelpers(engine, renderContext, castedModel); - this.Model = castedModel; - this.Url = new UrlHelpers(engine, renderContext); - this.ViewBag = renderContext.Context.ViewBag; - } - - protected IRenderContext RenderContext { get; set; } - - /// - /// Gets the current instance. - /// - /// A instance. - public NancyContext Context - { - get { return this.RenderContext.Context; } - } - - /// - /// Gets the current instance. - /// - /// A instance. - public Request Request - { - get { return this.Context.Request; } - } - - /// - /// Initializes a new instance of the class. - /// - protected NancyRazorViewBase() - { - this.Sections = new Dictionary(); - this.contents = new StringBuilder(); - } - - /// - /// Writes the results of expressions like: "@foo.Bar" - /// - /// The value. - public virtual void Write(object value) - { - WriteLiteral(HtmlEncode(value)); - } - - /// - /// Writes literals like markup: "

Foo

" - ///
- /// The value. - public virtual void WriteLiteral(object value) - { - contents.Append(value); - } - - public virtual void WriteAttribute(string name, Tuple prefix, Tuple suffix, params AttributeValue[] values) - { - var attributeValue = this.BuildAttribute(name, prefix, suffix, values); - this.WriteLiteral(attributeValue); - } - - public virtual void WriteAttributeTo(TextWriter writer, string name, Tuple prefix, Tuple suffix, params AttributeValue[] values) - { - var attributeValue = this.BuildAttribute(name, prefix, suffix, values); - this.WriteLiteralTo(writer, attributeValue); - } - - private string BuildAttribute(string name, Tuple prefix, Tuple suffix, - params AttributeValue[] values) - { - var writtenAttribute = false; - var attributeBuilder = new StringBuilder(prefix.Item1); - - foreach (var value in values) - { - if (this.ShouldWriteValue(value.Value.Item1)) - { - var stringValue = this.GetStringValue(value); - var valuePrefix = value.Prefix.Item1; - - // encode anything that hasn't opted out of it - if (!(value.Value.Item1 is IHtmlString)) - { - stringValue = HtmlEncode(stringValue); - } - - if (!string.IsNullOrEmpty(valuePrefix)) - { - attributeBuilder.Append(valuePrefix); - } - - attributeBuilder.Append(stringValue); - writtenAttribute = true; - } - } - - attributeBuilder.Append(suffix.Item1); - - var renderAttribute = writtenAttribute || values.Length == 0; - - if (renderAttribute) - { - return attributeBuilder.ToString(); - } - - return string.Empty; - } - - private string GetStringValue(AttributeValue value) - { - if (value.IsLiteral) - { - return (string)value.Value.Item1; - } - - if (value.Value.Item1 is IHtmlString) - { - return ((IHtmlString)value.Value.Item1).ToHtmlString(); - } - - if (value.Value.Item1 is DynamicDictionaryValue) - { - var dynamicValue = (DynamicDictionaryValue)value.Value.Item1; - return dynamicValue.HasValue ? dynamicValue.Value.ToString() : string.Empty; - } - - return value.Value.Item1.ToString(); - } - - private bool ShouldWriteValue(object value) - { - if (value == null) - { - return false; - } - - if (value is bool) - { - var boolValue = (bool)value; - - return boolValue; - } - - return true; - } - - /// - /// Writes the provided to the provided . - /// - /// The that should be written to. - /// The value that should be written. - public virtual void WriteTo(TextWriter writer, object value) - { - writer.Write(HtmlEncode(value)); - } - - /// - /// Writes the provided , as a literal, to the provided . - /// - /// The that should be written to. - /// The value that should be written as a literal. - public virtual void WriteLiteralTo(TextWriter writer, object value) - { - writer.Write(value); - } - - /// - /// Writes the provided to the provided . - /// - /// The that should be written to. - /// The that should be written. - public virtual void WriteTo(TextWriter writer, HelperResult value) - { - if (value != null) - { - value.WriteTo(writer); - } - } - - /// - /// Writes the provided , as a literal, to the provided . - /// - /// The that should be written to. - /// The that should be written as a literal. - public virtual void WriteLiteralTo(TextWriter writer, HelperResult value) - { - if (value != null) - { - value.WriteTo(writer); - } - } - - /// - /// Stores sections - /// - /// Name of the section. - /// The action. - public virtual void DefineSection(string sectionName, Action action) - { - this.Sections.Add(sectionName, action); - } - - /// - /// Renders the section. - /// - /// Name of the section. - /// - public virtual object RenderSection(string sectionName) - { - return this.RenderSection(sectionName, true); - } - - /// - /// Renders the section. - /// - /// Name of the section. - /// if set to true [required]. - public virtual object RenderSection(string sectionName, bool required) - { - string sectionContent; - - var exists = this.childSections.TryGetValue(sectionName, out sectionContent); - if (!exists && required) - { - throw new InvalidOperationException("Section name " + sectionName + " not found and is required."); - } - - this.contents.Append(sectionContent ?? String.Empty); - - return null; - } - - /// - /// Renders the body. - /// - /// - public virtual object RenderBody() - { - this.contents.Append(this.childBody); - - return null; - } - - /// - ///Indicates if a section is defined. - /// - public virtual bool IsSectionDefined(string sectionName) - { - return this.childSections.ContainsKey(sectionName); - } - - public virtual string ResolveUrl(string url) - { - return this.RenderContext.ParsePath(url); - } - - /// - /// Executes the view. - /// - /// The body. - /// The section contents. - public void ExecuteView(string body, IDictionary sectionContents) - { - this.childBody = body ?? string.Empty; - this.childSections = sectionContents ?? new Dictionary(); - - try - { - this.Execute(); - } - catch (NullReferenceException e) - { - throw new ViewRenderException("Unable to render the view. Most likely the Model, or a property on the Model, is null", e); - } - - this.Body = this.contents.ToString(); - - this.SectionContents = new Dictionary(this.Sections.Count); - foreach (var section in this.Sections) - { - this.contents.Clear(); - try - { - section.Value.Invoke(); - } - catch (NullReferenceException e) - { - throw new ViewRenderException(string.Format("A null reference was encountered while rendering the section {0}. Does the section require a model? (maybe it wasn't passed in)", section.Key), e); - } - this.SectionContents.Add(section.Key, this.contents.ToString()); - } - } - - /// - /// Html encodes an object if required - /// - /// Object to potentially encode - /// String representation, encoded if necessary - private string HtmlEncode(object value) - { - if (value == null) - { - return null; - } - - var str = value as IHtmlString; - - var currentCulture = this.Context.Culture ?? CultureInfo.CurrentCulture; - - return str != null ? str.ToHtmlString() : HttpUtility.HtmlEncode(Convert.ToString(value, currentCulture)); - } - } -} diff --git a/src/Nancy.ViewEngines.Razor/NancyViewContext.cs b/src/Nancy.ViewEngines.Razor/NancyViewContext.cs new file mode 100644 index 0000000000..1ee6366aff --- /dev/null +++ b/src/Nancy.ViewEngines.Razor/NancyViewContext.cs @@ -0,0 +1,25 @@ +namespace Nancy.ViewEngines.Razor +{ + using System.IO; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewEngines; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + + public class NancyViewContext : ViewContext + { + private readonly IRenderContext renderContext; + + public NancyViewContext(IRenderContext renderContext, ActionContext actionContext, IView view, ViewDataDictionary viewData, + ITempDataDictionary tempData, TextWriter writer, HtmlHelperOptions htmlHelperOptions) + : base(actionContext, view, viewData, tempData, writer, htmlHelperOptions) + { + this.renderContext = renderContext; + } + + public IRenderContext RenderContext + { + get { return this.renderContext; } + } + } +} \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/NonEncodedHtmlString.cs b/src/Nancy.ViewEngines.Razor/NonEncodedHtmlString.cs deleted file mode 100644 index 974ce55a75..0000000000 --- a/src/Nancy.ViewEngines.Razor/NonEncodedHtmlString.cs +++ /dev/null @@ -1,38 +0,0 @@ -namespace Nancy.ViewEngines.Razor -{ - /// - /// An html string that is not encoded. - /// - public class NonEncodedHtmlString : IHtmlString - { - /// - /// Represents the empty . This field is readonly. - /// - public static readonly NonEncodedHtmlString Empty = new NonEncodedHtmlString(string.Empty); - - private readonly string value; - - /// - /// Initializes a new instance of the class. - /// - /// The value. - public NonEncodedHtmlString(string value) - { - this.value = value; - } - - /// - /// Returns an HTML-encoded string. - /// - /// An HTML-encoded string. - public string ToHtmlString() - { - return value; - } - - public static implicit operator NonEncodedHtmlString(string value) - { - return new NonEncodedHtmlString(value); - } - } -} \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/RazorAssemblyProvider.cs b/src/Nancy.ViewEngines.Razor/RazorAssemblyProvider.cs deleted file mode 100644 index bcf73775a9..0000000000 --- a/src/Nancy.ViewEngines.Razor/RazorAssemblyProvider.cs +++ /dev/null @@ -1,94 +0,0 @@ -namespace Nancy.ViewEngines.Razor -{ - using System; - using System.Collections.Generic; - using System.Linq; - using System.Reflection; - - /// - /// Provides access to the that are available to Razor. - /// - public class RazorAssemblyProvider - { - private readonly IRazorConfiguration configuration; - private readonly IAssemblyCatalog assemblyCatalog; - private readonly Lazy> assemblies; - private readonly string[] defaultAssemblyDefinitions = { - "mscorlib", - "Microsoft.CSharp", - "System", - "System.Collections", - "System.Collections.Generic", - "System.Core", - "System.Runtime" - }; - - /// - /// Initializes a new instance of the class. - /// - /// An instance. - /// An instance. - public RazorAssemblyProvider(IRazorConfiguration configuration, IAssemblyCatalog assemblyCatalog) - { - this.configuration = configuration; - this.assemblyCatalog = assemblyCatalog; - this.assemblies = new Lazy>(this.GetAllAssemblies); - } - - /// - /// Get all instances that are available to the Razor engine. - /// - /// An of instances. - public IReadOnlyCollection GetAssemblies() - { - return this.assemblies.Value; - } - - private IReadOnlyCollection GetAllAssemblies() - { - return this.assemblyCatalog.GetAssemblies() - .Union(this.LoadAssembliesInConfiguration()) - .Union(this.GetDefaultAssemblies()) - .ToArray(); - } - - private IEnumerable LoadAssembliesInConfiguration() - { - var loadedAssemblies = new HashSet(); - - var validAssemblyDefinitions = this.configuration - .GetAssemblyNames() - .Where(definition => !string.IsNullOrEmpty(definition)); - - foreach (var assemblyDefinition in validAssemblyDefinitions) - { - try - { - loadedAssemblies.Add(Assembly.Load(assemblyDefinition)); - } - catch - { - } - } - - return loadedAssemblies; - } - - private IEnumerable GetDefaultAssemblies() - { - var loadedAssemblies = new HashSet(); - - foreach (var assemblyDefinition in this.defaultAssemblyDefinitions) - { - var assembly = AppDomain.CurrentDomain.GetAssemblies().SingleOrDefault(x => x.GetName().Name.Equals(assemblyDefinition, StringComparison.OrdinalIgnoreCase)); - - if (assembly != null) - { - loadedAssemblies.Add(assembly); - } - } - - return loadedAssemblies; - } - } -} diff --git a/src/Nancy.ViewEngines.Razor/RazorConfigurationSection.cs b/src/Nancy.ViewEngines.Razor/RazorConfigurationSection.cs deleted file mode 100644 index 3c642fa8e0..0000000000 --- a/src/Nancy.ViewEngines.Razor/RazorConfigurationSection.cs +++ /dev/null @@ -1,129 +0,0 @@ -namespace Nancy.ViewEngines.Razor -{ - using System; - using System.Collections; - using System.Collections.Generic; - using System.Configuration; - - public class RazorConfigurationSection : ConfigurationSection - { - [ConfigurationProperty("disableAutoIncludeModelNamespace", DefaultValue = "false", IsRequired = false)] - public Boolean DisableAutoIncludeModelNamespace - { - get { return (Boolean)this["disableAutoIncludeModelNamespace"]; } - set { this["disableAutoIncludeModelNamespace"] = value; } - } - - [ConfigurationProperty("assemblies", IsRequired = false)] - public AssemblyConfigurationCollection Assemblies - { - get { return this["assemblies"] as AssemblyConfigurationCollection; } - set { this["assemblies"] = value; } - } - - [ConfigurationProperty("namespaces", IsRequired = false)] - public NamespaceConfigurationCollection Namespaces - { - get { return this["namespaces"] as NamespaceConfigurationCollection; } - set { this["namespaces"] = value; } - } - } - - public sealed class AssemblyConfigurationItem : ConfigurationElement - { - // repeat this pattern for each additional attribute you want in the tag. - // Only the assembly="foo.dll" portion is defined in this class, and is accessed - // via the AssemblyName property. - public const string AssemblyPropertyName = "assembly"; - - [ConfigurationProperty(AssemblyPropertyName, IsRequired = true, IsKey = true)] - public string AssemblyName - { - get { return this[AssemblyPropertyName] as string; } - set { this[AssemblyPropertyName] = value; } - } - } - - public class AssemblyConfigurationCollection : ConfigurationElementCollection, IEnumerable - { - public const string PluginsElementName = "assembly"; - - protected override string ElementName - { - get { return PluginsElementName; } - } - - // this is extraneous, but I find it very useful for enumerating over a configuration collection in a type-safe manner. - - #region IEnumerable Members - - public new IEnumerator GetEnumerator() - { - foreach (AssemblyConfigurationItem item in (this as IEnumerable)) - { - yield return item; - } - } - - #endregion - - protected override ConfigurationElement CreateNewElement() - { - return new AssemblyConfigurationItem(); - } - - protected override object GetElementKey(ConfigurationElement element) - { - return ((AssemblyConfigurationItem)element).AssemblyName; - } - } - - public sealed class NamespaceConfigurationItem : ConfigurationElement - { - // repeat this pattern for each additional attribute you want in the tag. - // Only the assembly="foo.dll" portion is defined in this class, and is accessed - // via the AssemblyName property. - public const string NamespacePropertyName = "namespace"; - - [ConfigurationProperty(NamespacePropertyName, IsRequired = true, IsKey = true)] - public string NamespaceName - { - get { return this[NamespacePropertyName] as string; } - set { this[NamespacePropertyName] = value; } - } - } - - public class NamespaceConfigurationCollection : ConfigurationElementCollection, IEnumerable - { - public const string PluginsElementName = "namespace"; - - protected override string ElementName - { - get { return PluginsElementName; } - } - - // this is extraneous, but I find it very useful for enumerating over a configuration collection in a type-safe manner. - - #region IEnumerable Members - - public new IEnumerator GetEnumerator() - { - foreach (NamespaceConfigurationItem item in (this as IEnumerable)) - { - yield return item; - } - } - - #endregion - - protected override ConfigurationElement CreateNewElement() - { - return new NamespaceConfigurationItem(); - } - - protected override object GetElementKey(ConfigurationElement element) - { - return ((NamespaceConfigurationItem)element).NamespaceName; - } - } -} diff --git a/src/Nancy.ViewEngines.Razor/RazorViewEngine.cs b/src/Nancy.ViewEngines.Razor/RazorViewEngine.cs index 2e37e5b4ff..209b1cc7ba 100644 --- a/src/Nancy.ViewEngines.Razor/RazorViewEngine.cs +++ b/src/Nancy.ViewEngines.Razor/RazorViewEngine.cs @@ -1,31 +1,50 @@ namespace Nancy.ViewEngines.Razor { using System; - using System.CodeDom; - using System.CodeDom.Compiler; using System.Collections.Generic; + using System.Diagnostics; using System.IO; - using System.Linq; - using System.Reflection; - using System.Text.RegularExpressions; - using System.Web.Razor; - using Microsoft.CodeAnalysis; - using Microsoft.CodeAnalysis.CSharp; - using Microsoft.CodeAnalysis.Emit; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Hosting; + using Microsoft.AspNetCore.Http; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Abstractions; + using Microsoft.AspNetCore.Mvc.ModelBinding; + using Microsoft.AspNetCore.Mvc.Razor; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewEngines; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + using Microsoft.AspNetCore.Mvc.ViewFeatures.Internal; + using Microsoft.AspNetCore.Routing; + using Microsoft.Extensions.DependencyInjection; + using Microsoft.Extensions.Logging; + using Microsoft.Extensions.ObjectPool; using Nancy.Configuration; - using Nancy.Helpers; using Nancy.Responses; - using Nancy.ViewEngines.Razor.CSharp; + using System.Linq; + using System.Text; + using System.Text.Encodings.Web; + using Microsoft.AspNetCore.Mvc.Razor.Compilation; + using Microsoft.AspNetCore.Mvc.Razor.Internal; + using Microsoft.Extensions.FileProviders; + using Microsoft.Extensions.Primitives; /// /// View engine for rendering razor views. /// - public class RazorViewEngine : IViewEngine, IDisposable + public class RazorViewEngine : Nancy.ViewEngines.IViewEngine { + public static readonly string[] SupportedExtensions = { "cshtml" }; + private readonly IRazorConfiguration razorConfiguration; - private readonly IRazorViewRenderer viewRenderer; - private readonly TraceConfiguration traceConfiguration; - private readonly RazorAssemblyProvider razorAssemblyProvider; + + private readonly IAssemblyCatalog assemblyCatalog; + + private readonly IViewLocationProvider locationProvider; + + private readonly INancyEnvironment environment; + + private IServiceProvider razorServices; /// /// Gets the extensions file extensions that are supported by the view engine. @@ -34,366 +53,63 @@ public class RazorViewEngine : IViewEngine, IDisposable /// The extensions should not have a leading dot in the name. public IEnumerable Extensions { - get { yield return "cshtml"; } + get { return SupportedExtensions; } } /// /// Initializes a new instance of the class. /// - /// The that should be used by the engine. - /// An instance. - /// An instance. - public RazorViewEngine(IRazorConfiguration configuration, INancyEnvironment environment, IAssemblyCatalog assemblyCatalog) + public RazorViewEngine(IRazorConfiguration razorConfiguration, IAssemblyCatalog assemblyCatalog, IViewLocationProvider locationProvider, INancyEnvironment environment) { - this.razorAssemblyProvider = new RazorAssemblyProvider(configuration, assemblyCatalog); - this.viewRenderer = new CSharpRazorViewRenderer(this.razorAssemblyProvider); - this.razorConfiguration = configuration; - this.traceConfiguration = environment.GetValue(); - this.AddDefaultNameSpaces(this.viewRenderer.Host); + this.razorConfiguration = razorConfiguration; + this.assemblyCatalog = assemblyCatalog; + this.locationProvider = locationProvider; + this.environment = environment; } - /// - /// Initialise the view engine (if necessary) - /// - /// Startup context public void Initialize(ViewEngineStartupContext viewEngineStartupContext) { - } - - /// - /// Renders the view. - /// - /// A instance, containing information on how to get the view template. - /// The model that should be passed into the view - /// The render context. - /// A response. - public Response RenderView(ViewLocationResult viewLocationResult, dynamic model, IRenderContext renderContext) - { - return RenderView(viewLocationResult, model, renderContext, false); - } - - /// - /// Renders the view. - /// - /// A instance, containing information on how to get the view template. - /// The model that should be passed into the view - /// The render context. - /// Used by HtmlHelpers to declare a view as partial - /// A response. - public Response RenderView(ViewLocationResult viewLocationResult, dynamic model, IRenderContext renderContext, bool isPartial) - { - Assembly referencingAssembly = null; - - var response = new HtmlResponse(); - - response.Contents = stream => - { - var writer = - new StreamWriter(stream); - - var view = this.GetViewInstance(viewLocationResult, renderContext, model); - - view.ExecuteView(null, null); - - var body = view.Body; - var sectionContents = view.SectionContents; - - var layout = view.HasLayout ? view.Layout : GetViewStartLayout(model, renderContext, referencingAssembly, isPartial); - - var root = string.IsNullOrWhiteSpace(layout); - - while (!root) - { - var viewLocation = - renderContext.LocateView(layout, model); - - if (viewLocation == null) - { - throw new InvalidOperationException("Unable to locate layout: " + layout); - } - - view = this.GetViewInstance(viewLocation, renderContext, model); - - view.ExecuteView(body, sectionContents); - - body = view.Body; - sectionContents = view.SectionContents; - - layout = view.HasLayout ? view.Layout : GetViewStartLayout(model, renderContext, referencingAssembly, isPartial); - - root = !view.HasLayout; - } - - writer.Write(body); - writer.Flush(); - }; - - return response; - } - - private string GetViewStartLayout(dynamic model, IRenderContext renderContext, Assembly referencingAssembly, bool isPartial) - { - if (isPartial) - { - return string.Empty; - } - - var view = renderContext.LocateView("_ViewStart", model); - - if (view == null) - { - return string.Empty; - } - - if (!this.Extensions.Any(x => x.Equals(view.Extension, StringComparison.OrdinalIgnoreCase))) - { - return string.Empty; - } - - var viewInstance = GetViewInstance(view, renderContext, model); - - viewInstance.ExecuteView(null, null); - - return viewInstance.Layout ?? string.Empty; - } - - private void AddDefaultNameSpaces(RazorEngineHost engineHost) - { - engineHost.NamespaceImports.Add("System"); - engineHost.NamespaceImports.Add("System.IO"); - - if (this.razorConfiguration == null) - { - return; - } - - var namespaces = this.razorConfiguration.GetDefaultNamespaces(); - - if (namespaces == null) - { - return; - } - - foreach (var n in namespaces.Where(n => !string.IsNullOrWhiteSpace(n))) - { - engineHost.NamespaceImports.Add(n); - } - } - - private Func GetCompiledViewFactory(TextReader reader, Type passedModelType, ViewLocationResult viewLocationResult) - { - var engine = new RazorTemplateEngine(this.viewRenderer.Host); - - var razorResult = engine.GenerateCode(reader, null, null, "roo"); - - var viewFactory = this.GenerateRazorViewFactory(this.viewRenderer, razorResult, passedModelType, viewLocationResult); - - return viewFactory; - } - - private static Type GetModelTypeFromGeneratedCode(GeneratorResults generatorResults, Type passedModelType) - { - return (Type)generatorResults.GeneratedCode.Namespaces[0].Types[0].UserData["ModelType"] - ?? passedModelType - ?? typeof(object); - } - - private Func GenerateRazorViewFactory(IRazorViewRenderer renderer, GeneratorResults generatorResults, Type passedModelType, ViewLocationResult viewLocationResult) - { - var modelType = GetModelTypeFromGeneratedCode(generatorResults, passedModelType); - var sourceCode = string.Empty; + IServiceCollection serviceCollection = new ServiceCollection(); - if (this.razorConfiguration != null) + var mvcBuilder = serviceCollection + .AddMvcCore() + .AddRazorViewEngine(); + mvcBuilder.PartManager.FeatureProviders.Add(new MetadataReferenceFeatureProvider(this.razorConfiguration, + this.assemblyCatalog)); + serviceCollection.Configure(options => { - if (this.razorConfiguration.AutoIncludeModelNamespace) - { - AddModelNamespace(generatorResults, modelType); - } - } - - using (var writer = new StringWriter()) - { - renderer.Provider.GenerateCodeFromCompileUnit(generatorResults.GeneratedCode, writer, new CodeGeneratorOptions()); - sourceCode = writer.ToString(); - } - - var compilation = CSharpCompilation.Create( - assemblyName: string.Format("Temp_{0}.dll", Guid.NewGuid().ToString("N")), - syntaxTrees: new[] { CSharpSyntaxTree.ParseText(sourceCode) }, - references: this.GetMetadataReferences().Value, - options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); - - using (var ms = new MemoryStream()) - { - var result = compilation.Emit(ms); - - if (!result.Success) - { - return () => new NancyRazorErrorView(BuildErrorMessage(result, viewLocationResult, sourceCode), this.traceConfiguration); - } - - ms.Seek(0, SeekOrigin.Begin); - var viewAssembly = Assembly.Load(ms.ToArray()); - - return () => (INancyRazorView) Activator.CreateInstance(viewAssembly.GetType("RazorOutput.RazorView")); - } - } - - private static string BuildErrorMessage(EmitResult result, ViewLocationResult viewLocationResult, string sourceCode) - { - var failures = result.Diagnostics - .Where(diagnostic => diagnostic.IsWarningAsError || diagnostic.Severity == DiagnosticSeverity.Error) - .ToArray(); - - var fullTemplateName = viewLocationResult.Location + "/" + viewLocationResult.Name + "." + viewLocationResult.Extension; - var templateLines = GetViewBodyLines(viewLocationResult); - var compilationSource = GetCompilationSource(sourceCode); - var errorMessages = BuildErrorMessages(failures, templateLines, compilationSource); - - var lineNumber = 1; - - var errorDetails = string.Format( - "Template: {0}

Errors:
    {1}
Details:
{2}

Compilation Source:
{3}
", - fullTemplateName, - errorMessages, - templateLines.Aggregate((s1, s2) => s1 + "
" + s2), - compilationSource.Aggregate((s1, s2) => s1 + "
Line " + lineNumber++ + ":\t" + s2.Replace("<", ">").Replace(">", "<"))); - - return errorDetails; - } - - private Lazy> GetMetadataReferences() - { - return new Lazy>(() => - { - return this.razorAssemblyProvider.GetAssemblies() - .Where(x => !string.IsNullOrEmpty(x.Location)) - .Select(x => MetadataReference.CreateFromFile(x.Location)) - .ToList(); + options.ViewLocationExpanders.Add(new ViewLocationExpander()); }); - } - - private static string[] GetCompilationSource(string code) - { - return HttpUtility.HtmlEncode(code).Split(new[] { Environment.NewLine }, StringSplitOptions.None); - } - - private static int GetLineNumber(int startLineIndex, IReadOnlyList compilationSource) - { - - for (var lineIndex = startLineIndex; lineIndex >= 0; lineIndex--) - { - var match = Regex.Match(compilationSource[lineIndex], @"#line (?[\d]+)"); - if (match.Success) - { - return int.Parse(match.Groups["row"].Value); - } - } - - return -1; - } - - private static string BuildErrorMessages(IEnumerable errors, IList templateLines, IReadOnlyList compilationSource) - { - var messages = errors.Select(error => - { - var lineIndex = error.Location.GetLineSpan().StartLinePosition.Line - 1; - var lineNumber = GetLineNumber(lineIndex, compilationSource); - - if (lineNumber > 0) - { - templateLines[lineNumber - 1] = string.Format("{1}", lineNumber, templateLines[lineNumber - 1]); - - return string.Format( - "
  • [{0}] Line: {1} Column: {2} - {3} (show)
  • ", - error.Id, - lineNumber, - error.Location.GetLineSpan().StartLinePosition.Character, - error.GetMessage()); - } - - return null; + + serviceCollection + .AddSingleton() + .AddSingleton() + .AddSingleton() + .AddSingleton(this.razorConfiguration) + .AddSingleton() + .AddScoped() + .AddScoped(); - }).Where(x => x != null).ToArray(); - - return (messages.Any()) - ? string.Join(string.Empty, messages) - : string.Empty; + this.razorServices = serviceCollection.BuildServiceProvider(); } - private static string[] GetViewBodyLines(ViewLocationResult viewLocationResult) + public Response RenderView(ViewLocationResult viewLocation, dynamic model, IRenderContext renderContext) { - var templateLines = new List(); - using (var templateReader = viewLocationResult.Contents.Invoke()) + var scopeFactory = this.razorServices.GetRequiredService(); + using (var scope = scopeFactory.CreateScope()) { - var currentLine = templateReader.ReadLine(); - while (currentLine != null) - { - templateLines.Add(HttpUtility.HtmlEncode(currentLine)); - - currentLine = templateReader.ReadLine(); - } - } - return templateLines.ToArray(); - } - - private static void AddModelNamespace(GeneratorResults razorResult, Type modelType) - { - if (string.IsNullOrWhiteSpace(modelType.Namespace)) - { - return; - } - - if (razorResult.GeneratedCode.Namespaces[0].Imports.OfType().Any(x => x.Namespace == modelType.Namespace)) - { - return; - } - - razorResult.GeneratedCode.Namespaces[0].Imports.Add(new CodeNamespaceImport(modelType.Namespace)); - } + // Set the file provider in the hosting environment with the current model and render context before filling other services + var hostingEnvironment = scope.ServiceProvider.GetRequiredService(); + hostingEnvironment.WebRootFileProvider = new ViewLocationFileProvider(this.locationProvider, renderContext, model); - private INancyRazorView GetOrCompileView(ViewLocationResult viewLocationResult, IRenderContext renderContext, Type passedModelType) - { - var viewFactory = renderContext.ViewCache.GetOrAdd( - viewLocationResult, - x => + // Get the view renderer and render the view + var viewRenderer = scope.ServiceProvider.GetRequiredService(); + var response = new HtmlResponse { - using (var reader = x.Contents.Invoke()) - return this.GetCompiledViewFactory(reader, passedModelType, viewLocationResult); - }); - - var view = viewFactory.Invoke(); - - return view; - } - - private INancyRazorView GetViewInstance(ViewLocationResult viewLocationResult, IRenderContext renderContext, dynamic model) - { - var modelType = (model == null) ? typeof(object) : model.GetType(); - - var view = this.GetOrCompileView(viewLocationResult, renderContext, modelType); - - view.Initialize(this, renderContext, model); - - return view; - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - if (this.viewRenderer == null) - { - return; - } - - var disposable = this.viewRenderer as IDisposable; - - if (disposable != null) - { - disposable.Dispose(); + Contents = stream => viewRenderer.RenderView(viewLocation, model, renderContext, this.environment, stream) + }; + return response; } } } -} \ No newline at end of file +} diff --git a/src/Nancy.ViewEngines.Razor/RazorViewEngineApplicationStartupRegistrations.cs b/src/Nancy.ViewEngines.Razor/RazorViewEngineRegistrations.cs similarity index 92% rename from src/Nancy.ViewEngines.Razor/RazorViewEngineApplicationStartupRegistrations.cs rename to src/Nancy.ViewEngines.Razor/RazorViewEngineRegistrations.cs index 398a97cb80..413b6bd593 100644 --- a/src/Nancy.ViewEngines.Razor/RazorViewEngineApplicationStartupRegistrations.cs +++ b/src/Nancy.ViewEngines.Razor/RazorViewEngineRegistrations.cs @@ -1,7 +1,7 @@ +using Nancy.Bootstrapper; + namespace Nancy.ViewEngines.Razor { - using Nancy.Bootstrapper; - /// /// Default dependency registrations for the class. /// @@ -16,4 +16,4 @@ public RazorViewEngineRegistrations(ITypeCatalog typeCatalog) : base(typeCatalog this.RegisterWithDefault(typeof(DefaultRazorConfiguration)); } } -} +} \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/RazorViewRenderer.cs b/src/Nancy.ViewEngines.Razor/RazorViewRenderer.cs new file mode 100644 index 0000000000..fc47688416 --- /dev/null +++ b/src/Nancy.ViewEngines.Razor/RazorViewRenderer.cs @@ -0,0 +1,169 @@ +namespace Nancy.ViewEngines.Razor +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Text.Encodings.Web; + using System.Text.RegularExpressions; + using Microsoft.AspNetCore.Diagnostics; + using Microsoft.AspNetCore.Hosting; + using Microsoft.AspNetCore.Http; + using Microsoft.AspNetCore.Mvc; + using Microsoft.AspNetCore.Mvc.Abstractions; + using Microsoft.AspNetCore.Mvc.ModelBinding; + using Microsoft.AspNetCore.Mvc.Razor; + using Microsoft.AspNetCore.Mvc.Razor.Compilation; + using Microsoft.AspNetCore.Mvc.Razor.Internal; + using Microsoft.AspNetCore.Mvc.Rendering; + using Microsoft.AspNetCore.Mvc.ViewEngines; + using Microsoft.AspNetCore.Mvc.ViewFeatures; + using Microsoft.AspNetCore.Routing; + using Microsoft.CodeAnalysis; + using Microsoft.CodeAnalysis.Emit; + using Microsoft.Extensions.Primitives; + using Nancy.Configuration; + using Nancy.Helpers; + using Nancy.ViewEngines; + using Nancy.ViewEngines.Razor; + + public class RazorViewRenderer + { + private readonly IServiceProvider serviceProvider; + + private readonly IRazorViewEngine viewEngine; + + private readonly IRazorPageActivator pageActivator; + + private readonly HtmlEncoder htmlEncoder; + + private readonly IRazorPageFactoryProvider pageFactoryProvider; + + private readonly IRazorCompilationService razorCompilationService; + + private readonly ITempDataProvider tempDataProvider; + + public RazorViewRenderer(IServiceProvider serviceProvider, IRazorViewEngine viewEngine, + IRazorPageActivator pageActivator, + HtmlEncoder htmlEncoder, IRazorPageFactoryProvider pageFactoryProvider, + IRazorCompilationService razorCompilationService, + ITempDataProvider tempDataProvider) + { + this.serviceProvider = serviceProvider; + this.viewEngine = viewEngine; + this.pageActivator = pageActivator; + this.htmlEncoder = htmlEncoder; + this.pageFactoryProvider = pageFactoryProvider; + this.razorCompilationService = razorCompilationService; + this.tempDataProvider = tempDataProvider; + } + + public void RenderView(ViewLocationResult viewLocation, dynamic model, IRenderContext renderContext, INancyEnvironment environment, Stream stream) + { + // Get and render the view + var view = this.GetViewFromViewLocation(viewLocation, environment); + var output = new StreamWriter(stream); + var viewContext = GetViewContext(view, model, output, renderContext); + try + { + view.RenderAsync(viewContext).GetAwaiter().GetResult(); + } + catch (InvalidOperationException ex) + { + // Throw a specialized exception for partial view location problems + if (ex.Message.StartsWith("The partial view")) + { + throw new ViewNotFoundException(ex.Message); + } + throw; + } + output.Flush(); + } + + private ViewContext GetViewContext(IView view, dynamic model, TextWriter output, IRenderContext renderContext) + { + var httpContext = new DefaultHttpContext + { + RequestServices = this.serviceProvider + }; + var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); + var viewData = new ViewDataDictionary(new EmptyModelMetadataProvider(), actionContext.ModelState) + { + Model = model + }; + var tempData = new TempDataDictionary(actionContext.HttpContext, this.tempDataProvider); + var viewContext = new NancyViewContext(renderContext, + actionContext, view, viewData, tempData, output, new HtmlHelperOptions()); + return viewContext; + } + + /// + /// Gets the view for a located view location. + /// + private IView GetViewFromViewLocation(ViewLocationResult viewLocation, INancyEnvironment environment) + { + var viewStartLocations = ViewHierarchyUtility.GetViewStartLocations(viewLocation.Location); + var viewStartPages = viewStartLocations + .Select(this.pageFactoryProvider.CreateFactory) + .Where(x => x.Success) + .Select(x => x.RazorPageFactory()) + .Reverse() + .ToList(); + var page = this.GetPageFromViewLocation(viewLocation, environment); + var activator = page is NancyRazorErrorView ? new EmptyPageActivator() : this.pageActivator; + return new RazorView(this.viewEngine, activator, viewStartPages, page, this.htmlEncoder); + } + + /// + /// Gets the Razor page for a view location. This is roughly modeled on + /// DefaultRazorPageFactory and CompilerCache. + /// + private IRazorPage GetPageFromViewLocation(ViewLocationResult viewLocation, INancyEnvironment environment) + { + // Get the file info by combining the view location with info found at the document's original location (if any) + string relativePath = string.Format("/{0}/{1}", viewLocation.Location, viewLocation.Name); + var fileInfo = new ViewLocationFileInfo(viewLocation); + var relativeFileInfo = new RelativeFileInfo(fileInfo, relativePath); + + // Create the compilation + var compilationResult = this.razorCompilationService.Compile(relativeFileInfo); + + // Check for errors + if (compilationResult.CompilationFailures != null) + { + var traceConfiguration = environment.GetValue(); + return new NancyRazorErrorView(BuildErrorMessage(compilationResult.CompilationFailures.First(), viewLocation), traceConfiguration); + } + compilationResult.EnsureSuccessful(); + + // Create and return the page + // We're not actually using the cache, but the CompilerCacheResult ctor contains the logic to create the page factory + var compilerCacheResult = new CompilerCacheResult(relativePath, compilationResult, new IChangeToken[] { }); + return compilerCacheResult.PageFactory(); + } + + private static string BuildErrorMessage(CompilationFailure failure, ViewLocationResult viewLocationResult) + { + var fullTemplateName = viewLocationResult.Location + "/" + viewLocationResult.Name + "." + viewLocationResult.Extension; + var errorMessages = failure.Messages.Select(error => string.Format( + "
  • Line: {0} Column: {1} - {2}
  • ", + error.StartLine, + error.StartColumn, + error.Message)).ToArray(); + + var errorDetails = string.Format( + "Template: {0}

    Errors:
      {1}
    ", + fullTemplateName, + string.Join(Environment.NewLine, errorMessages)); + + return errorDetails; + } + + public class EmptyPageActivator : IRazorPageActivator + { + public void Activate(IRazorPage page, ViewContext context) + { + } + } + } +} \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/SilentDiagnosticSource.cs b/src/Nancy.ViewEngines.Razor/SilentDiagnosticSource.cs new file mode 100644 index 0000000000..d3ac591433 --- /dev/null +++ b/src/Nancy.ViewEngines.Razor/SilentDiagnosticSource.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Nancy.ViewEngines.Razor +{ + internal class SilentDiagnosticSource : System.Diagnostics.DiagnosticSource + { + public override void Write(string name, object value) + { + // Do nothing + } + + public override bool IsEnabled(string name) => true; + } +} diff --git a/src/Nancy.ViewEngines.Razor/SilentLogger.cs b/src/Nancy.ViewEngines.Razor/SilentLogger.cs new file mode 100644 index 0000000000..02744f05dd --- /dev/null +++ b/src/Nancy.ViewEngines.Razor/SilentLogger.cs @@ -0,0 +1,23 @@ +using System; +using Microsoft.Extensions.Logging; + +namespace Nancy.ViewEngines.Razor +{ + public class SilentLogger : ILogger + { + public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) + { + // Do nothing + } + + public bool IsEnabled(LogLevel logLevel) + { + return true; + } + + public IDisposable BeginScope(TState state) + { + return new EmptyDisposable(); + } + } +} \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/SilentLoggerFactory.cs b/src/Nancy.ViewEngines.Razor/SilentLoggerFactory.cs new file mode 100644 index 0000000000..7a18864b25 --- /dev/null +++ b/src/Nancy.ViewEngines.Razor/SilentLoggerFactory.cs @@ -0,0 +1,20 @@ +using Microsoft.Extensions.Logging; + +namespace Nancy.ViewEngines.Razor +{ + public class SilentLoggerFactory : ILoggerFactory + { + public void Dispose() + { + } + + public ILogger CreateLogger(string categoryName) + { + return new SilentLogger(); + } + + public void AddProvider(ILoggerProvider provider) + { + } + } +} \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/TextReaderStream.cs b/src/Nancy.ViewEngines.Razor/TextReaderStream.cs new file mode 100644 index 0000000000..ee9340ce00 --- /dev/null +++ b/src/Nancy.ViewEngines.Razor/TextReaderStream.cs @@ -0,0 +1,169 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Nancy.ViewEngines.Razor +{ + /// + /// A read-only stream backed by a TextReader. + /// From https://github.com/dotlattice/LatticeUtils + /// Licensed as public domain: https://github.com/dotlattice/LatticeUtils/blob/master/LICENSE.md + /// + public class TextReaderStream : Stream + { + private readonly TextReader textReader; + private readonly Encoding encoding; + private readonly List internalBuffer = new List(); + + /// + /// Constructs a stream that reads from the specified TextReader encoded to bytes using the UTF8 encoding. + /// + /// the backing TextReader + /// the textReader is null + public TextReaderStream(TextReader textReader) + : this(textReader, encoding: null) { } + + /// + /// Constructs a stream that reads from the specified TextReader using the specified encoding. + /// + /// the backing TextReader + /// the encoding to use; if null then the encoding will default to UTF8 + /// the textReader is null + public TextReaderStream(TextReader textReader, Encoding encoding) + { + if (textReader == null) throw new ArgumentNullException("textReader"); + if (encoding == null) encoding = Encoding.UTF8; + + this.textReader = textReader; + this.encoding = encoding; + } + + /// + /// The encoding used to encode the characters from the backing TextReader as bytes. + /// + public Encoding Encoding { get { return encoding; } } + + /// + /// Always true. + /// + public override bool CanRead { get { return true; } } + + /// + public override int Read(byte[] buffer, int offset, int count) + { + FillInternalBufferfNecessary(count); + if (!internalBuffer.Any()) + { + return 0; + } + + int readCount = Math.Min(internalBuffer.Count, count); + internalBuffer.CopyTo(0, buffer, offset, readCount); + internalBuffer.RemoveRange(0, readCount); + return readCount; + } + + /// + public override int ReadByte() + { + FillInternalBufferfNecessary(1); + if (!internalBuffer.Any()) + { + return -1; + } + + int result = (int)internalBuffer[0]; + internalBuffer.RemoveAt(0); + return result; + } + + private void FillInternalBufferfNecessary(int count) + { + if (internalBuffer.Count >= count) + { + // Not necessary + return; + } + + int requestedByteCount = count - internalBuffer.Count; + + // We're assuming that each character is at least one byte in the encoding. + // It's fine if a character is more than one byte; that just means we'll get more + // data than we need in the buffer for this request (and we'll use it on the next one). + int requestedCharCount = requestedByteCount; + + var charBuffer = new char[requestedCharCount]; + int charReadCount = textReader.Read(charBuffer, index: 0, count: charBuffer.Length); + if (charReadCount > 0) + { + var charBytes = encoding.GetBytes(charBuffer, index: 0, count: charReadCount); + internalBuffer.AddRange(charBytes); + } + } + + /// + /// Does nothing. + /// + public override void Flush() { } + + /// + protected override void Dispose(bool disposing) + { + if (disposing) + { + textReader.Dispose(); + internalBuffer.Clear(); + } + } + + #region Not Supported + + /// + /// Always false. + /// + public override bool CanSeek { get { return false; } } + + /// + /// Not supported. + /// + /// always + public override long Seek(long offset, SeekOrigin origin) { throw new NotSupportedException(); } + + /// + /// Not supported. + /// + public override long Position + { + get { throw new NotSupportedException(); } + set { throw new NotSupportedException(); } + } + + /// + /// Not supported. + /// + /// always + public override long Length { get { throw new NotSupportedException(); } } + + /// + /// Not supported. + /// + /// always + public override void SetLength(long value) { throw new NotSupportedException(); } + + /// + /// Always false. + /// + public override bool CanWrite { get { return false; } } + + /// + /// Not supported. + /// + /// always + public override void Write(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } + + #endregion + } +} diff --git a/src/Nancy.ViewEngines.Razor/UrlHelpers.cs b/src/Nancy.ViewEngines.Razor/UrlHelpers.cs deleted file mode 100644 index 1096d2972c..0000000000 --- a/src/Nancy.ViewEngines.Razor/UrlHelpers.cs +++ /dev/null @@ -1,41 +0,0 @@ -namespace Nancy.ViewEngines.Razor -{ - /// - /// Helpers for url related functions. - /// - /// The type of the model. - public class UrlHelpers - { - /// - /// Initializes a new instance of the class. - /// - /// The razor view engine. - /// The render context. - public UrlHelpers(RazorViewEngine razorViewEngine, IRenderContext renderContext) - { - this.RazorViewEngine = razorViewEngine; - this.RenderContext = renderContext; - } - - /// - /// The engine that is currently rendering the view. - /// - /// A instance. - public RazorViewEngine RazorViewEngine { get; set; } - - /// - /// The context of the current render operation. - /// - /// An instance. - public IRenderContext RenderContext { get; set; } - - /// - /// Retrieves the absolute url of the specified path. - /// - /// The path. - public string Content(string path) - { - return this.RenderContext.ParsePath(path); - } - } -} \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/ViewLocationExpander.cs b/src/Nancy.ViewEngines.Razor/ViewLocationExpander.cs new file mode 100644 index 0000000000..8386419ee2 --- /dev/null +++ b/src/Nancy.ViewEngines.Razor/ViewLocationExpander.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc.Razor; + +namespace Nancy.ViewEngines.Razor +{ + public class ViewLocationExpander : IViewLocationExpander + { + public void PopulateValues(ViewLocationExpanderContext context) + { + } + + public IEnumerable ExpandViewLocations(ViewLocationExpanderContext context, IEnumerable viewLocations) + { + // Nancy is handling view path expansion, so always just look at the view name + return new[] { "{0}" }; + } + } +} \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/ViewLocationFileInfo.cs b/src/Nancy.ViewEngines.Razor/ViewLocationFileInfo.cs new file mode 100644 index 0000000000..f292796019 --- /dev/null +++ b/src/Nancy.ViewEngines.Razor/ViewLocationFileInfo.cs @@ -0,0 +1,77 @@ +namespace Nancy.ViewEngines.Razor +{ + using System; + using System.IO; + using Microsoft.Extensions.FileProviders; + + public class ViewLocationFileInfo : IFileInfo + { + private readonly ViewLocationResult viewLocation; + + public ViewLocationFileInfo(ViewLocationResult viewLocation) + { + this.viewLocation = viewLocation; + } + + public bool Exists + { + get { return this.viewLocation != null; } + } + + public long Length + { + get + { + if (this.viewLocation != null + && this.viewLocation.Contents != null) + { + var reader = this.viewLocation.Contents(); + if (reader != null) + { + return reader.ReadToEnd().Length; + } + } + return 0; + } + } + + public string PhysicalPath + { + get { return this.viewLocation != null ? (this.viewLocation.Location ?? null) : null; } + } + + public string Name + { + get { return this.viewLocation != null ? (this.viewLocation.Name ?? null) : null; } + } + + public DateTimeOffset LastModified + { + get { return DateTimeOffset.Now; } + } + + public bool IsDirectory + { + get { return false; } + } + + public Stream CreateReadStream() + { + TextReader reader = null; + if (this.viewLocation != null) + { + reader = this.viewLocation.Contents != null ? this.viewLocation.Contents() : null; + } + if (reader == null) + { + reader = new StringReader(string.Empty); + } + var streamReader = reader as StreamReader; + if (streamReader != null && streamReader.BaseStream != null) + { + return streamReader.BaseStream; + } + return new TextReaderStream(reader); + } + } +} \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/ViewLocationFileProvider.cs b/src/Nancy.ViewEngines.Razor/ViewLocationFileProvider.cs new file mode 100644 index 0000000000..aa884364c0 --- /dev/null +++ b/src/Nancy.ViewEngines.Razor/ViewLocationFileProvider.cs @@ -0,0 +1,38 @@ +using System; +using System.IO; +using System.Text; +using Microsoft.Extensions.FileProviders; +using Microsoft.Extensions.Primitives; + +namespace Nancy.ViewEngines.Razor +{ + public class ViewLocationFileProvider : IFileProvider + { + private readonly IViewLocationProvider locationProvider; + private readonly IRenderContext renderContext; + private readonly dynamic model; + + public ViewLocationFileProvider(IViewLocationProvider locationProvider, IRenderContext renderContext, dynamic model) + { + this.locationProvider = locationProvider; + this.renderContext = renderContext; + this.model = model; + } + + public IFileInfo GetFileInfo(string subpath) + { + return new ViewLocationFileInfo(this.renderContext.LocateView(subpath.TrimStart(new char[] { '/', '\\' }), this.model)); + } + + public IDirectoryContents GetDirectoryContents(string subpath) + { + return new LocationProviderDirectoryContents(this.locationProvider, subpath); + } + + public IChangeToken Watch(string filter) + { + return new EmptyChangeToken(); + } + + } +} \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/app.config.transform b/src/Nancy.ViewEngines.Razor/app.config.transform deleted file mode 100644 index 77b1409e05..0000000000 --- a/src/Nancy.ViewEngines.Razor/app.config.transform +++ /dev/null @@ -1,17 +0,0 @@ - - - -
    - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Nancy.ViewEngines.Razor/project.json b/src/Nancy.ViewEngines.Razor/project.json index be18f5e4ab..6a72bc2c2c 100644 --- a/src/Nancy.ViewEngines.Razor/project.json +++ b/src/Nancy.ViewEngines.Razor/project.json @@ -1,39 +1,40 @@ { - "version": "2.0.0-barneyrubble", - "description": "Enables using the Razor view engine with Nancy.", - "authors": [ "Andreas Håkansson, Steven Robbins and contributors" ], + "version": "2.0.0-barneyrubble", + "description": "Enables using Razor with Nancy.", + "authors": [ "Andreas Håkansson, Steven Robbins and contributors" ], - "packOptions": { - "tags": [ "Nancy", "View Engine", "Razor" ], - "projectUrl": "http://nancyfx.org", - "licenseUrl": "https://github.com/NancyFx/Nancy/blob/master/license.txt", - "iconUrl": "http://nancyfx.org/nancy-nuget.png" - }, + "packOptions": { + "tags": [ "Nancy", "View Engine", "Razor" ], + "projectUrl": "http://nancyfx.org", + "licenseUrl": "https://github.com/NancyFx/Nancy/blob/master/license.txt", + "iconUrl": "http://nancyfx.org/nancy-nuget.png" + }, - "dependencies": { - "Nancy": { "target": "project" }, - "Microsoft.AspNet.Razor": "2.0.30506.0", - "Microsoft.CodeAnalysis.CSharp": "1.1.0-rc1-20151109-01" - }, + "buildOptions": { + "embed": "Resources/**/*.*", + "xmlDoc": true + }, - "buildOptions": { - "embed": "Resources/**/*.*", - "xmlDoc": true - }, + "dependencies": { + "Nancy": { "target": "project" }, + "Microsoft.AspNetCore.Mvc.Razor": "1.0.0", + "Microsoft.AspNetCore.Mvc.Razor.Host": "1.0.1", + "Microsoft.Extensions.Configuration": "1.0.0", + "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.0.0", + "Microsoft.Extensions.Configuration.Json": "1.0.0", + "Microsoft.Extensions.DependencyInjection": "1.0.0", + "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0", + "NETStandard.Library": "1.6.0", + "System.Reflection": "4.1.0" + }, - "frameworks": { - "net452": { - "dependencies": { - "Microsoft.CodeDom.Providers.DotNetCompilerPlatform": "1.0.1" - }, - "frameworkAssemblies": { - "System.Configuration": { "type": "build" }, - "System.IO": { "type": "build" }, - "System.Reflection": { "type": "build" }, - "System.Runtime": { "type": "build" }, - "System.Text.Encoding": { "type": "build" }, - "System.Threading.Tasks": { "type": "build" } - } - } + "frameworks": { + "net452": { }, + "netstandard1.6": { + "buildOptions": { + "define": [ "CORE" ] + }, + "imports": "dnxcore50" } + } } diff --git a/src/Nancy.ViewEngines.Razor/targets/Nancy.ViewEngines.Razor.targets b/src/Nancy.ViewEngines.Razor/targets/Nancy.ViewEngines.Razor.targets deleted file mode 100644 index 608227f3b6..0000000000 --- a/src/Nancy.ViewEngines.Razor/targets/Nancy.ViewEngines.Razor.targets +++ /dev/null @@ -1,14 +0,0 @@ - - - CopyRazorFiles;$(BuildDependsOn) - - - - $(ProjectDir)\bin - - - - - - - diff --git a/src/Nancy.ViewEngines.Razor/web.config.transform b/src/Nancy.ViewEngines.Razor/web.config.transform deleted file mode 100644 index f229afb4b6..0000000000 --- a/src/Nancy.ViewEngines.Razor/web.config.transform +++ /dev/null @@ -1,25 +0,0 @@ - - - -
    - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/Nancy/DynamicDictionaryValue.cs b/src/Nancy/DynamicDictionaryValue.cs index d24f187c8f..d10b8ccb1c 100644 --- a/src/Nancy/DynamicDictionaryValue.cs +++ b/src/Nancy/DynamicDictionaryValue.cs @@ -355,7 +355,7 @@ public override bool TryConvert(ConvertBinder binder, out object result) /// public override string ToString() { - return this.value == null ? base.ToString() : Convert.ToString(this.value); + return this.value == null ? string.Empty : Convert.ToString(this.value); } diff --git a/test/Nancy.Testing.Tests.MSBuild/Nancy.Testing.Tests.csproj b/test/Nancy.Testing.Tests.MSBuild/Nancy.Testing.Tests.csproj index 985240e90f..ef6e643144 100644 --- a/test/Nancy.Testing.Tests.MSBuild/Nancy.Testing.Tests.csproj +++ b/test/Nancy.Testing.Tests.MSBuild/Nancy.Testing.Tests.csproj @@ -86,8 +86,8 @@ false - - ..\..\packages\AngleSharp.0.9.5\lib\net45\AngleSharp.dll + + ..\..\packages\AngleSharp.0.9.8.1\lib\net45\AngleSharp.dll True diff --git a/test/Nancy.Tests.Functional.MSBuild/Nancy.Tests.Functional.csproj b/test/Nancy.Tests.Functional.MSBuild/Nancy.Tests.Functional.csproj index 849151ce6d..570bd03dd4 100644 --- a/test/Nancy.Tests.Functional.MSBuild/Nancy.Tests.Functional.csproj +++ b/test/Nancy.Tests.Functional.MSBuild/Nancy.Tests.Functional.csproj @@ -1,5 +1,5 @@  - + Debug @@ -10,7 +10,7 @@ Nancy.Tests.Functional Nancy.Tests.Functional 512 - v4.5 + v4.5.1 publish\ true Disk @@ -28,6 +28,7 @@ true + true @@ -67,8 +68,232 @@ false + + ..\..\packages\Microsoft.AspNetCore.Antiforgery.1.0.1\lib\net451\Microsoft.AspNetCore.Antiforgery.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Authorization.1.0.0\lib\net451\Microsoft.AspNetCore.Authorization.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Cryptography.Internal.1.0.0\lib\net451\Microsoft.AspNetCore.Cryptography.Internal.dll + True + + + ..\..\packages\Microsoft.AspNetCore.DataProtection.1.0.0\lib\net451\Microsoft.AspNetCore.DataProtection.dll + True + + + ..\..\packages\Microsoft.AspNetCore.DataProtection.Abstractions.1.0.0\lib\net451\Microsoft.AspNetCore.DataProtection.Abstractions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Diagnostics.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.AspNetCore.Diagnostics.Abstractions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Hosting.Abstractions.1.0.0\lib\net451\Microsoft.AspNetCore.Hosting.Abstractions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Hosting.Server.Abstractions.1.0.0\lib\net451\Microsoft.AspNetCore.Hosting.Server.Abstractions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Html.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.AspNetCore.Html.Abstractions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Http.1.0.0\lib\net451\Microsoft.AspNetCore.Http.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Http.Abstractions.1.0.0\lib\net451\Microsoft.AspNetCore.Http.Abstractions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Http.Extensions.1.0.0\lib\net451\Microsoft.AspNetCore.Http.Extensions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Http.Features.1.0.0\lib\net451\Microsoft.AspNetCore.Http.Features.dll + True + + + ..\..\packages\Microsoft.AspNetCore.JsonPatch.1.0.0\lib\netstandard1.1\Microsoft.AspNetCore.JsonPatch.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Mvc.Abstractions.1.0.1\lib\net451\Microsoft.AspNetCore.Mvc.Abstractions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Mvc.Core.1.0.1\lib\net451\Microsoft.AspNetCore.Mvc.Core.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Mvc.DataAnnotations.1.0.1\lib\net451\Microsoft.AspNetCore.Mvc.DataAnnotations.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Mvc.Formatters.Json.1.0.1\lib\net451\Microsoft.AspNetCore.Mvc.Formatters.Json.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Mvc.Razor.1.0.1\lib\net451\Microsoft.AspNetCore.Mvc.Razor.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Mvc.Razor.Host.1.0.1\lib\net451\Microsoft.AspNetCore.Mvc.Razor.Host.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Mvc.ViewFeatures.1.0.1\lib\net451\Microsoft.AspNetCore.Mvc.ViewFeatures.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Razor.1.0.0\lib\net451\Microsoft.AspNetCore.Razor.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Razor.Runtime.1.0.0\lib\net451\Microsoft.AspNetCore.Razor.Runtime.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Routing.1.0.0\lib\net451\Microsoft.AspNetCore.Routing.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Routing.Abstractions.1.0.0\lib\net451\Microsoft.AspNetCore.Routing.Abstractions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.WebUtilities.1.0.0\lib\net451\Microsoft.AspNetCore.WebUtilities.dll + True + + + ..\..\packages\Microsoft.CodeAnalysis.Common.1.3.0\lib\net45\Microsoft.CodeAnalysis.dll + True + + + ..\..\packages\Microsoft.CodeAnalysis.CSharp.1.3.0\lib\net45\Microsoft.CodeAnalysis.CSharp.dll + True + + + ..\..\packages\Microsoft.DotNet.InternalAbstractions.1.0.0\lib\net451\Microsoft.DotNet.InternalAbstractions.dll + True + + + ..\..\packages\Microsoft.Extensions.Caching.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.Extensions.Caching.Abstractions.dll + True + + + ..\..\packages\Microsoft.Extensions.Caching.Memory.1.0.0\lib\net451\Microsoft.Extensions.Caching.Memory.dll + True + + + ..\..\packages\Microsoft.Extensions.Configuration.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.Extensions.Configuration.Abstractions.dll + True + + + ..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + True + + + ..\..\packages\Microsoft.Extensions.DependencyModel.1.0.0\lib\net451\Microsoft.Extensions.DependencyModel.dll + True + + + ..\..\packages\Microsoft.Extensions.FileProviders.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.Extensions.FileProviders.Abstractions.dll + True + + + ..\..\packages\Microsoft.Extensions.FileProviders.Composite.1.0.0\lib\netstandard1.0\Microsoft.Extensions.FileProviders.Composite.dll + True + + + ..\..\packages\Microsoft.Extensions.FileProviders.Physical.1.0.0\lib\net451\Microsoft.Extensions.FileProviders.Physical.dll + True + + + ..\..\packages\Microsoft.Extensions.FileSystemGlobbing.1.0.0\lib\net451\Microsoft.Extensions.FileSystemGlobbing.dll + True + + + ..\..\packages\Microsoft.Extensions.Localization.1.0.0\lib\net451\Microsoft.Extensions.Localization.dll + True + + + ..\..\packages\Microsoft.Extensions.Localization.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.Extensions.Localization.Abstractions.dll + True + + + ..\..\packages\Microsoft.Extensions.Logging.Abstractions.1.0.0\lib\netstandard1.1\Microsoft.Extensions.Logging.Abstractions.dll + True + + + ..\..\packages\Microsoft.Extensions.ObjectPool.1.0.0\lib\net451\Microsoft.Extensions.ObjectPool.dll + True + + + ..\..\packages\Microsoft.Extensions.Options.1.0.0\lib\netstandard1.0\Microsoft.Extensions.Options.dll + True + + + ..\..\packages\Microsoft.Extensions.PlatformAbstractions.1.0.0\lib\net451\Microsoft.Extensions.PlatformAbstractions.dll + True + + + ..\..\packages\Microsoft.Extensions.Primitives.1.0.0\lib\netstandard1.0\Microsoft.Extensions.Primitives.dll + True + + + ..\..\packages\Microsoft.Extensions.WebEncoders.1.0.0\lib\netstandard1.0\Microsoft.Extensions.WebEncoders.dll + True + + + ..\..\packages\Microsoft.Net.Http.Headers.1.0.0\lib\netstandard1.1\Microsoft.Net.Http.Headers.dll + True + + + ..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll + True + + + ..\..\packages\System.Buffers.4.0.0\lib\netstandard1.1\System.Buffers.dll + True + + + ..\..\packages\System.Collections.Immutable.1.1.37\lib\dotnet\System.Collections.Immutable.dll + True + + + + + ..\..\packages\System.ComponentModel.Primitives.4.1.0\lib\net45\System.ComponentModel.Primitives.dll + True + + + ..\..\packages\System.ComponentModel.TypeConverter.4.1.0\lib\net45\System.ComponentModel.TypeConverter.dll + True + + + ..\..\packages\System.Diagnostics.DiagnosticSource.4.0.0\lib\portable-net45+win8+wpa81\System.Diagnostics.DiagnosticSource.dll + True + + + ..\..\packages\System.Reflection.Metadata.1.2.0\lib\portable-net45+win8\System.Reflection.Metadata.dll + True + + + + + ..\..\packages\System.Text.Encodings.Web.4.0.0\lib\netstandard1.0\System.Text.Encodings.Web.dll + True + @@ -226,6 +451,10 @@ + + + + diff --git a/test/Nancy.Tests.Functional.MSBuild/packages.config b/test/Nancy.Tests.Functional.MSBuild/packages.config index 15426f7161..5866147480 100644 --- a/test/Nancy.Tests.Functional.MSBuild/packages.config +++ b/test/Nancy.Tests.Functional.MSBuild/packages.config @@ -1,5 +1,82 @@  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/Nancy.Tests.Functional/Tests/ViewBagTests.cs b/test/Nancy.Tests.Functional/Tests/ViewBagTests.cs index c2b440b944..5c4cf45d39 100644 --- a/test/Nancy.Tests.Functional/Tests/ViewBagTests.cs +++ b/test/Nancy.Tests.Functional/Tests/ViewBagTests.cs @@ -23,22 +23,6 @@ public ViewBagTests() [Fact] public async Task Should_render_content_from_viewbag() - { - // Given - // When - var response = await browser.Get( - @"/razor-viewbag", - with => - { - with.HttpRequest(); - }); - - // Then - Assert.True(response.Body.AsString().Contains(@"Hello Bob")); - } - - [Fact] - public async Task Should_render_content_from_viewbags() { // Given // When diff --git a/test/Nancy.Tests.Functional/Views/RazorPage.cshtml b/test/Nancy.Tests.Functional/Views/RazorPage.cshtml index 3b3bc89364..ee59b98f94 100644 --- a/test/Nancy.Tests.Functional/Views/RazorPage.cshtml +++ b/test/Nancy.Tests.Functional/Views/RazorPage.cshtml @@ -1,4 +1,4 @@ -@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase +@inherits Nancy.ViewEngines.Razor.NancyRazorPage Hello @ViewBag.Name diff --git a/test/Nancy.Tests.Functional/Views/RazorPageWithUnknownPartial.cshtml b/test/Nancy.Tests.Functional/Views/RazorPageWithUnknownPartial.cshtml index ddfa3e83c0..ea3b62bccf 100644 --- a/test/Nancy.Tests.Functional/Views/RazorPageWithUnknownPartial.cshtml +++ b/test/Nancy.Tests.Functional/Views/RazorPageWithUnknownPartial.cshtml @@ -1,4 +1,4 @@ -@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase +@inherits Nancy.ViewEngines.Razor.NancyRazorPage Hello @ViewBag.Name diff --git a/test/Nancy.Tests.Functional/Views/_LayoutPage.cshtml b/test/Nancy.Tests.Functional/Views/_LayoutPage.cshtml index 0d4b809097..c26610a650 100644 --- a/test/Nancy.Tests.Functional/Views/_LayoutPage.cshtml +++ b/test/Nancy.Tests.Functional/Views/_LayoutPage.cshtml @@ -1,4 +1,4 @@ -@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase +@inherits Nancy.ViewEngines.Razor.NancyRazorPage diff --git a/test/Nancy.ViewEngines.Razor.Tests.MSBuild/Nancy.ViewEngines.Razor.Tests.csproj b/test/Nancy.ViewEngines.Razor.Tests.MSBuild/Nancy.ViewEngines.Razor.Tests.csproj index da3035f1e5..213d87eec2 100644 --- a/test/Nancy.ViewEngines.Razor.Tests.MSBuild/Nancy.ViewEngines.Razor.Tests.csproj +++ b/test/Nancy.ViewEngines.Razor.Tests.MSBuild/Nancy.ViewEngines.Razor.Tests.csproj @@ -1,5 +1,5 @@  - + Debug @@ -27,9 +27,10 @@ false false true - v4.5 + v4.5.1 + True @@ -92,8 +93,232 @@ ..\..\packages\FakeItEasy.2.0.0\lib\net40\FakeItEasy.dll True + + ..\..\packages\Microsoft.AspNetCore.Antiforgery.1.0.1\lib\net451\Microsoft.AspNetCore.Antiforgery.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Authorization.1.0.0\lib\net451\Microsoft.AspNetCore.Authorization.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Cryptography.Internal.1.0.0\lib\net451\Microsoft.AspNetCore.Cryptography.Internal.dll + True + + + ..\..\packages\Microsoft.AspNetCore.DataProtection.1.0.0\lib\net451\Microsoft.AspNetCore.DataProtection.dll + True + + + ..\..\packages\Microsoft.AspNetCore.DataProtection.Abstractions.1.0.0\lib\net451\Microsoft.AspNetCore.DataProtection.Abstractions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Diagnostics.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.AspNetCore.Diagnostics.Abstractions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Hosting.Abstractions.1.0.0\lib\net451\Microsoft.AspNetCore.Hosting.Abstractions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Hosting.Server.Abstractions.1.0.0\lib\net451\Microsoft.AspNetCore.Hosting.Server.Abstractions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Html.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.AspNetCore.Html.Abstractions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Http.1.0.0\lib\net451\Microsoft.AspNetCore.Http.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Http.Abstractions.1.0.0\lib\net451\Microsoft.AspNetCore.Http.Abstractions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Http.Extensions.1.0.0\lib\net451\Microsoft.AspNetCore.Http.Extensions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Http.Features.1.0.0\lib\net451\Microsoft.AspNetCore.Http.Features.dll + True + + + ..\..\packages\Microsoft.AspNetCore.JsonPatch.1.0.0\lib\netstandard1.1\Microsoft.AspNetCore.JsonPatch.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Mvc.Abstractions.1.0.1\lib\net451\Microsoft.AspNetCore.Mvc.Abstractions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Mvc.Core.1.0.1\lib\net451\Microsoft.AspNetCore.Mvc.Core.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Mvc.DataAnnotations.1.0.1\lib\net451\Microsoft.AspNetCore.Mvc.DataAnnotations.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Mvc.Formatters.Json.1.0.1\lib\net451\Microsoft.AspNetCore.Mvc.Formatters.Json.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Mvc.Razor.1.0.1\lib\net451\Microsoft.AspNetCore.Mvc.Razor.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Mvc.Razor.Host.1.0.1\lib\net451\Microsoft.AspNetCore.Mvc.Razor.Host.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Mvc.ViewFeatures.1.0.1\lib\net451\Microsoft.AspNetCore.Mvc.ViewFeatures.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Razor.1.0.0\lib\net451\Microsoft.AspNetCore.Razor.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Razor.Runtime.1.0.0\lib\net451\Microsoft.AspNetCore.Razor.Runtime.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Routing.1.0.0\lib\net451\Microsoft.AspNetCore.Routing.dll + True + + + ..\..\packages\Microsoft.AspNetCore.Routing.Abstractions.1.0.0\lib\net451\Microsoft.AspNetCore.Routing.Abstractions.dll + True + + + ..\..\packages\Microsoft.AspNetCore.WebUtilities.1.0.0\lib\net451\Microsoft.AspNetCore.WebUtilities.dll + True + + + ..\..\packages\Microsoft.CodeAnalysis.Common.1.3.0\lib\net45\Microsoft.CodeAnalysis.dll + True + + + ..\..\packages\Microsoft.CodeAnalysis.CSharp.1.3.0\lib\net45\Microsoft.CodeAnalysis.CSharp.dll + True + + + ..\..\packages\Microsoft.DotNet.InternalAbstractions.1.0.0\lib\net451\Microsoft.DotNet.InternalAbstractions.dll + True + + + ..\..\packages\Microsoft.Extensions.Caching.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.Extensions.Caching.Abstractions.dll + True + + + ..\..\packages\Microsoft.Extensions.Caching.Memory.1.0.0\lib\net451\Microsoft.Extensions.Caching.Memory.dll + True + + + ..\..\packages\Microsoft.Extensions.Configuration.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.Extensions.Configuration.Abstractions.dll + True + + + ..\..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll + True + + + ..\..\packages\Microsoft.Extensions.DependencyModel.1.0.0\lib\net451\Microsoft.Extensions.DependencyModel.dll + True + + + ..\..\packages\Microsoft.Extensions.FileProviders.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.Extensions.FileProviders.Abstractions.dll + True + + + ..\..\packages\Microsoft.Extensions.FileProviders.Composite.1.0.0\lib\netstandard1.0\Microsoft.Extensions.FileProviders.Composite.dll + True + + + ..\..\packages\Microsoft.Extensions.FileProviders.Physical.1.0.0\lib\net451\Microsoft.Extensions.FileProviders.Physical.dll + True + + + ..\..\packages\Microsoft.Extensions.FileSystemGlobbing.1.0.0\lib\net451\Microsoft.Extensions.FileSystemGlobbing.dll + True + + + ..\..\packages\Microsoft.Extensions.Localization.1.0.0\lib\net451\Microsoft.Extensions.Localization.dll + True + + + ..\..\packages\Microsoft.Extensions.Localization.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.Extensions.Localization.Abstractions.dll + True + + + ..\..\packages\Microsoft.Extensions.Logging.Abstractions.1.0.0\lib\netstandard1.1\Microsoft.Extensions.Logging.Abstractions.dll + True + + + ..\..\packages\Microsoft.Extensions.ObjectPool.1.0.0\lib\net451\Microsoft.Extensions.ObjectPool.dll + True + + + ..\..\packages\Microsoft.Extensions.Options.1.0.0\lib\netstandard1.0\Microsoft.Extensions.Options.dll + True + + + ..\..\packages\Microsoft.Extensions.PlatformAbstractions.1.0.0\lib\net451\Microsoft.Extensions.PlatformAbstractions.dll + True + + + ..\..\packages\Microsoft.Extensions.Primitives.1.0.0\lib\netstandard1.0\Microsoft.Extensions.Primitives.dll + True + + + ..\..\packages\Microsoft.Extensions.WebEncoders.1.0.0\lib\netstandard1.0\Microsoft.Extensions.WebEncoders.dll + True + + + ..\..\packages\Microsoft.Net.Http.Headers.1.0.0\lib\netstandard1.1\Microsoft.Net.Http.Headers.dll + True + + + ..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll + True + + + ..\..\packages\System.Buffers.4.0.0\lib\netstandard1.1\System.Buffers.dll + True + + + ..\..\packages\System.Collections.Immutable.1.1.37\lib\dotnet\System.Collections.Immutable.dll + True + + + + + ..\..\packages\System.ComponentModel.Primitives.4.1.0\lib\net45\System.ComponentModel.Primitives.dll + True + + + ..\..\packages\System.ComponentModel.TypeConverter.4.1.0\lib\net45\System.ComponentModel.TypeConverter.dll + True + + + ..\..\packages\System.Diagnostics.DiagnosticSource.4.0.0\lib\portable-net45+win8+wpa81\System.Diagnostics.DiagnosticSource.dll + True + + + ..\..\packages\System.Reflection.Metadata.1.2.0\lib\portable-net45+win8\System.Reflection.Metadata.dll + True + + + + + ..\..\packages\System.Text.Encodings.Web.4.0.0\lib\netstandard1.0\System.Text.Encodings.Web.dll + True + @@ -133,14 +358,14 @@ + + {2c6f51df-015c-4db6-b44c-0e5e4f25e2a9} + Nancy.ViewEngines.Razor + {3F18F5DA-93E0-4513-8BF4-BC8EE5C4117C} Nancy.ViewEngines.Razor.Tests.Models - - {2C6F51DF-015C-4DB6-B44C-0E5E4F25E2A9} - Nancy.ViewEngines.Razor - {34576216-0DCA-4B0F-A0DC-9075E75A676F} Nancy @@ -152,10 +377,6 @@ Always TestViews\ViewThatUsesAttributeWithRawHtmlStringInside.cshtml - - Always - TestViews\ViewThatUsesHelper.cshtml - Always TestViews\ViewThatUsesAttributeWithCodeInside.cshtml @@ -237,6 +458,8 @@ + + diff --git a/test/Nancy.ViewEngines.Razor.Tests.MSBuild/packages.config b/test/Nancy.ViewEngines.Razor.Tests.MSBuild/packages.config index 60b866375b..b4413e9634 100644 --- a/test/Nancy.ViewEngines.Razor.Tests.MSBuild/packages.config +++ b/test/Nancy.ViewEngines.Razor.Tests.MSBuild/packages.config @@ -2,6 +2,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/test/Nancy.ViewEngines.Razor.Tests/GreetingViewBase.cs b/test/Nancy.ViewEngines.Razor.Tests/GreetingViewBase.cs index 8aede0b60a..966ef32546 100644 --- a/test/Nancy.ViewEngines.Razor.Tests/GreetingViewBase.cs +++ b/test/Nancy.ViewEngines.Razor.Tests/GreetingViewBase.cs @@ -1,6 +1,6 @@ namespace Nancy.ViewEngines.Razor.Tests { - public abstract class GreetingViewBase : NancyRazorViewBase + public abstract class GreetingViewBase : NancyRazorPage { public string Greet() { diff --git a/test/Nancy.ViewEngines.Razor.Tests/RazorViewEngineFixture.cs b/test/Nancy.ViewEngines.Razor.Tests/RazorViewEngineFixture.cs index e9bbdeb16f..0f2fbc8a20 100644 --- a/test/Nancy.ViewEngines.Razor.Tests/RazorViewEngineFixture.cs +++ b/test/Nancy.ViewEngines.Razor.Tests/RazorViewEngineFixture.cs @@ -3,6 +3,7 @@ using System; using System.CodeDom; using System.CodeDom.Compiler; + using System.Collections.Generic; using System.Dynamic; using System.IO; using System.Linq; @@ -24,24 +25,22 @@ public class RazorViewEngineFixture public RazorViewEngineFixture() { + this.rootPathProvider = A.Fake(); + A.CallTo(() => this.rootPathProvider.GetRootPath()).Returns(Path.Combine(Environment.CurrentDirectory, "TestViews")); + + this.fileSystemViewLocationProvider = new FileSystemViewLocationProvider(this.rootPathProvider, new DefaultFileSystemReader()); + var assemblyCatalog = new AppDomainAssemblyCatalog(); var environment = new DefaultNancyEnvironment(); - environment.Tracing( - enabled: true, - displayErrorTraces: true); + environment.Tracing(enabled: true, displayErrorTraces: true); + environment.AddValue(ViewConfiguration.Default); this.configuration = A.Fake(); - this.engine = new RazorViewEngine(this.configuration, environment, assemblyCatalog); + this.engine = new RazorViewEngine(this.configuration, assemblyCatalog, this.fileSystemViewLocationProvider, environment); A.CallTo(() => this.configuration.GetAssemblyNames()).Returns(new[] { "Nancy.ViewEngines.Razor.Tests.Models" }); var cache = A.Fake(); - A.CallTo(() => cache.GetOrAdd(A.Ignored, A>>.Ignored)) - .ReturnsLazily(x => - { - var result = x.GetArgument(0); - return x.GetArgument>>(1).Invoke(result); - }); this.renderContext = A.Fake(); A.CallTo(() => this.renderContext.ViewCache).Returns(cache); @@ -49,13 +48,12 @@ public RazorViewEngineFixture() .ReturnsLazily(x => { var viewName = x.GetArgument(0); - return FindView(viewName); + return this.FindView(viewName); }); - this.rootPathProvider = A.Fake(); - A.CallTo(() => this.rootPathProvider.GetRootPath()).Returns(Path.Combine(Environment.CurrentDirectory, "TestViews")); - - this.fileSystemViewLocationProvider = new FileSystemViewLocationProvider(this.rootPathProvider, new DefaultFileSystemReader()); + var locator = new DefaultViewLocator(this.fileSystemViewLocationProvider, new[] { engine }, environment); + var context = new ViewEngineStartupContext(A.Fake(), locator); + this.engine.Initialize(context); } [Fact] @@ -218,62 +216,62 @@ public void RenderView_csharp_should_be_able_to_use_a_using_statement() stream.ShouldEqual("

    Mr. Jeff likes Music!

    ", true); } - [Fact] - public void RenderView_csharp_should_be_able_to_find_the_model_when_a_null_model_is_passed() - { - var view = new StringBuilder() - .AppendLine("@model Nancy.ViewEngines.Razor.Tests.Models.Person") - .AppendLine(@"@{ var hobby = new Hobby { Name = ""Music"" }; }") - .Append("

    Mr. Somebody likes @hobby.Name!

    "); + //[Fact] + //public void RenderView_csharp_should_be_able_to_find_the_model_when_a_null_model_is_passed() + //{ + // var view = new StringBuilder() + // .AppendLine("@model Nancy.ViewEngines.Razor.Tests.Models.Person") + // .AppendLine(@"@{ var hobby = new Hobby { Name = ""Music"" }; }") + // .Append("

    Mr. Somebody likes @hobby.Name!

    "); - var location = new ViewLocationResult( - string.Empty, - string.Empty, - "cshtml", - () => new StringReader(view.ToString()) - ); + // var location = new ViewLocationResult( + // string.Empty, + // string.Empty, + // "cshtml", + // () => new StringReader(view.ToString()) + // ); - var stream = new MemoryStream(); + // var stream = new MemoryStream(); - A.CallTo(() => this.configuration.AutoIncludeModelNamespace).Returns(true); + // A.CallTo(() => this.configuration.AutoIncludeModelNamespace).Returns(true); - // When - var response = this.engine.RenderView(location, null, this.renderContext); - response.Contents.Invoke(stream); + // // When + // var response = this.engine.RenderView(location, null, this.renderContext); + // response.Contents.Invoke(stream); - // Then - stream.ShouldEqual("

    Mr. Somebody likes Music!

    ", true); - } + // // Then + // stream.ShouldEqual("

    Mr. Somebody likes Music!

    ", true); + //} - [Fact] - public void RenderView_csharp_should_include_namespace_of_model_if_specified_in_the_configuration() - { - // Given - var view = new StringBuilder() - .AppendLine("@model Nancy.ViewEngines.Razor.Tests.Models.Person") - .AppendLine(@"@{ var hobby = new Hobby { Name = ""Music"" }; }") - .Append("

    Mr. @Model.Name likes @hobby.Name!

    "); + //[Fact] + //public void RenderView_csharp_should_include_namespace_of_model_if_specified_in_the_configuration() + //{ + // // Given + // var view = new StringBuilder() + // .AppendLine("@model Nancy.ViewEngines.Razor.Tests.Models.Person") + // .AppendLine(@"@{ var hobby = new Hobby { Name = ""Music"" }; }") + // .Append("

    Mr. @Model.Name likes @hobby.Name!

    "); - var location = new ViewLocationResult( - string.Empty, - string.Empty, - "cshtml", - () => new StringReader(view.ToString()) - ); + // var location = new ViewLocationResult( + // string.Empty, + // string.Empty, + // "cshtml", + // () => new StringReader(view.ToString()) + // ); - var stream = new MemoryStream(); + // var stream = new MemoryStream(); - var model = new Person { Name = "Jeff" }; + // var model = new Person { Name = "Jeff" }; - A.CallTo(() => this.configuration.AutoIncludeModelNamespace).Returns(true); + // A.CallTo(() => this.configuration.AutoIncludeModelNamespace).Returns(true); - // When - var response = this.engine.RenderView(location, model, this.renderContext); - response.Contents.Invoke(stream); + // // When + // var response = this.engine.RenderView(location, model, this.renderContext); + // response.Contents.Invoke(stream); - // Then - stream.ShouldEqual("

    Mr. Jeff likes Music!

    ", true); - } + // // Then + // stream.ShouldEqual("

    Mr. Jeff likes Music!

    ", true); + //} [Fact] public void Should_be_able_to_render_view_with_layout_to_stream() @@ -407,23 +405,6 @@ public void Should_be_able_to_render_view_with_layout_and_optional_section_overr "
    ViewThatUsesLayoutAndOptionalSectionOverridingDefaults
    "); } - [Fact] - public void Should_be_able_to_render_view_with_helper_to_steam() - { - // Given - var location = FindView("ViewThatUsesHelper"); - - var stream = new MemoryStream(); - - // When - var response = this.engine.RenderView(location, null, this.renderContext); - response.Contents.Invoke(stream); - - // Then - var output = ReadAll(stream); - output.ShouldContainInOrder("

    SimplyLayout

    ", "
    ViewThatUsesHelper
    ", "

    "); - } - [Fact] public void Should_use_custom_view_base_with_csharp_views() { @@ -464,9 +445,9 @@ public void Should_render_attributes_with_code_inside() var output = ReadAll(stream); output.ShouldContain("Bob"); } - + [Fact] - public void Should_render_compilation_source_on_compilation_error() + public void Should_render_compilation_errors() { // Given var view = new StringBuilder() @@ -488,7 +469,7 @@ public void Should_render_compilation_source_on_compilation_error() // Then var output = ReadAll(stream); - output.ShouldContain("namespace RazorOutput {"); + output.ShouldContain("Line: 2 Column: 10"); } [Fact] @@ -542,22 +523,22 @@ public void Should_render_attributes_with_RawHtmlString_inside() output.ShouldContain(string.Format("", PHRASE)); } - [Fact] - public void Should_render_attributes_with_NonEncodedHtmlString_inside() - { - // Given - var location = FindView("ViewThatUsesAttributeWithNonEncodedHtmlStringInside"); - var stream = new MemoryStream(); - const string PHRASE = "Slugs are secret spies on gardeners, but no one knows who they spy for"; - - // When - var response = this.engine.RenderView(location, new NonEncodedHtmlString(PHRASE), this.renderContext); - response.Contents.Invoke(stream); - - // Then - var output = ReadAll(stream); - output.ShouldContain(string.Format("", PHRASE)); - } + //[Fact] + //public void Should_render_attributes_with_NonEncodedHtmlString_inside() + //{ + // // Given + // var location = FindView("ViewThatUsesAttributeWithNonEncodedHtmlStringInside"); + // var stream = new MemoryStream(); + // const string PHRASE = "Slugs are secret spies on gardeners, but no one knows who they spy for"; + + // // When + // var response = this.engine.RenderView(location, new NonEncodedHtmlString(PHRASE), this.renderContext); + // response.Contents.Invoke(stream); + + // // Then + // var output = ReadAll(stream); + // output.ShouldContain(string.Format("", PHRASE)); + //} [Theory] [InlineData(typeof(string))]