init
This commit is contained in:
223
.gitignore
vendored
Normal file
223
.gitignore
vendored
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.userosscache
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
|
*.userprefs
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
[Dd]ebug/
|
||||||
|
[Dd]ebugPublic/
|
||||||
|
[Rr]elease/
|
||||||
|
[Rr]eleases/
|
||||||
|
x64/
|
||||||
|
x86/
|
||||||
|
build/
|
||||||
|
bld/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
|
||||||
|
# Visual Studio 2015 cache/options directory
|
||||||
|
.vs/
|
||||||
|
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||||
|
wwwroot/
|
||||||
|
|
||||||
|
# MSTest test Results
|
||||||
|
[Tt]est[Rr]esult*/
|
||||||
|
[Bb]uild[Ll]og.*
|
||||||
|
|
||||||
|
# NUNIT
|
||||||
|
*.VisualState.xml
|
||||||
|
TestResult.xml
|
||||||
|
|
||||||
|
# Build Results of an ATL Project
|
||||||
|
[Dd]ebugPS/
|
||||||
|
[Rr]eleasePS/
|
||||||
|
dlldata.c
|
||||||
|
|
||||||
|
# DNX
|
||||||
|
project.lock.json
|
||||||
|
artifacts/
|
||||||
|
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*_i.h
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.tmp_proj
|
||||||
|
*.log
|
||||||
|
*.vspscc
|
||||||
|
*.vssscc
|
||||||
|
.builds
|
||||||
|
*.pidb
|
||||||
|
*.svclog
|
||||||
|
*.scc
|
||||||
|
|
||||||
|
# Chutzpah Test files
|
||||||
|
_Chutzpah*
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
*.cachefile
|
||||||
|
|
||||||
|
# Visual Studio profiler
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
*.vspx
|
||||||
|
*.sap
|
||||||
|
|
||||||
|
# TFS 2012 Local Workspace
|
||||||
|
$tf/
|
||||||
|
|
||||||
|
# Guidance Automation Toolkit
|
||||||
|
*.gpState
|
||||||
|
|
||||||
|
# ReSharper is a .NET coding add-in
|
||||||
|
_ReSharper*/
|
||||||
|
*.[Rr]e[Ss]harper
|
||||||
|
*.DotSettings.user
|
||||||
|
|
||||||
|
# JustCode is a .NET coding add-in
|
||||||
|
.JustCode
|
||||||
|
|
||||||
|
# TeamCity is a build add-in
|
||||||
|
_TeamCity*
|
||||||
|
|
||||||
|
# DotCover is a Code Coverage Tool
|
||||||
|
*.dotCover
|
||||||
|
|
||||||
|
# NCrunch
|
||||||
|
_NCrunch_*
|
||||||
|
.*crunch*.local.xml
|
||||||
|
nCrunchTemp_*
|
||||||
|
|
||||||
|
# MightyMoose
|
||||||
|
*.mm.*
|
||||||
|
AutoTest.Net/
|
||||||
|
|
||||||
|
# Web workbench (sass)
|
||||||
|
.sass-cache/
|
||||||
|
|
||||||
|
# Installshield output folder
|
||||||
|
[Ee]xpress/
|
||||||
|
|
||||||
|
# DocProject is a documentation generator add-in
|
||||||
|
DocProject/buildhelp/
|
||||||
|
DocProject/Help/*.HxT
|
||||||
|
DocProject/Help/*.HxC
|
||||||
|
DocProject/Help/*.hhc
|
||||||
|
DocProject/Help/*.hhk
|
||||||
|
DocProject/Help/*.hhp
|
||||||
|
DocProject/Help/Html2
|
||||||
|
DocProject/Help/html
|
||||||
|
|
||||||
|
# Click-Once directory
|
||||||
|
publish/
|
||||||
|
|
||||||
|
# Publish Web Output
|
||||||
|
*.[Pp]ublish.xml
|
||||||
|
*.azurePubxml
|
||||||
|
# TODO: Comment the next line if you want to checkin your web deploy settings
|
||||||
|
# but database connection strings (with potential passwords) will be unencrypted
|
||||||
|
*.pubxml
|
||||||
|
*.publishproj
|
||||||
|
|
||||||
|
# NuGet Packages
|
||||||
|
*.nupkg
|
||||||
|
# The packages folder can be ignored because of Package Restore
|
||||||
|
**/packages/*
|
||||||
|
# except build/, which is used as an MSBuild target.
|
||||||
|
!**/packages/build/
|
||||||
|
# Uncomment if necessary however generally it will be regenerated when needed
|
||||||
|
#!**/packages/repositories.config
|
||||||
|
|
||||||
|
# Windows Azure Build Output
|
||||||
|
csx/
|
||||||
|
*.build.csdef
|
||||||
|
|
||||||
|
# Windows Store app package directory
|
||||||
|
AppPackages/
|
||||||
|
|
||||||
|
# Visual Studio cache files
|
||||||
|
# files ending in .cache can be ignored
|
||||||
|
*.[Cc]ache
|
||||||
|
# but keep track of directories ending in .cache
|
||||||
|
!*.[Cc]ache/
|
||||||
|
|
||||||
|
# Others
|
||||||
|
ClientBin/
|
||||||
|
[Ss]tyle[Cc]op.*
|
||||||
|
~$*
|
||||||
|
*~
|
||||||
|
*.dbmdl
|
||||||
|
*.dbproj.schemaview
|
||||||
|
*.pfx
|
||||||
|
*.publishsettings
|
||||||
|
node_modules/
|
||||||
|
orleans.codegen.cs
|
||||||
|
|
||||||
|
# RIA/Silverlight projects
|
||||||
|
Generated_Code/
|
||||||
|
|
||||||
|
# Backup & report files from converting an old project file
|
||||||
|
# to a newer Visual Studio version. Backup files are not needed,
|
||||||
|
# because we have git ;-)
|
||||||
|
_UpgradeReport_Files/
|
||||||
|
Backup*/
|
||||||
|
UpgradeLog*.XML
|
||||||
|
UpgradeLog*.htm
|
||||||
|
|
||||||
|
# SQL Server files
|
||||||
|
*.mdf
|
||||||
|
*.ldf
|
||||||
|
|
||||||
|
# Business Intelligence projects
|
||||||
|
*.rdl.data
|
||||||
|
*.bim.layout
|
||||||
|
*.bim_*.settings
|
||||||
|
|
||||||
|
# Microsoft Fakes
|
||||||
|
FakesAssemblies/
|
||||||
|
|
||||||
|
# Node.js Tools for Visual Studio
|
||||||
|
.ntvs_analysis.dat
|
||||||
|
|
||||||
|
# Visual Studio 6 build log
|
||||||
|
*.plg
|
||||||
|
|
||||||
|
# Visual Studio 6 workspace options file
|
||||||
|
*.opt
|
||||||
|
|
||||||
|
# Visual Studio LightSwitch build output
|
||||||
|
**/*.HTMLClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/ModelManifest.xml
|
||||||
|
**/*.Server/GeneratedArtifacts
|
||||||
|
**/*.Server/ModelManifest.xml
|
||||||
|
_Pvt_Extensions
|
||||||
|
|
||||||
|
# Paket dependency manager
|
||||||
|
.paket/paket.exe
|
||||||
|
|
||||||
|
# FAKE - F# Make
|
||||||
|
.fake/
|
||||||
40
DotNetMashup.sln
Normal file
40
DotNetMashup.sln
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 14
|
||||||
|
VisualStudioVersion = 14.0.23107.0
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{67290B97-2478-46D3-9D10-87A0B89A03C2}"
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8610EB85-922A-40CE-AB4B-355048BFC7D2}"
|
||||||
|
ProjectSection(SolutionItems) = preProject
|
||||||
|
global.json = global.json
|
||||||
|
NuGet.Config = NuGet.Config
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "DotNetMashup", "src\DotNetMashup\DotNetMashup.xproj", "{E68542EE-79D4-47A1-BC66-BFB4B78856A1}"
|
||||||
|
EndProject
|
||||||
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "DotNetMashup.Web", "src\DotNetMashup.Web\DotNetMashup.Web.xproj", "{53E3E5AF-13BF-465D-89E8-B68E4CCC4D7E}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{E68542EE-79D4-47A1-BC66-BFB4B78856A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{E68542EE-79D4-47A1-BC66-BFB4B78856A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{E68542EE-79D4-47A1-BC66-BFB4B78856A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{E68542EE-79D4-47A1-BC66-BFB4B78856A1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{53E3E5AF-13BF-465D-89E8-B68E4CCC4D7E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{53E3E5AF-13BF-465D-89E8-B68E4CCC4D7E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{53E3E5AF-13BF-465D-89E8-B68E4CCC4D7E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{53E3E5AF-13BF-465D-89E8-B68E4CCC4D7E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(NestedProjects) = preSolution
|
||||||
|
{E68542EE-79D4-47A1-BC66-BFB4B78856A1} = {67290B97-2478-46D3-9D10-87A0B89A03C2}
|
||||||
|
{53E3E5AF-13BF-465D-89E8-B68E4CCC4D7E} = {67290B97-2478-46D3-9D10-87A0B89A03C2}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
8
NuGet.Config
Normal file
8
NuGet.Config
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<configuration>
|
||||||
|
<packageSources>
|
||||||
|
<!--To inherit the global NuGet package sources remove the <clear/> line below -->
|
||||||
|
<clear />
|
||||||
|
<add key="api.nuget.org" value="https://api.nuget.org/v3/index.json" />
|
||||||
|
</packageSources>
|
||||||
|
</configuration>
|
||||||
6
global.json
Normal file
6
global.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"projects": [ "src", "test" ],
|
||||||
|
"sdk": {
|
||||||
|
"version": "1.0.0-beta7"
|
||||||
|
}
|
||||||
|
}
|
||||||
3
src/DotNetMashup.Web/.bowerrc
Normal file
3
src/DotNetMashup.Web/.bowerrc
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"directory": "wwwroot/lib"
|
||||||
|
}
|
||||||
44
src/DotNetMashup.Web/Controllers/HomeController.cs
Normal file
44
src/DotNetMashup.Web/Controllers/HomeController.cs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using DotNetMashup.Web.Factories;
|
||||||
|
using Microsoft.AspNet.Mvc;
|
||||||
|
|
||||||
|
namespace DotNetMashup.Web.Controllers
|
||||||
|
{
|
||||||
|
public class HomeController : Controller
|
||||||
|
{
|
||||||
|
private readonly BlogPostFactory factory;
|
||||||
|
|
||||||
|
public HomeController(BlogPostFactory factory)
|
||||||
|
{
|
||||||
|
this.factory = factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IActionResult Index()
|
||||||
|
{
|
||||||
|
var data = factory.GetData();
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IActionResult About()
|
||||||
|
{
|
||||||
|
ViewData["Message"] = "Your application description page.";
|
||||||
|
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IActionResult Contact()
|
||||||
|
{
|
||||||
|
ViewData["Message"] = "Your contact page.";
|
||||||
|
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IActionResult Error()
|
||||||
|
{
|
||||||
|
return View("~/Views/Shared/Error.cshtml");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
19
src/DotNetMashup.Web/DotNetMashup.Web.xproj
Normal file
19
src/DotNetMashup.Web/DotNetMashup.Web.xproj
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>53e3e5af-13bf-465d-89e8-b68e4ccc4d7e</ProjectGuid>
|
||||||
|
<RootNamespace>DotNetMashup.Web</RootNamespace>
|
||||||
|
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||||
|
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
<DevelopmentServerPort>59713</DevelopmentServerPort>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
</Project>
|
||||||
169
src/DotNetMashup.Web/Extensions/StringHtmlExtension.cs
Normal file
169
src/DotNetMashup.Web/Extensions/StringHtmlExtension.cs
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
//This code came from https://raw.githubusercontent.com/robvolk/Helpers.Net/master/Src/Helpers.Net/StringHtmlExtensions.cs
|
||||||
|
|
||||||
|
namespace DotNetMashup.Web.Extensions
|
||||||
|
{
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
public static class StringHtmlExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Truncates a string containing HTML to a number of text characters, keeping whole words.
|
||||||
|
/// The result contains HTML and any tags left open are closed.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="s"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string TruncateHtml(this string html, int maxCharacters, string trailingText)
|
||||||
|
{
|
||||||
|
if(string.IsNullOrEmpty(html))
|
||||||
|
return html;
|
||||||
|
|
||||||
|
// find the spot to truncate
|
||||||
|
// count the text characters and ignore tags
|
||||||
|
var textCount = 0;
|
||||||
|
var charCount = 0;
|
||||||
|
var ignore = false;
|
||||||
|
foreach(char c in html)
|
||||||
|
{
|
||||||
|
charCount++;
|
||||||
|
if(c == '<')
|
||||||
|
ignore = true;
|
||||||
|
else if(!ignore)
|
||||||
|
textCount++;
|
||||||
|
|
||||||
|
if(c == '>')
|
||||||
|
ignore = false;
|
||||||
|
|
||||||
|
// stop once we hit the limit
|
||||||
|
if(textCount >= maxCharacters)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Truncate the html and keep whole words only
|
||||||
|
var trunc = new StringBuilder(html.TruncateWords(charCount));
|
||||||
|
|
||||||
|
// keep track of open tags and close any tags left open
|
||||||
|
var tags = new Stack<string>();
|
||||||
|
var matches = Regex.Matches(trunc.ToString(),
|
||||||
|
@"<((?<tag>[^\s/>]+)|/(?<closeTag>[^\s>]+)).*?(?<selfClose>/)?\s*>",
|
||||||
|
RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Multiline);
|
||||||
|
|
||||||
|
foreach(Match match in matches)
|
||||||
|
{
|
||||||
|
if(match.Success)
|
||||||
|
{
|
||||||
|
var tag = match.Groups["tag"].Value;
|
||||||
|
var closeTag = match.Groups["closeTag"].Value;
|
||||||
|
|
||||||
|
// push to stack if open tag and ignore it if it is self-closing, i.e. <br />
|
||||||
|
if(!string.IsNullOrEmpty(tag) && string.IsNullOrEmpty(match.Groups["selfClose"].Value))
|
||||||
|
tags.Push(tag);
|
||||||
|
|
||||||
|
// pop from stack if close tag
|
||||||
|
else if(!string.IsNullOrEmpty(closeTag))
|
||||||
|
{
|
||||||
|
// pop the tag to close it.. find the matching opening tag
|
||||||
|
// ignore any unclosed tags
|
||||||
|
while(tags.Pop() != closeTag && tags.Count > 0)
|
||||||
|
{ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(html.Length > charCount)
|
||||||
|
// add the trailing text
|
||||||
|
trunc.Append(trailingText);
|
||||||
|
|
||||||
|
// pop the rest off the stack to close remainder of tags
|
||||||
|
while(tags.Count > 0)
|
||||||
|
{
|
||||||
|
trunc.Append("</");
|
||||||
|
trunc.Append(tags.Pop());
|
||||||
|
trunc.Append('>');
|
||||||
|
}
|
||||||
|
|
||||||
|
return trunc.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Truncates a string containing HTML to a number of text characters, keeping whole words.
|
||||||
|
/// The result contains HTML and any tags left open are closed.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="s"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string TruncateHtml(this string html, int maxCharacters)
|
||||||
|
{
|
||||||
|
return html.TruncateHtml(maxCharacters, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Strips all HTML tags from a string
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="s"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string StripHtml(this string html)
|
||||||
|
{
|
||||||
|
if(string.IsNullOrEmpty(html))
|
||||||
|
return html;
|
||||||
|
|
||||||
|
return Regex.Replace(html, @"<(.|\n)*?>", string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Truncates text to a number of characters
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text"></param>
|
||||||
|
/// <param name="maxCharacters"></param>
|
||||||
|
/// <param name="trailingText"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string Truncate(this string text, int maxCharacters)
|
||||||
|
{
|
||||||
|
return text.Truncate(maxCharacters, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Truncates text to a number of characters and adds trailing text, i.e. elipses, to the end
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text"></param>
|
||||||
|
/// <param name="maxCharacters"></param>
|
||||||
|
/// <param name="trailingText"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string Truncate(this string text, int maxCharacters, string trailingText)
|
||||||
|
{
|
||||||
|
if(string.IsNullOrEmpty(text) || maxCharacters <= 0 || text.Length <= maxCharacters)
|
||||||
|
return text;
|
||||||
|
else
|
||||||
|
return text.Substring(0, maxCharacters) + trailingText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Truncates text and discars any partial words left at the end
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text"></param>
|
||||||
|
/// <param name="maxCharacters"></param>
|
||||||
|
/// <param name="trailingText"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string TruncateWords(this string text, int maxCharacters)
|
||||||
|
{
|
||||||
|
return text.TruncateWords(maxCharacters, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Truncates text and discars any partial words left at the end
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text"></param>
|
||||||
|
/// <param name="maxCharacters"></param>
|
||||||
|
/// <param name="trailingText"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string TruncateWords(this string text, int maxCharacters, string trailingText)
|
||||||
|
{
|
||||||
|
if(string.IsNullOrEmpty(text) || maxCharacters <= 0 || text.Length <= maxCharacters)
|
||||||
|
return text;
|
||||||
|
|
||||||
|
// trunctate the text, then remove the partial word at the end
|
||||||
|
return Regex.Replace(text.Truncate(maxCharacters),
|
||||||
|
@"\s+[^\s]+$", string.Empty, RegexOptions.IgnoreCase | RegexOptions.Compiled) + trailingText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
151
src/DotNetMashup.Web/Factories/BlogPostFactory.cs
Normal file
151
src/DotNetMashup.Web/Factories/BlogPostFactory.cs
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.ServiceModel.Syndication;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml;
|
||||||
|
using DotNetMashup.Web.Extensions;
|
||||||
|
using DotNetMashup.Web.Global;
|
||||||
|
using DotNetMashup.Web.Model;
|
||||||
|
using Microsoft.Framework.Caching.Memory;
|
||||||
|
|
||||||
|
namespace DotNetMashup.Web.Factories
|
||||||
|
{
|
||||||
|
public class BlogPostFactory : IFactory
|
||||||
|
{
|
||||||
|
private readonly ISiteSetting setting;
|
||||||
|
|
||||||
|
private readonly IMemoryCache cache;
|
||||||
|
private readonly IEnumerable<MetaData> _data;
|
||||||
|
private const string cacheKey = "blogposts";
|
||||||
|
|
||||||
|
public BlogPostFactory(IEnumerable<MetaData> data, IMemoryCache cache, ISiteSetting setting)
|
||||||
|
{
|
||||||
|
this._data = data;
|
||||||
|
this.cache = cache;
|
||||||
|
this.setting = setting;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string FactoryName
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return "BlogPost";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<IExternalData> GetData()
|
||||||
|
{
|
||||||
|
var cachedata = cache.Get<IEnumerable<IExternalData>>(cacheKey);
|
||||||
|
if(cachedata != null) return cachedata;
|
||||||
|
var syndicationFeeds = GetSyndicationFeeds(_data);
|
||||||
|
|
||||||
|
var data = syndicationFeeds
|
||||||
|
.SelectMany(pair => pair.Value.Items, (pair, item) => new { Id = pair.Key, Item = item })
|
||||||
|
.Where(x => x.Item.Categories.Any(category => setting.Categories.Any(setting => string.Equals(setting, category.Name, StringComparison.OrdinalIgnoreCase))))
|
||||||
|
.Select(x =>
|
||||||
|
{
|
||||||
|
var metaauthor = _data.First(y => y.Id == x.Id);
|
||||||
|
var authorname = metaauthor.Author;
|
||||||
|
var authoremail = metaauthor.AuthorEmail;
|
||||||
|
|
||||||
|
var link = x.Item.Links.FirstOrDefault(y => y.RelationshipType == "alternate");
|
||||||
|
var locallink = string.Empty;
|
||||||
|
if(link != null)
|
||||||
|
{
|
||||||
|
locallink = link.Uri.Segments.Last();
|
||||||
|
if(locallink.Contains("."))
|
||||||
|
{
|
||||||
|
locallink = locallink.Substring(0, locallink.IndexOf(".", System.StringComparison.Ordinal));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var originallink = link == null ? string.Empty : link.Uri.AbsoluteUri;
|
||||||
|
|
||||||
|
var summary = x.Item.Summary == null
|
||||||
|
? ((TextSyndicationContent)x.Item.Content).Text
|
||||||
|
: x.Item.Summary.Text;
|
||||||
|
|
||||||
|
var truncatedSummary = summary.TruncateHtml(700, "");
|
||||||
|
|
||||||
|
var encodedcontent = x.Item.ElementExtensions.ReadElementExtensions<string>("encoded",
|
||||||
|
"http://purl.org/rss/1.0/modules/content/");
|
||||||
|
|
||||||
|
var content = string.Empty;
|
||||||
|
|
||||||
|
if(encodedcontent.Any())
|
||||||
|
{
|
||||||
|
content = encodedcontent.First();
|
||||||
|
}
|
||||||
|
else if(x.Item.Content != null)
|
||||||
|
{
|
||||||
|
content = ((TextSyndicationContent)x.Item.Content).Text;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
content = summary;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new BlogPost
|
||||||
|
{
|
||||||
|
Title = x.Item.Title.Text,
|
||||||
|
Summary = truncatedSummary,
|
||||||
|
Author = authorname,
|
||||||
|
AuthorEmail = authoremail,
|
||||||
|
Localink = locallink,
|
||||||
|
OriginalLink = originallink,
|
||||||
|
PublishedDate = x.Item.PublishDate.DateTime,
|
||||||
|
Content = content
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.OrderByDescending(x => x.PublishedDate)
|
||||||
|
.ToList();
|
||||||
|
cache.Set(cacheKey, data.Cast<IExternalData>());
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<KeyValuePair<string, SyndicationFeed>> GetSyndicationFeeds(IEnumerable<MetaData> metadataEntries)
|
||||||
|
{
|
||||||
|
var syndicationFeeds = new List<KeyValuePair<string, SyndicationFeed>>();
|
||||||
|
foreach(var metadata in metadataEntries)
|
||||||
|
{
|
||||||
|
GetFeed(metadata.FeedUrl, metadata.Id, syndicationFeeds);
|
||||||
|
}
|
||||||
|
|
||||||
|
return syndicationFeeds;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void GetFeed(string url, string id, List<KeyValuePair<string, SyndicationFeed>> syndicationFeeds)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SyndicationFeed feed = null;
|
||||||
|
using(var reader = XmlReader.Create(url))
|
||||||
|
{
|
||||||
|
feed = SyndicationFeed.Load(reader);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(feed != null)
|
||||||
|
{
|
||||||
|
syndicationFeeds.Add(new KeyValuePair<string, SyndicationFeed>(id, feed));
|
||||||
|
if(feed.Links.Any(x => x.RelationshipType == "next"))
|
||||||
|
{
|
||||||
|
foreach(var pagingLink in feed.Links.Where(x => x.RelationshipType == "next"))
|
||||||
|
{
|
||||||
|
GetFeed(pagingLink.Uri.AbsoluteUri, id, syndicationFeeds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(WebException)
|
||||||
|
{
|
||||||
|
//Unable to load RSS feed
|
||||||
|
}
|
||||||
|
catch(XmlException)
|
||||||
|
{
|
||||||
|
//Unable to load RSS feed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/DotNetMashup.Web/Factories/IFactory.cs
Normal file
15
src/DotNetMashup.Web/Factories/IFactory.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using DotNetMashup.Web.Model;
|
||||||
|
|
||||||
|
namespace DotNetMashup.Web.Factories
|
||||||
|
{
|
||||||
|
public interface IFactory
|
||||||
|
{
|
||||||
|
string FactoryName { get; }
|
||||||
|
|
||||||
|
IEnumerable<IExternalData> GetData();
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/DotNetMashup.Web/Global/ISiteSetting.cs
Normal file
12
src/DotNetMashup.Web/Global/ISiteSetting.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DotNetMashup.Web.Global
|
||||||
|
{
|
||||||
|
public interface ISiteSetting
|
||||||
|
{
|
||||||
|
List<string> Categories { get; }
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/DotNetMashup.Web/Global/SiteSettings.cs
Normal file
12
src/DotNetMashup.Web/Global/SiteSettings.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DotNetMashup.Web.Global
|
||||||
|
{
|
||||||
|
public class SiteSettings : ISiteSetting
|
||||||
|
{
|
||||||
|
public List<string> Categories { get; } = new List<string> { "c#", "csharp", "cs", "asp.net", "NancyFx", "Nancy", "vNext", "asp.net 5" };
|
||||||
|
}
|
||||||
|
}
|
||||||
19
src/DotNetMashup.Web/Model/BlogPost.cs
Normal file
19
src/DotNetMashup.Web/Model/BlogPost.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DotNetMashup.Web.Model
|
||||||
|
{
|
||||||
|
public class BlogPost : IExternalData
|
||||||
|
{
|
||||||
|
public string Title { get; set; }
|
||||||
|
public string Content { get; set; }
|
||||||
|
public DateTime PublishedDate { get; set; }
|
||||||
|
public string Summary { get; set; }
|
||||||
|
public string Localink { get; set; }
|
||||||
|
public string OriginalLink { get; set; }
|
||||||
|
public string Author { get; set; }
|
||||||
|
public string AuthorEmail { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/DotNetMashup.Web/Model/IExternalData.cs
Normal file
15
src/DotNetMashup.Web/Model/IExternalData.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DotNetMashup.Web.Model
|
||||||
|
{
|
||||||
|
public interface IExternalData
|
||||||
|
{
|
||||||
|
string Title { get; set; }
|
||||||
|
string Content { get; set; }
|
||||||
|
string OriginalLink { get; set; }
|
||||||
|
string Author { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/DotNetMashup.Web/Model/IFeedData.cs
Normal file
16
src/DotNetMashup.Web/Model/IFeedData.cs
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DotNetMashup.Web.Model
|
||||||
|
{
|
||||||
|
public interface IFeedData
|
||||||
|
{
|
||||||
|
string FeedUrl { get; set; }
|
||||||
|
string Author { get; set; }
|
||||||
|
string AuthorEmail { get; set; }
|
||||||
|
string GravatarUrl { get; set; }
|
||||||
|
string Id { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/DotNetMashup.Web/Model/MetaData.cs
Normal file
12
src/DotNetMashup.Web/Model/MetaData.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
namespace DotNetMashup.Web.Model
|
||||||
|
{
|
||||||
|
//stolen idea from: https://github.com/NancyFx/Nancy.Blog/blob/master/src/Nancy.Blog/Model/MetaData.cs
|
||||||
|
public class MetaData : IFeedData
|
||||||
|
{
|
||||||
|
public string FeedUrl { get; set; }
|
||||||
|
public string Author { get; set; }
|
||||||
|
public string AuthorEmail { get; set; }
|
||||||
|
public string GravatarUrl { get; set; }
|
||||||
|
public string Id { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
203
src/DotNetMashup.Web/Project_Readme.html
Normal file
203
src/DotNetMashup.Web/Project_Readme.html
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>Welcome to ASP.NET 5</title>
|
||||||
|
<style>
|
||||||
|
html {
|
||||||
|
background: #f1f1f1;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: #fff;
|
||||||
|
color: #505050;
|
||||||
|
font: 14px 'Segoe UI', tahoma, arial, helvetica, sans-serif;
|
||||||
|
margin: 1%;
|
||||||
|
min-height: 95.5%;
|
||||||
|
border: 1px solid silver;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header h1 {
|
||||||
|
font-size: 44px;
|
||||||
|
font-weight: normal;
|
||||||
|
margin: 0;
|
||||||
|
padding: 10px 30px 10px 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header span {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 30px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header p {
|
||||||
|
font-size: 20px;
|
||||||
|
color: #fff;
|
||||||
|
background: #007acc;
|
||||||
|
padding: 0 30px;
|
||||||
|
line-height: 50px;
|
||||||
|
margin-top: 25px;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#header p a {
|
||||||
|
color: #fff;
|
||||||
|
text-decoration: underline;
|
||||||
|
font-weight: bold;
|
||||||
|
padding-right: 35px;
|
||||||
|
background: no-repeat right bottom url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAWCAMAAAAcqPc3AAAANlBMVEUAAAAAeswfitI9mthXp91us+KCvuaTx+mjz+2x1u+83PLH4vTR5/ba7Pjj8Pns9fv1+v3////wy3dWAAAAAXRSTlMAQObYZgAAAHxJREFUeNp9kVcSwCAIRMHUYoH7XzaxOxJ9P8oyQ1uIqNPwh3s2aLmIM2YtqrLcQIeQEylhuCeUOlhgve5yoBCfWmlnlgkN4H8ykbpaE7gR03AbUHiwoOxUH9Xp+ubd41p1HF3mBPrfC87BHeTdaB3ceeKL9HGpcvX9zu6+DdMWT9KQPvYAAAAASUVORK5CYII=);
|
||||||
|
}
|
||||||
|
|
||||||
|
#main {
|
||||||
|
padding: 5px 30px;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
width: 21.7%;
|
||||||
|
float: left;
|
||||||
|
margin: 0 0 0 4%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section h2 {
|
||||||
|
font-size: 13px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
margin: 0;
|
||||||
|
border-bottom: 1px solid silver;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section.first {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section.first h2 {
|
||||||
|
font-size: 24px;
|
||||||
|
text-transform: none;
|
||||||
|
margin-bottom: 25px;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section.first li {
|
||||||
|
border-top: 1px solid silver;
|
||||||
|
padding: 8px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section.last {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
padding: 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #267cb2;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
#footer {
|
||||||
|
clear: both;
|
||||||
|
padding-top: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#footer p {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 10px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div id="header">
|
||||||
|
<h1>Welcome to ASP.NET 5 Preview</h1>
|
||||||
|
<span>
|
||||||
|
We've made some big updates in this release, so it’s <b>important</b> that you spend
|
||||||
|
a few minutes to learn what’s new.
|
||||||
|
<br /><br />
|
||||||
|
ASP.NET 5 has been rearchitected to make it <b>lean</b> and <b>composable</b>. It's fully
|
||||||
|
<b>open source</b> and available on <a href="http://go.microsoft.com/fwlink/?LinkID=517854">GitHub</a>.
|
||||||
|
<br />
|
||||||
|
Your new project automatically takes advantage of modern client-side utilities
|
||||||
|
like <a href="http://go.microsoft.com/fwlink/?LinkId=518004">Bower</a> and <a href="http://go.microsoft.com/fwlink/?LinkId=518005">npm</a>
|
||||||
|
(to add client-side libraries) and <a href="http://go.microsoft.com/fwlink/?LinkId=518007">Gulp</a> (for client-side build and automation tasks).
|
||||||
|
|
||||||
|
<br /><br />
|
||||||
|
We hope you enjoy the new capabilities in ASP.NET 5 and Visual Studio 2015.
|
||||||
|
<br />
|
||||||
|
The ASP.NET Team
|
||||||
|
</span>
|
||||||
|
<p>You've created a new ASP.NET 5 project. <a href="http://go.microsoft.com/fwlink/?LinkId=518016">Learn what's new</a></p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="main">
|
||||||
|
<div class="section first">
|
||||||
|
<h2>This application consists of:</h2>
|
||||||
|
<ul>
|
||||||
|
<li>Sample pages using ASP.NET MVC 6</li>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkId=518007">Gulp</a> and <a href="http://go.microsoft.com/fwlink/?LinkId=518004">Bower</a> for managing client-side resources</li>
|
||||||
|
<li>Theming using <a href="http://go.microsoft.com/fwlink/?LinkID=398939">Bootstrap</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<h2>New concepts</h2>
|
||||||
|
<ul>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkId=518008">The 'wwwroot' explained</a></li>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkId=518012">Configuration in ASP.NET 5</a></li>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkId=518013">Dependency Injection</a></li>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkId=518014">Razor TagHelpers</a></li>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkID=517849">Manage client tasks using Gulp</a></li>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkID=517850">Develop on different platforms</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section">
|
||||||
|
<h2>Customize app</h2>
|
||||||
|
<ul>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkID=398600">Add Controllers and Views</a></li>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkID=398602">Add Data using EntityFramework</a></li>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkID=398603">Add Authentication using Identity</a></li>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkID=398606">Add real time support using SignalR</a></li>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkID=398604">Add Class library</a></li>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkId=518009">Add Web APIs with MVC 6</a></li>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkID=517848">Add client packages using Bower</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="section last">
|
||||||
|
<h2>Deploy</h2>
|
||||||
|
<ul>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkID=517851">Run your app locally</a></li>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkID=517852">Run your app on ASP.NET Core 5</a></li>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkID=517853">Run commands in your project.json</a></li>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkID=398609">Publish to Microsoft Azure Web Sites</a></li>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkId=518019">Publish to the file system</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="footer">
|
||||||
|
<p>We would love to hear your <a href="http://go.microsoft.com/fwlink/?LinkId=518015">feedback</a></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
91
src/DotNetMashup.Web/Startup.cs
Normal file
91
src/DotNetMashup.Web/Startup.cs
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using DotNetMashup.Web.Factories;
|
||||||
|
using DotNetMashup.Web.Global;
|
||||||
|
using DotNetMashup.Web.Model;
|
||||||
|
using Microsoft.AspNet.Builder;
|
||||||
|
using Microsoft.AspNet.Hosting;
|
||||||
|
using Microsoft.Dnx.Runtime;
|
||||||
|
using Microsoft.Framework.Caching.Memory;
|
||||||
|
using Microsoft.Framework.Configuration;
|
||||||
|
using Microsoft.Framework.DependencyInjection;
|
||||||
|
using Microsoft.Framework.Logging;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace DotNetMashup.Web
|
||||||
|
{
|
||||||
|
public class Startup
|
||||||
|
{
|
||||||
|
private IEnumerable<MetaData> _feedData = null;
|
||||||
|
|
||||||
|
public Startup(IHostingEnvironment env, IApplicationEnvironment appEnv)
|
||||||
|
{
|
||||||
|
// Setup configuration sources.
|
||||||
|
var builder = new ConfigurationBuilder(appEnv.ApplicationBasePath)
|
||||||
|
.AddJsonFile("config.json")
|
||||||
|
.AddEnvironmentVariables();
|
||||||
|
Configuration = builder.Build();
|
||||||
|
_feedData = JsonConvert.DeserializeObject<IEnumerable<MetaData>>(File.ReadAllText(Path.Combine(appEnv.ApplicationBasePath, "blogfeed.json")));
|
||||||
|
}
|
||||||
|
|
||||||
|
public IConfigurationRoot Configuration { get; set; }
|
||||||
|
|
||||||
|
// This method gets called by the runtime.
|
||||||
|
public void ConfigureServices(IServiceCollection services)
|
||||||
|
{
|
||||||
|
services.AddSingleton<ISiteSetting>(prov =>
|
||||||
|
{
|
||||||
|
return new SiteSettings();
|
||||||
|
});
|
||||||
|
services.AddSingleton<IMemoryCache>((provider) =>
|
||||||
|
{
|
||||||
|
return new MemoryCache(new MemoryCacheOptions());
|
||||||
|
});
|
||||||
|
services.AddInstance(_feedData);
|
||||||
|
services.AddSingleton<BlogPostFactory>();
|
||||||
|
// Add MVC services to the services container.
|
||||||
|
services.AddMvc();
|
||||||
|
|
||||||
|
// Uncomment the following line to add Web API services which makes it easier to port Web API 2 controllers.
|
||||||
|
// You will also need to add the Microsoft.AspNet.Mvc.WebApiCompatShim package to the 'dependencies' section of project.json.
|
||||||
|
// services.AddWebApiConventions();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure is called after ConfigureServices is called.
|
||||||
|
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
|
||||||
|
{
|
||||||
|
loggerFactory.MinimumLevel = LogLevel.Information;
|
||||||
|
loggerFactory.AddConsole();
|
||||||
|
loggerFactory.AddDebug();
|
||||||
|
|
||||||
|
// Configure the HTTP request pipeline.
|
||||||
|
|
||||||
|
// Add the following to the request pipeline only in development environment.
|
||||||
|
if(env.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseBrowserLink();
|
||||||
|
app.UseErrorPage();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Add Error handling middleware which catches all application specific errors and
|
||||||
|
// send the request to the following path or controller action.
|
||||||
|
app.UseErrorHandler("/Home/Error");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add static files to the request pipeline.
|
||||||
|
app.UseStaticFiles();
|
||||||
|
|
||||||
|
// Add MVC to the request pipeline.
|
||||||
|
app.UseMvc(routes =>
|
||||||
|
{
|
||||||
|
routes.MapRoute(
|
||||||
|
name: "default",
|
||||||
|
template: "{controller=Home}/{action=Index}/{id?}");
|
||||||
|
|
||||||
|
// Uncomment the following line to add a route for porting Web API 2 controllers.
|
||||||
|
// routes.MapWebApiRoute("DefaultApi", "api/{controller}/{id?}");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/DotNetMashup.Web/Views/Home/About.cshtml
Normal file
7
src/DotNetMashup.Web/Views/Home/About.cshtml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
@{
|
||||||
|
ViewData["Title"] = "About";
|
||||||
|
}
|
||||||
|
<h2>@ViewData["Title"].</h2>
|
||||||
|
<h3>@ViewData["Message"]</h3>
|
||||||
|
|
||||||
|
<p>Use this area to provide additional information.</p>
|
||||||
17
src/DotNetMashup.Web/Views/Home/Contact.cshtml
Normal file
17
src/DotNetMashup.Web/Views/Home/Contact.cshtml
Normal file
@@ -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>
|
||||||
104
src/DotNetMashup.Web/Views/Home/Index.cshtml
Normal file
104
src/DotNetMashup.Web/Views/Home/Index.cshtml
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
@{
|
||||||
|
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/ASP-NET-Banners-01.png" alt="ASP.NET" class="img-responsive" />
|
||||||
|
<div class="container">
|
||||||
|
<div class="carousel-caption">
|
||||||
|
<p>
|
||||||
|
Learn how to build ASP.NET apps that can run anywhere.
|
||||||
|
<a class="btn btn-default btn-default" href="http://go.microsoft.com/fwlink/?LinkID=525028&clcid=0x409">
|
||||||
|
Learn More
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<img src="~/images/Banner-02-VS.png" alt="Visual Studio" class="img-responsive" />
|
||||||
|
<div class="container">
|
||||||
|
<div class="carousel-caption">
|
||||||
|
<p>
|
||||||
|
There are powerful new features in Visual Studio for building modern web apps.
|
||||||
|
<a class="btn btn-default btn-default" href="http://go.microsoft.com/fwlink/?LinkID=525030&clcid=0x409">
|
||||||
|
Learn More
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<img src="~/images/ASP-NET-Banners-02.png" alt="Package Management" class="img-responsive" />
|
||||||
|
<div class="container">
|
||||||
|
<div class="carousel-caption">
|
||||||
|
<p>
|
||||||
|
Bring in libraries from NuGet, Bower, and npm, and automate tasks using Grunt or Gulp.
|
||||||
|
<a class="btn btn-default btn-default" href="http://go.microsoft.com/fwlink/?LinkID=525029&clcid=0x409">
|
||||||
|
Learn More
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item">
|
||||||
|
<img src="~/images/Banner-01-Azure.png" alt="Microsoft Azure" class="img-responsive" />
|
||||||
|
<div class="container">
|
||||||
|
<div class="carousel-caption">
|
||||||
|
<p>
|
||||||
|
Learn how Microsoft's Azure cloud platform allows you to build, deploy, and scale web apps.
|
||||||
|
<a class="btn btn-default btn-default" href="http://go.microsoft.com/fwlink/?LinkID=525027&clcid=0x409">
|
||||||
|
Learn More
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-3">
|
||||||
|
<h2>Application uses</h2>
|
||||||
|
<ul>
|
||||||
|
<li>Sample pages using ASP.NET 5 (MVC 6)</li>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkId=518007">Gulp</a> and <a href="http://go.microsoft.com/fwlink/?LinkId=518004">Bower</a> for managing client-side resources</li>
|
||||||
|
<li>Theming using <a href="http://go.microsoft.com/fwlink/?LinkID=398939">Bootstrap</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<h2>New concepts</h2>
|
||||||
|
<ul>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkId=518008">Conceptual overview of ASP.NET 5</a></li>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkId=518008">Fundamentals in ASP.NET 5</a></li>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkID=517849">Client-Side Development using npm, Bower and Gulp</a></li>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkID=517850">Develop on different platforms</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<h2>Customize app</h2>
|
||||||
|
<ul>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkID=398600">Add Controllers and Views</a></li>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkID=398602">Add Data using EntityFramework</a></li>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkID=398603">Add Authentication using Identity</a></li>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkID=517848">Manage client-side packages using Bower/ Gulp</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<h2>Deploy</h2>
|
||||||
|
<ul>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkID=517851">Run your app locally</a></li>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkID=517852">Run your app on .NET Core</a></li>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkID=517853">Run commands in your app</a></li>
|
||||||
|
<li><a href="http://go.microsoft.com/fwlink/?LinkID=398609">Publish to Microsoft Azure Web Apps</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
6
src/DotNetMashup.Web/Views/Shared/Error.cshtml
Normal file
6
src/DotNetMashup.Web/Views/Shared/Error.cshtml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
@{
|
||||||
|
ViewData["Title"] = "Error";
|
||||||
|
}
|
||||||
|
|
||||||
|
<h1 class="text-danger">Error.</h1>
|
||||||
|
<h2 class="text-danger">An error occurred while processing your request.</h2>
|
||||||
80
src/DotNetMashup.Web/Views/Shared/_Layout.cshtml
Normal file
80
src/DotNetMashup.Web/Views/Shared/_Layout.cshtml
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>@ViewData["Title"] - DotNetMashup.Web</title>
|
||||||
|
|
||||||
|
<environment names="Development">
|
||||||
|
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
|
||||||
|
<link rel="stylesheet" href="~/lib/bootstrap-touch-carousel/dist/css/bootstrap-touch-carousel.css" />
|
||||||
|
<link rel="stylesheet" href="~/css/site.css" />
|
||||||
|
</environment>
|
||||||
|
<environment names="Staging,Production">
|
||||||
|
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.0.0/css/bootstrap.min.css"
|
||||||
|
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
|
||||||
|
asp-fallback-test-class="hidden" asp-fallback-test-property="visibility" asp-fallback-test-value="hidden" />
|
||||||
|
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap-touch-carousel/0.8.0/css/bootstrap-touch-carousel.css"
|
||||||
|
asp-fallback-href="~/lib/bootstrap-touch-carousel/css/bootstrap-touch-carousel.css"
|
||||||
|
asp-fallback-test-class="carousel-caption" asp-fallback-test-property="display" asp-fallback-test-value="none" />
|
||||||
|
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
|
||||||
|
</environment>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div 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="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
<span class="icon-bar"></span>
|
||||||
|
</button>
|
||||||
|
<a asp-controller="Home" asp-action="Index" class="navbar-brand">DotNetMashup.Web</a>
|
||||||
|
</div>
|
||||||
|
<div class="navbar-collapse collapse">
|
||||||
|
<ul class="nav navbar-nav">
|
||||||
|
<li><a asp-controller="Home" asp-action="Index">Home</a></li>
|
||||||
|
<li><a asp-controller="Home" asp-action="About">About</a></li>
|
||||||
|
<li><a asp-controller="Home" asp-action="Contact">Contact</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="container body-content">
|
||||||
|
@RenderBody()
|
||||||
|
<hr />
|
||||||
|
<footer>
|
||||||
|
<p>© 2015 - DotNetMashup.Web</p>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<environment names="Development">
|
||||||
|
<script src="~/lib/jquery/dist/jquery.js"></script>
|
||||||
|
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
|
||||||
|
<script src="~/lib/hammer.js/hammer.js"></script>
|
||||||
|
<script src="~/lib/bootstrap-touch-carousel/dist/js/bootstrap-touch-carousel.js"></script>
|
||||||
|
<script src="~/js/site.js" asp-append-version="true"></script>
|
||||||
|
</environment>
|
||||||
|
<environment names="Staging,Production">
|
||||||
|
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.1.4.min.js"
|
||||||
|
asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
|
||||||
|
asp-fallback-test="window.jQuery">
|
||||||
|
</script>
|
||||||
|
<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.0.0/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">
|
||||||
|
</script>
|
||||||
|
<script src="https://ajax.aspnetcdn.com/ajax/hammer.js/2.0.4/hammer.min.js"
|
||||||
|
asp-fallback-src="~/lib/hammer.js/hammer.js"
|
||||||
|
asp-fallback-test="window.Hammer">
|
||||||
|
</script>
|
||||||
|
<script src="https://ajax.aspnetcdn.com/ajax/bootstrap-touch-carousel/0.8.0/js/bootstrap-touch-carousel.js"
|
||||||
|
asp-fallback-src="~/lib/bootstrap-touch-carousel/dist/js/bootstrap-touch-carousel.js"
|
||||||
|
asp-fallback-test="window.Hammer && window.Hammer.Instance">
|
||||||
|
</script>
|
||||||
|
<script src="~/js/site.js" asp-append-version="true"></script>
|
||||||
|
</environment>
|
||||||
|
|
||||||
|
@RenderSection("scripts", required: false)
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
2
src/DotNetMashup.Web/Views/_ViewImports.cshtml
Normal file
2
src/DotNetMashup.Web/Views/_ViewImports.cshtml
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
@using DotNetMashup.Web
|
||||||
|
@addTagHelper "*, Microsoft.AspNet.Mvc.TagHelpers"
|
||||||
3
src/DotNetMashup.Web/Views/_ViewStart.cshtml
Normal file
3
src/DotNetMashup.Web/Views/_ViewStart.cshtml
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
@{
|
||||||
|
Layout = "_Layout";
|
||||||
|
}
|
||||||
9
src/DotNetMashup.Web/blogfeed.json
Normal file
9
src/DotNetMashup.Web/blogfeed.json
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"id": "tparnell",
|
||||||
|
"feedurl": "https://blog.tommyparnell.com/rss/",
|
||||||
|
"author": "Tommy Parnell",
|
||||||
|
"authoremail": "tparnell8@gmail.com",
|
||||||
|
"gravatarurl": "http://www.gravatar.com/avatar/333e3cea32cd17ff2007d131df336061.png?s=128"
|
||||||
|
}
|
||||||
|
]
|
||||||
12
src/DotNetMashup.Web/bower.json
Normal file
12
src/DotNetMashup.Web/bower.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "ASP.NET",
|
||||||
|
"private": true,
|
||||||
|
"dependencies": {
|
||||||
|
"bootstrap": "3.0.0",
|
||||||
|
"bootstrap-touch-carousel": "0.8.0",
|
||||||
|
"hammer.js": "2.0.4",
|
||||||
|
"jquery": "2.1.4",
|
||||||
|
"jquery-validation": "1.11.1",
|
||||||
|
"jquery-validation-unobtrusive": "3.2.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/DotNetMashup.Web/config.json
Normal file
7
src/DotNetMashup.Web/config.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"Data": {
|
||||||
|
"DefaultConnection": {
|
||||||
|
"ConnectionString": "Server=(localdb)\\mssqllocaldb;Database=DotNetMashup;Trusted_Connection=True;MultipleActiveResultSets=true"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
45
src/DotNetMashup.Web/gulpfile.js
Normal file
45
src/DotNetMashup.Web/gulpfile.js
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/// <binding Clean='clean' />
|
||||||
|
|
||||||
|
var gulp = require("gulp"),
|
||||||
|
rimraf = require("rimraf"),
|
||||||
|
concat = require("gulp-concat"),
|
||||||
|
cssmin = require("gulp-cssmin"),
|
||||||
|
uglify = require("gulp-uglify"),
|
||||||
|
project = require("./project.json");
|
||||||
|
|
||||||
|
var paths = {
|
||||||
|
webroot: "./" + project.webroot + "/"
|
||||||
|
};
|
||||||
|
|
||||||
|
paths.js = paths.webroot + "js/**/*.js";
|
||||||
|
paths.minJs = paths.webroot + "js/**/*.min.js";
|
||||||
|
paths.css = paths.webroot + "css/**/*.css";
|
||||||
|
paths.minCss = paths.webroot + "css/**/*.min.css";
|
||||||
|
paths.concatJsDest = paths.webroot + "js/site.min.js";
|
||||||
|
paths.concatCssDest = paths.webroot + "css/site.min.css";
|
||||||
|
|
||||||
|
gulp.task("clean:js", function (cb) {
|
||||||
|
rimraf(paths.concatJsDest, cb);
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("clean:css", function (cb) {
|
||||||
|
rimraf(paths.concatCssDest, cb);
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("clean", ["clean:js", "clean:css"]);
|
||||||
|
|
||||||
|
gulp.task("min:js", function () {
|
||||||
|
gulp.src([paths.js, "!" + paths.minJs], { base: "." })
|
||||||
|
.pipe(concat(paths.concatJsDest))
|
||||||
|
.pipe(uglify())
|
||||||
|
.pipe(gulp.dest("."));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("min:css", function () {
|
||||||
|
gulp.src([paths.css, "!" + paths.minCss])
|
||||||
|
.pipe(concat(paths.concatCssDest))
|
||||||
|
.pipe(cssmin())
|
||||||
|
.pipe(gulp.dest("."));
|
||||||
|
});
|
||||||
|
|
||||||
|
gulp.task("min", ["min:js", "min:css"]);
|
||||||
2
src/DotNetMashup.Web/hosting.ini
Normal file
2
src/DotNetMashup.Web/hosting.ini
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
server=Microsoft.AspNet.Server.WebListener
|
||||||
|
server.urls=http://localhost:5000
|
||||||
11
src/DotNetMashup.Web/package.json
Normal file
11
src/DotNetMashup.Web/package.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "ASP.NET",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"devDependencies": {
|
||||||
|
"gulp": "3.8.11",
|
||||||
|
"gulp-concat": "2.5.2",
|
||||||
|
"gulp-cssmin": "0.1.7",
|
||||||
|
"gulp-uglify": "1.2.0",
|
||||||
|
"rimraf": "2.2.8"
|
||||||
|
}
|
||||||
|
}
|
||||||
48
src/DotNetMashup.Web/project.json
Normal file
48
src/DotNetMashup.Web/project.json
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
{
|
||||||
|
"webroot": "wwwroot",
|
||||||
|
"version": "1.0.0-*",
|
||||||
|
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.AspNet.Diagnostics": "1.0.0-beta7",
|
||||||
|
"Microsoft.AspNet.Mvc": "6.0.0-beta7",
|
||||||
|
"Microsoft.AspNet.Mvc.TagHelpers": "6.0.0-beta7",
|
||||||
|
"Microsoft.AspNet.Server.IIS": "1.0.0-beta7",
|
||||||
|
"Microsoft.AspNet.Server.WebListener": "1.0.0-beta7",
|
||||||
|
"Microsoft.AspNet.StaticFiles": "1.0.0-beta7",
|
||||||
|
"Microsoft.AspNet.Tooling.Razor": "1.0.0-beta7",
|
||||||
|
"Microsoft.Framework.Configuration.Json": "1.0.0-beta7",
|
||||||
|
"Microsoft.Framework.Logging": "1.0.0-beta7",
|
||||||
|
"Microsoft.Framework.Logging.Console": "1.0.0-beta7",
|
||||||
|
"Microsoft.Framework.Logging.Debug": "1.0.0-beta7",
|
||||||
|
"Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.0.0-beta7",
|
||||||
|
"Newtonsoft.Json": "7.0.1"
|
||||||
|
},
|
||||||
|
|
||||||
|
"commands": {
|
||||||
|
"web": "Microsoft.AspNet.Hosting --config hosting.ini"
|
||||||
|
},
|
||||||
|
|
||||||
|
"frameworks": {
|
||||||
|
"dnx451": {
|
||||||
|
"frameworkAssemblies": {
|
||||||
|
"System.ServiceModel": "4.0.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"exclude": [
|
||||||
|
"wwwroot",
|
||||||
|
"node_modules",
|
||||||
|
"bower_components"
|
||||||
|
],
|
||||||
|
"publishExclude": [
|
||||||
|
"node_modules",
|
||||||
|
"bower_components",
|
||||||
|
"**.xproj",
|
||||||
|
"**.user",
|
||||||
|
"**.vspscc"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"prepublish": [ "npm install", "bower install", "gulp clean", "gulp min" ]
|
||||||
|
}
|
||||||
|
}
|
||||||
20
src/DotNetMashup/DotNetMashup.xproj
Normal file
20
src/DotNetMashup/DotNetMashup.xproj
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
||||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>e68542ee-79d4-47a1-bc66-bfb4b78856a1</ProjectGuid>
|
||||||
|
<RootNamespace>DotNetMashup</RootNamespace>
|
||||||
|
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
||||||
|
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
</Project>
|
||||||
169
src/DotNetMashup/Extensions/StringHtmlExtension.cs
Normal file
169
src/DotNetMashup/Extensions/StringHtmlExtension.cs
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
//This code came from https://raw.githubusercontent.com/robvolk/Helpers.Net/master/Src/Helpers.Net/StringHtmlExtensions.cs
|
||||||
|
|
||||||
|
namespace DotNetMashup.Extensions
|
||||||
|
{
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
public static class StringHtmlExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Truncates a string containing HTML to a number of text characters, keeping whole words.
|
||||||
|
/// The result contains HTML and any tags left open are closed.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="s"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string TruncateHtml(this string html, int maxCharacters, string trailingText)
|
||||||
|
{
|
||||||
|
if(string.IsNullOrEmpty(html))
|
||||||
|
return html;
|
||||||
|
|
||||||
|
// find the spot to truncate
|
||||||
|
// count the text characters and ignore tags
|
||||||
|
var textCount = 0;
|
||||||
|
var charCount = 0;
|
||||||
|
var ignore = false;
|
||||||
|
foreach(char c in html)
|
||||||
|
{
|
||||||
|
charCount++;
|
||||||
|
if(c == '<')
|
||||||
|
ignore = true;
|
||||||
|
else if(!ignore)
|
||||||
|
textCount++;
|
||||||
|
|
||||||
|
if(c == '>')
|
||||||
|
ignore = false;
|
||||||
|
|
||||||
|
// stop once we hit the limit
|
||||||
|
if(textCount >= maxCharacters)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Truncate the html and keep whole words only
|
||||||
|
var trunc = new StringBuilder(html.TruncateWords(charCount));
|
||||||
|
|
||||||
|
// keep track of open tags and close any tags left open
|
||||||
|
var tags = new Stack<string>();
|
||||||
|
var matches = Regex.Matches(trunc.ToString(),
|
||||||
|
@"<((?<tag>[^\s/>]+)|/(?<closeTag>[^\s>]+)).*?(?<selfClose>/)?\s*>",
|
||||||
|
RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.Multiline);
|
||||||
|
|
||||||
|
foreach(Match match in matches)
|
||||||
|
{
|
||||||
|
if(match.Success)
|
||||||
|
{
|
||||||
|
var tag = match.Groups["tag"].Value;
|
||||||
|
var closeTag = match.Groups["closeTag"].Value;
|
||||||
|
|
||||||
|
// push to stack if open tag and ignore it if it is self-closing, i.e. <br />
|
||||||
|
if(!string.IsNullOrEmpty(tag) && string.IsNullOrEmpty(match.Groups["selfClose"].Value))
|
||||||
|
tags.Push(tag);
|
||||||
|
|
||||||
|
// pop from stack if close tag
|
||||||
|
else if(!string.IsNullOrEmpty(closeTag))
|
||||||
|
{
|
||||||
|
// pop the tag to close it.. find the matching opening tag
|
||||||
|
// ignore any unclosed tags
|
||||||
|
while(tags.Pop() != closeTag && tags.Count > 0)
|
||||||
|
{ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(html.Length > charCount)
|
||||||
|
// add the trailing text
|
||||||
|
trunc.Append(trailingText);
|
||||||
|
|
||||||
|
// pop the rest off the stack to close remainder of tags
|
||||||
|
while(tags.Count > 0)
|
||||||
|
{
|
||||||
|
trunc.Append("</");
|
||||||
|
trunc.Append(tags.Pop());
|
||||||
|
trunc.Append('>');
|
||||||
|
}
|
||||||
|
|
||||||
|
return trunc.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Truncates a string containing HTML to a number of text characters, keeping whole words.
|
||||||
|
/// The result contains HTML and any tags left open are closed.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="s"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string TruncateHtml(this string html, int maxCharacters)
|
||||||
|
{
|
||||||
|
return html.TruncateHtml(maxCharacters, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Strips all HTML tags from a string
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="s"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string StripHtml(this string html)
|
||||||
|
{
|
||||||
|
if(string.IsNullOrEmpty(html))
|
||||||
|
return html;
|
||||||
|
|
||||||
|
return Regex.Replace(html, @"<(.|\n)*?>", string.Empty);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Truncates text to a number of characters
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text"></param>
|
||||||
|
/// <param name="maxCharacters"></param>
|
||||||
|
/// <param name="trailingText"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string Truncate(this string text, int maxCharacters)
|
||||||
|
{
|
||||||
|
return text.Truncate(maxCharacters, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Truncates text to a number of characters and adds trailing text, i.e. elipses, to the end
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text"></param>
|
||||||
|
/// <param name="maxCharacters"></param>
|
||||||
|
/// <param name="trailingText"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string Truncate(this string text, int maxCharacters, string trailingText)
|
||||||
|
{
|
||||||
|
if(string.IsNullOrEmpty(text) || maxCharacters <= 0 || text.Length <= maxCharacters)
|
||||||
|
return text;
|
||||||
|
else
|
||||||
|
return text.Substring(0, maxCharacters) + trailingText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Truncates text and discars any partial words left at the end
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text"></param>
|
||||||
|
/// <param name="maxCharacters"></param>
|
||||||
|
/// <param name="trailingText"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string TruncateWords(this string text, int maxCharacters)
|
||||||
|
{
|
||||||
|
return text.TruncateWords(maxCharacters, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Truncates text and discars any partial words left at the end
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="text"></param>
|
||||||
|
/// <param name="maxCharacters"></param>
|
||||||
|
/// <param name="trailingText"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string TruncateWords(this string text, int maxCharacters, string trailingText)
|
||||||
|
{
|
||||||
|
if(string.IsNullOrEmpty(text) || maxCharacters <= 0 || text.Length <= maxCharacters)
|
||||||
|
return text;
|
||||||
|
|
||||||
|
// trunctate the text, then remove the partial word at the end
|
||||||
|
return Regex.Replace(text.Truncate(maxCharacters),
|
||||||
|
@"\s+[^\s]+$", string.Empty, RegexOptions.IgnoreCase | RegexOptions.Compiled) + trailingText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
19
src/DotNetMashup/Model/BlogPost.cs
Normal file
19
src/DotNetMashup/Model/BlogPost.cs
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace DotNetMashup.Model
|
||||||
|
{
|
||||||
|
public class BlogPost
|
||||||
|
{
|
||||||
|
public string Title { get; set; }
|
||||||
|
public string Content { get; set; }
|
||||||
|
public DateTime PublishedDate { get; set; }
|
||||||
|
public string Summary { get; set; }
|
||||||
|
public string Localink { get; set; }
|
||||||
|
public string OriginalLink { get; set; }
|
||||||
|
public string Author { get; set; }
|
||||||
|
public string AuthorEmail { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/DotNetMashup/Model/MetaData.cs
Normal file
12
src/DotNetMashup/Model/MetaData.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
namespace DotNetMashup
|
||||||
|
{
|
||||||
|
//stolen idea from: https://github.com/NancyFx/Nancy.Blog/blob/master/src/Nancy.Blog/Model/MetaData.cs
|
||||||
|
public class MetaData
|
||||||
|
{
|
||||||
|
public string FeedUrl { get; set; }
|
||||||
|
public string Author { get; set; }
|
||||||
|
public string AuthorEmail { get; set; }
|
||||||
|
public string GravatarUrl { get; set; }
|
||||||
|
public string Id { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
22
src/DotNetMashup/project.json
Normal file
22
src/DotNetMashup/project.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"version": "1.0.0-*",
|
||||||
|
"description": "DotNetMashup Class Library",
|
||||||
|
"authors": [ "Tommy Parnell" ],
|
||||||
|
"tags": [ "" ],
|
||||||
|
"projectUrl": "",
|
||||||
|
"licenseUrl": "",
|
||||||
|
|
||||||
|
"frameworks": {
|
||||||
|
"dnx451": { },
|
||||||
|
"dnxcore50": {
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.CSharp": "4.0.1-beta-23225",
|
||||||
|
"System.Collections": "4.0.11-beta-23225",
|
||||||
|
"System.Linq": "4.0.1-beta-23225",
|
||||||
|
"System.Runtime": "4.0.21-beta-23225",
|
||||||
|
"System.Threading": "4.0.11-beta-23225",
|
||||||
|
"System.Text.RegularExpressions": "4.0.11-beta-23225"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user