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