Add some benchmarks for project system
Adds a few benchmarks for things we're working on, also addressed a few small perf issues that have an impact for large documents.
This commit is contained in:
parent
63af9221dc
commit
9b911cbb6e
|
|
@ -17,6 +17,18 @@
|
|||
<Compile Include="..\..\src\Microsoft.VisualStudio.LanguageServices.Razor\Serialization\*.cs">
|
||||
<Link>Serialization\%(FileName)%(Extension)</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\test\Microsoft.CodeAnalysis.Razor.Workspaces.Test.Common\TestServices.cs">
|
||||
<Link>TestServices\%(FileName)%(Extension)</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\test\Microsoft.CodeAnalysis.Razor.Workspaces.Test.Common\TestWorkspace.cs">
|
||||
<Link>TestServices\%(FileName)%(Extension)</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\test\Microsoft.CodeAnalysis.Razor.Workspaces.Test.Common\TestLanguageServices.cs">
|
||||
<Link>TestServices\%(FileName)%(Extension)</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\test\Microsoft.CodeAnalysis.Razor.Workspaces.Test.Common\TestWorkspaceServices.cs">
|
||||
<Link>TestServices\%(FileName)%(Extension)</Link>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,53 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Performance
|
||||
{
|
||||
public class BackgroundCodeGenerationBenchmark : ProjectSnapshotManagerBenchmarkBase
|
||||
{
|
||||
[IterationSetup]
|
||||
public void Setup()
|
||||
{
|
||||
SnapshotManager = CreateProjectSnapshotManager();
|
||||
SnapshotManager.HostProjectAdded(HostProject);
|
||||
SnapshotManager.Changed += SnapshotManager_Changed;
|
||||
}
|
||||
|
||||
[IterationCleanup]
|
||||
public void Cleanup()
|
||||
{
|
||||
SnapshotManager.Changed -= SnapshotManager_Changed;
|
||||
|
||||
Tasks.Clear();
|
||||
}
|
||||
|
||||
private List<Task> Tasks { get; } = new List<Task>();
|
||||
|
||||
private DefaultProjectSnapshotManager SnapshotManager { get; set; }
|
||||
|
||||
[Benchmark(Description = "Generates the code for 100 files", OperationsPerInvoke = 100)]
|
||||
public async Task BackgroundCodeGeneration_Generate100Files()
|
||||
{
|
||||
for (var i = 0; i < Documents.Length; i++)
|
||||
{
|
||||
SnapshotManager.DocumentAdded(HostProject, Documents[i], TextLoaders[i % 4]);
|
||||
}
|
||||
|
||||
await Task.WhenAll(Tasks);
|
||||
}
|
||||
|
||||
private void SnapshotManager_Changed(object sender, ProjectChangeEventArgs e)
|
||||
{
|
||||
// The real work happens here.
|
||||
var project = SnapshotManager.GetLoadedProject(e.ProjectFilePath);
|
||||
var document = project.GetDocument(e.DocumentFilePath);
|
||||
|
||||
Tasks.Add(document.GetGeneratedOutputAsync());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Performance
|
||||
{
|
||||
public class ProjectLoadBenchmark : ProjectSnapshotManagerBenchmarkBase
|
||||
{
|
||||
[IterationSetup]
|
||||
public void Setup()
|
||||
{
|
||||
SnapshotManager = CreateProjectSnapshotManager();
|
||||
}
|
||||
|
||||
private DefaultProjectSnapshotManager SnapshotManager { get; set; }
|
||||
|
||||
[Benchmark(Description = "Initializes a project and 100 files", OperationsPerInvoke = 100)]
|
||||
public void ProjectLoad_AddProjectAnd100Files()
|
||||
{
|
||||
SnapshotManager.HostProjectAdded(HostProject);
|
||||
|
||||
for (var i= 0; i < Documents.Length; i++)
|
||||
{
|
||||
SnapshotManager.DocumentAdded(HostProject, Documents[i], TextLoaders[i % 4]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Mvc.Razor.Extensions;
|
||||
using Microsoft.AspNetCore.Razor.Language;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.Host;
|
||||
using Microsoft.CodeAnalysis.Razor;
|
||||
using Microsoft.CodeAnalysis.Razor.ProjectSystem;
|
||||
using Microsoft.CodeAnalysis.Text;
|
||||
using Microsoft.VisualStudio.LanguageServices.Razor.Serialization;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Microsoft.AspNetCore.Razor.Performance
|
||||
{
|
||||
public class ProjectSnapshotManagerBenchmarkBase
|
||||
{
|
||||
public ProjectSnapshotManagerBenchmarkBase()
|
||||
{
|
||||
var current = new DirectoryInfo(AppContext.BaseDirectory);
|
||||
while (current != null && !File.Exists(Path.Combine(current.FullName, "Razor.sln")))
|
||||
{
|
||||
current = current.Parent;
|
||||
}
|
||||
|
||||
var root = current;
|
||||
var projectRoot = Path.Combine(root.FullName, "test", "testapps", "LargeProject");
|
||||
|
||||
HostProject = new HostProject(Path.Combine(projectRoot, "LargeProject.csproj"), FallbackRazorConfiguration.MVC_2_1);
|
||||
|
||||
TextLoaders = new TextLoader[4];
|
||||
for (var i = 0; i < 4; i++)
|
||||
{
|
||||
var filePath = Path.Combine(projectRoot, "Views", "Home", $"View00{i % 4}.cshtml");
|
||||
var text = SourceText.From(filePath, encoding: null);
|
||||
TextLoaders[i] = TextLoader.From(TextAndVersion.Create(text, VersionStamp.Create()));
|
||||
}
|
||||
|
||||
Documents = new HostDocument[100];
|
||||
for (var i = 0; i < Documents.Length; i++)
|
||||
{
|
||||
var filePath = Path.Combine(projectRoot, "Views", "Home", $"View00{i % 4}.cshtml");
|
||||
Documents[i] = new HostDocument(filePath, $"/Views/Home/View00{i}.cshtml");
|
||||
}
|
||||
|
||||
var tagHelpers = Path.Combine(root.FullName, "benchmarks", "Microsoft.AspNetCore.Razor.Performance", "taghelpers.json");
|
||||
TagHelperResolver = new StaticTagHelperResolver(ReadTagHelpers(tagHelpers));
|
||||
}
|
||||
|
||||
internal HostProject HostProject { get; }
|
||||
|
||||
internal HostDocument[] Documents { get; }
|
||||
|
||||
internal TextLoader[] TextLoaders { get; }
|
||||
|
||||
internal TagHelperResolver TagHelperResolver { get; }
|
||||
|
||||
internal DefaultProjectSnapshotManager CreateProjectSnapshotManager()
|
||||
{
|
||||
var services = TestServices.Create(
|
||||
new IWorkspaceService[]
|
||||
{
|
||||
new StaticProjectSnapshotProjectEngineFactory(),
|
||||
},
|
||||
new ILanguageService[]
|
||||
{
|
||||
TagHelperResolver,
|
||||
});
|
||||
|
||||
return new DefaultProjectSnapshotManager(
|
||||
new TestForegroundDispatcher(),
|
||||
new TestErrorReporter(),
|
||||
Array.Empty<ProjectSnapshotChangeTrigger>(),
|
||||
new AdhocWorkspace(services));
|
||||
}
|
||||
|
||||
private static IReadOnlyList<TagHelperDescriptor> ReadTagHelpers(string filePath)
|
||||
{
|
||||
var serializer = new JsonSerializer();
|
||||
serializer.Converters.Add(new RazorDiagnosticJsonConverter());
|
||||
serializer.Converters.Add(new TagHelperDescriptorJsonConverter());
|
||||
|
||||
using (var reader = new JsonTextReader(File.OpenText(filePath)))
|
||||
{
|
||||
return serializer.Deserialize<IReadOnlyList<TagHelperDescriptor>>(reader);
|
||||
}
|
||||
}
|
||||
|
||||
private class TestForegroundDispatcher : ForegroundDispatcher
|
||||
{
|
||||
public override bool IsForegroundThread => true;
|
||||
|
||||
public override TaskScheduler ForegroundScheduler => TaskScheduler.Default;
|
||||
|
||||
public override TaskScheduler BackgroundScheduler => TaskScheduler.Default;
|
||||
}
|
||||
|
||||
private class TestErrorReporter : ErrorReporter
|
||||
{
|
||||
public override void ReportError(Exception exception)
|
||||
{
|
||||
}
|
||||
|
||||
public override void ReportError(Exception exception, ProjectSnapshot project)
|
||||
{
|
||||
}
|
||||
|
||||
public override void ReportError(Exception exception, Project workspaceProject)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private class StaticTagHelperResolver : TagHelperResolver
|
||||
{
|
||||
private readonly IReadOnlyList<TagHelperDescriptor> _tagHelpers;
|
||||
|
||||
public StaticTagHelperResolver(IReadOnlyList<TagHelperDescriptor> tagHelpers)
|
||||
{
|
||||
this._tagHelpers = tagHelpers;
|
||||
}
|
||||
|
||||
public override Task<TagHelperResolutionResult> GetTagHelpersAsync(ProjectSnapshot project, CancellationToken cancellationToken = default)
|
||||
{
|
||||
return Task.FromResult(new TagHelperResolutionResult(_tagHelpers, Array.Empty<RazorDiagnostic>()));
|
||||
}
|
||||
}
|
||||
|
||||
private class StaticProjectSnapshotProjectEngineFactory : ProjectSnapshotProjectEngineFactory
|
||||
{
|
||||
public override RazorProjectEngine Create(ProjectSnapshot project, RazorProjectFileSystem fileSystem, Action<RazorProjectEngineBuilder> configure)
|
||||
{
|
||||
return RazorProjectEngine.Create(project.Configuration, fileSystem, b =>
|
||||
{
|
||||
RazorExtensions.Register(b);
|
||||
});
|
||||
}
|
||||
|
||||
public override IProjectEngineFactory FindFactory(ProjectSnapshot project)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public override IProjectEngineFactory FindSerializableFactory(ProjectSnapshot project)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -19,10 +19,7 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
'\u2029' // Paragraph separator
|
||||
};
|
||||
|
||||
public static bool IsNewLine(char value)
|
||||
{
|
||||
return NewLineCharacters.Contains(value);
|
||||
}
|
||||
public static bool IsNewLine(char value) => Array.IndexOf<char>(NewLineCharacters, value) != -1;
|
||||
|
||||
public static bool IsNewLine(string value)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
{
|
||||
private readonly LineTrackingStringBuffer _buffer;
|
||||
private int _position = 0;
|
||||
private int _current;
|
||||
private SourceLocation _location;
|
||||
private char? _current;
|
||||
|
||||
public SeekableTextReader(string source, string filePath) : this(source.ToCharArray(), filePath) { }
|
||||
|
||||
|
|
@ -24,8 +24,6 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
|
||||
_buffer = new LineTrackingStringBuffer(source, filePath);
|
||||
UpdateState();
|
||||
|
||||
_location = new SourceLocation(filePath, 0, 0, 0);
|
||||
}
|
||||
|
||||
public SourceLocation Location => _location;
|
||||
|
|
@ -47,24 +45,13 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
|
||||
public override int Read()
|
||||
{
|
||||
if (_current == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
var chr = _current.Value;
|
||||
var c = _current;
|
||||
_position++;
|
||||
UpdateState();
|
||||
return chr;
|
||||
return c;
|
||||
}
|
||||
|
||||
public override int Peek()
|
||||
{
|
||||
if (_current == null)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
return _current.Value;
|
||||
}
|
||||
public override int Peek() => _current;
|
||||
|
||||
private void UpdateState()
|
||||
{
|
||||
|
|
@ -76,12 +63,12 @@ namespace Microsoft.AspNetCore.Razor.Language.Legacy
|
|||
}
|
||||
else if (_buffer.Length == 0)
|
||||
{
|
||||
_current = null;
|
||||
_current = -1;
|
||||
_location = SourceLocation.Zero;
|
||||
}
|
||||
else
|
||||
{
|
||||
_current = null;
|
||||
_current = -1;
|
||||
_location = _buffer.EndLocation;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,23 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<_RazorMSBuildRoot>$(SolutionRoot)src\Microsoft.AspNetCore.Razor.Design\bin\$(Configuration)\</_RazorMSBuildRoot>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="$(SolutionRoot)src\Microsoft.AspNetCore.Razor.Design\build\netstandard2.0\Microsoft.AspNetCore.Razor.Design.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<!-- Override for the MVC extension -->
|
||||
<_MvcExtensionAssemblyPath>$(SolutionRoot)src\Microsoft.AspNetCore.Mvc.Razor.Extensions\bin\$(Configuration)\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.Extensions.dll</_MvcExtensionAssemblyPath>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(SolutionRoot)src\Microsoft.AspNetCore.Mvc.Razor.Extensions\build\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.Extensions.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.2</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Test Placeholder -->
|
||||
|
||||
<Import Project="$(SolutionRoot)src\Microsoft.AspNetCore.Mvc.Razor.Extensions\build\netstandard2.0\Microsoft.AspNetCore.Mvc.Razor.Extensions.targets" />
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>@ViewData["Title"] - SimplePages</title>
|
||||
|
||||
<environment include="Development">
|
||||
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
|
||||
<link rel="stylesheet" href="~/css/site.css" />
|
||||
</environment>
|
||||
<environment exclude="Development">
|
||||
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
|
||||
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
|
||||
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
|
||||
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
|
||||
</environment>
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a asp-page="/Index" class="navbar-brand">SimplePages</a>
|
||||
</div>
|
||||
<div class="navbar-collapse collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a asp-page="/Index">Home</a></li>
|
||||
<li><a asp-page="/About">About</a></li>
|
||||
<li><a asp-page="/Contact">Contact</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container body-content">
|
||||
@RenderBody()
|
||||
<hr />
|
||||
<footer>
|
||||
<p>© 2017 - SimplePages</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<environment include="Development">
|
||||
<script src="~/lib/jquery/dist/jquery.js"></script>
|
||||
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
|
||||
<script src="~/js/site.js" asp-append-version="true"></script>
|
||||
</environment>
|
||||
<environment exclude="Development">
|
||||
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"
|
||||
asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
|
||||
asp-fallback-test="window.jQuery"
|
||||
crossorigin="anonymous"
|
||||
integrity="sha384-K+ctZQ+LL8q6tP7I94W+qzQsfRV2a+AfHIi9k8z8l9ggpc8X+Ytst4yBo/hH+8Fk">
|
||||
</script>
|
||||
<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/bootstrap.min.js"
|
||||
asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
|
||||
asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
|
||||
crossorigin="anonymous"
|
||||
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa">
|
||||
</script>
|
||||
<script src="~/js/site.min.js" asp-append-version="true"></script>
|
||||
</environment>
|
||||
|
||||
@RenderSection("Scripts", required: false)
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
@{
|
||||
ViewData["Title"] = "About";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
||||
<p>Use this area to provide additional information.</p>
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
@{
|
||||
ViewData["Title"] = "Home Page";
|
||||
}
|
||||
|
||||
<div id="myCarousel" class="carousel slide" data-ride="carousel" data-interval="6000">
|
||||
<ol class="carousel-indicators">
|
||||
<li data-target="#myCarousel" data-slide-to="0" class="active"></li>
|
||||
<li data-target="#myCarousel" data-slide-to="1"></li>
|
||||
<li data-target="#myCarousel" data-slide-to="2"></li>
|
||||
<li data-target="#myCarousel" data-slide-to="3"></li>
|
||||
</ol>
|
||||
<div class="carousel-inner" role="listbox">
|
||||
<div class="item active">
|
||||
<img src="~/images/banner1.svg" alt="ASP.NET" class="img-responsive" />
|
||||
<div class="carousel-caption" role="option">
|
||||
<p>
|
||||
Learn how to build ASP.NET apps that can run anywhere.
|
||||
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525028&clcid=0x409">
|
||||
Learn More
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<img src="~/images/banner2.svg" alt="Visual Studio" class="img-responsive" />
|
||||
<div class="carousel-caption" role="option">
|
||||
<p>
|
||||
There are powerful new features in Visual Studio for building modern web apps.
|
||||
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525030&clcid=0x409">
|
||||
Learn More
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<img src="~/images/banner3.svg" alt="Package Management" class="img-responsive" />
|
||||
<div class="carousel-caption" role="option">
|
||||
<p>
|
||||
Bring in libraries from NuGet, Bower, and npm, and automate tasks using Grunt or Gulp.
|
||||
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525029&clcid=0x409">
|
||||
Learn More
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="item">
|
||||
<img src="~/images/banner4.svg" alt="Microsoft Azure" class="img-responsive" />
|
||||
<div class="carousel-caption" role="option">
|
||||
<p>
|
||||
Learn how Microsoft's Azure cloud platform allows you to build, deploy, and scale web apps.
|
||||
<a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkID=525027&clcid=0x409">
|
||||
Learn More
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
|
||||
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
|
||||
<span class="sr-only">Previous</span>
|
||||
</a>
|
||||
<a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
|
||||
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
|
||||
<span class="sr-only">Next</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-3">
|
||||
<h2>Application uses</h2>
|
||||
<ul>
|
||||
<li>Sample pages using ASP.NET Core MVC</li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=518004">Bower</a> for managing client-side libraries</li>
|
||||
<li>Theming using <a href="https://go.microsoft.com/fwlink/?LinkID=398939">Bootstrap</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<h2>How to</h2>
|
||||
<ul>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=398600">Add a Controller and View</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699315">Manage User Secrets using Secret Manager.</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699316">Use logging to log a message.</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699317">Add packages using NuGet.</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699318">Add client packages using Bower.</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699319">Target development, staging or production environment.</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<h2>Overview</h2>
|
||||
<ul>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=518008">Conceptual overview of what is ASP.NET Core</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=699320">Fundamentals of ASP.NET Core such as Startup and middleware.</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=398602">Working with Data</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkId=398603">Security</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=699321">Client side development</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=699322">Develop on different platforms</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=699323">Read more on the documentation site</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<h2>Run & Deploy</h2>
|
||||
<ul>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=517851">Run your app</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=517853">Run tools such as EF migrations and more</a></li>
|
||||
<li><a href="https://go.microsoft.com/fwlink/?LinkID=398609">Publish to Microsoft Azure Web Apps</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
@{
|
||||
ViewData["Title"] = "Contact";
|
||||
}
|
||||
<h2>@ViewData["Title"]</h2>
|
||||
<h3>@ViewData["Message"]</h3>
|
||||
|
||||
<address>
|
||||
One Microsoft Way<br />
|
||||
Redmond, WA 98052-6399<br />
|
||||
<abbr title="Phone">P:</abbr>
|
||||
425.555.0100
|
||||
</address>
|
||||
|
||||
<address>
|
||||
<strong>Support:</strong> <a href="mailto:Support@example.com">Support@example.com</a><br />
|
||||
<strong>Marketing:</strong> <a href="mailto:Marketing@example.com">Marketing@example.com</a>
|
||||
</address>
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>@ViewData["Title"] - SimplePages</title>
|
||||
|
||||
<environment include="Development">
|
||||
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
|
||||
<link rel="stylesheet" href="~/css/site.css" />
|
||||
</environment>
|
||||
<environment exclude="Development">
|
||||
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
|
||||
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
|
||||
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-value="absolute" />
|
||||
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
|
||||
</environment>
|
||||
</head>
|
||||
<body>
|
||||
<nav class="navbar navbar-inverse navbar-fixed-top">
|
||||
<div class="container">
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a asp-page="/Index" class="navbar-brand">SimplePages</a>
|
||||
</div>
|
||||
<div class="navbar-collapse collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a asp-page="/Index">Home</a></li>
|
||||
<li><a asp-page="/About">About</a></li>
|
||||
<li><a asp-page="/Contact">Contact</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
<div class="container body-content">
|
||||
@RenderBody()
|
||||
<hr />
|
||||
<footer>
|
||||
<p>© 2017 - SimplePages</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<environment include="Development">
|
||||
<script src="~/lib/jquery/dist/jquery.js"></script>
|
||||
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
|
||||
<script src="~/js/site.js" asp-append-version="true"></script>
|
||||
</environment>
|
||||
<environment exclude="Development">
|
||||
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"
|
||||
asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
|
||||
asp-fallback-test="window.jQuery"
|
||||
crossorigin="anonymous"
|
||||
integrity="sha384-K+ctZQ+LL8q6tP7I94W+qzQsfRV2a+AfHIi9k8z8l9ggpc8X+Ytst4yBo/hH+8Fk">
|
||||
</script>
|
||||
<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/bootstrap.min.js"
|
||||
asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
|
||||
asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
|
||||
crossorigin="anonymous"
|
||||
integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa">
|
||||
</script>
|
||||
<script src="~/js/site.min.js" asp-append-version="true"></script>
|
||||
</environment>
|
||||
|
||||
@RenderSection("Scripts", required: false)
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
@using LargeProject
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
@{
|
||||
Layout = "_Layout";
|
||||
}
|
||||
Loading…
Reference in New Issue