Skip to content

Instantly share code, notes, and snippets.

@ghuntley
Last active August 29, 2015 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ghuntley/50d40359eb5cf8559fb7 to your computer and use it in GitHub Desktop.
Save ghuntley/50d40359eb5cf8559fb7 to your computer and use it in GitHub Desktop.
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Net;
using System.Web;
using System.Web.Mvc;
using DevTrends.MvcDonutCaching;
using GhuntleyWeb.Services;
namespace GhuntleyWeb.Controllers
{
[RoutePrefix("blog")]
public class BlogController : Controller
{
public BlogController(IBlogPostService blogPostService)
{
Contract.Requires(blogPostService != null);
BlogPostService = blogPostService;
}
public IBlogPostService BlogPostService { get; private set; }
// GET: GetPost
[Route("", Name = "blog")]
[DonutOutputCache(CacheProfile = "OneDay")]
public ActionResult Index()
{
var posts = BlogPostService.GetPosts(10);
return View();
}
// GET: GetPost
[Route("{slug:maxlength(128)}", Name = "getpost")]
#if !DEBUG
[DonutOutputCache(CacheProfile = "OneDay")]
#endif
public ActionResult ViewBlogPost(string slug)
{
try
{
var post = BlogPostService.GetPost(slug);
return View(post);
}
catch (KeyNotFoundException ex)
{
throw new HttpException((int) HttpStatusCode.NotFound, slug);
}
}
}
}
using System.Net;
using System.Web.Mvc;
using DevTrends.MvcDonutCaching;
namespace GhuntleyWeb.Controllers
{
[RoutePrefix("error")]
public class ErrorController : Controller
{
/// <summary>
/// HTTP 404 Not Found
/// </summary>
[Route("notfound", Name = "notfound")]
[DonutOutputCache(CacheProfile = "OneDay")]
public ActionResult NotFound()
{
Response.StatusCode = (int) HttpStatusCode.NotFound;
return View();
}
/// <summary>
/// HTTP 5xx Internal Server Error
/// </summary>
[Route("internalservererror", Name = "internalservererror")]
[DonutOutputCache(CacheProfile = "OneDay")]
public ActionResult InternalServerError()
{
Response.StatusCode = (int) HttpStatusCode.InternalServerError;
return View();
}
/// <summary>
/// HTTP 4xx Bad Request
/// </summary>
[Route("badrequest", Name = "badrequest")]
[DonutOutputCache(CacheProfile = "OneDay")]
public ActionResult BadRequest()
{
Response.StatusCode = (int) HttpStatusCode.BadRequest;
return View();
}
}
}
using System;
using System.Net;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Autofac;
using Autofac.Integration.Mvc;
using GhuntleyWeb.Services;
using SimpleMvcSitemap;
namespace GhuntleyWeb
{
public class MvcApplication : HttpApplication
{
protected void Application_BeginRequest(object sender, EventArgs e)
{
EnsureHttpRequestIsServedFromDomainRoot();
//EnsureHttpRequestIsLowerCase();
EnsureHttpRequestIsSecure();
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
var builder = new ContainerBuilder();
//builder.RegisterType<SampleMvcAutoAuthenticationCallbackProvider>().As<IAuthenticationCallbackProvider>();
//builder.RegisterType<CookieCache>().As<ICache>();
// register services first.
var blogPostsDirectory = new Uri(HttpContext.Current.Server.MapPath(AppSettings.BlogPostsDirectory));
builder.Register(c => new BlogPostFileSystemProvider(blogPostsDirectory))
.As<IBlogPostService>()
.SingleInstance();
// register containers and sitemap last.
builder.RegisterControllers(typeof (MvcApplication).Assembly);
builder.Register(c => new SitemapProvider()).As<ISitemapProvider>().SingleInstance();
IContainer container = builder.Build();
container.ActivateGlimpse(); // Register AutoFac into Glimpse
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
protected void EnsureHttpRequestIsLowerCase()
{
// Exclude http get, files and sitemap from redirection.
bool isGet = HttpContext.Current.Request.RequestType.ToLowerInvariant().Contains("get");
bool isFile = HttpContext.Current.Request.Url.AbsolutePath.Contains(".");
if (isGet == true && isFile == false)
{
string lowercaseUrl = (Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Authority +
HttpContext.Current.Request.Url.AbsolutePath);
if (Regex.IsMatch(lowercaseUrl, @"[A-Z]"))
{
// Don't change casing on query strings
lowercaseUrl = lowercaseUrl.ToLower() + HttpContext.Current.Request.Url.Query;
PermanentlyRedirectTo(lowercaseUrl);
}
}
}
protected void EnsureHttpRequestIsSecure()
{
if (!Context.Request.IsSecureConnection && !Context.Request.IsLocal)
{
string sslUrl = Context.Request.Url.ToString().Replace("http:", "https:");
PermanentlyRedirectTo(sslUrl);
}
}
protected void EnsureHttpRequestIsServedFromDomainRoot()
{
if (Request.Url.Host.StartsWith("www") && !Request.Url.IsLoopback)
{
var nakedUrl = new UriBuilder(Request.Url)
{
Host = Request.Url.Host.Replace("www.", String.Empty)
};
PermanentlyRedirectTo(nakedUrl.ToString());
}
}
protected void PermanentlyRedirectTo(string location)
{
Response.Clear();
Response.StatusCode = (int) HttpStatusCode.MovedPermanently;
Response.AddHeader("Location", location);
Response.End();
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Antlr" version="3.4.1.9004" targetFramework="net45" />
<package id="Autofac" version="3.4.0" targetFramework="net45" />
<package id="Autofac.Mvc5" version="3.3.3" targetFramework="net45" />
<package id="Glimpse" version="1.8.6" targetFramework="net45" />
<package id="Glimpse.AspNet" version="1.9.1" targetFramework="net45" />
<package id="Glimpse.Autofac" version="0.2.4" targetFramework="net45" />
<package id="Glimpse.Mvc5" version="1.5.3" targetFramework="net45" />
<package id="Glimpse.RavenDb" version="2.2" targetFramework="net45" />
<package id="Glimpse.WindowsAzure" version="0.9.0-beta1" targetFramework="net45" />
<package id="Humanizer" version="1.29.0" targetFramework="net45" />
<package id="MarkdownSharp" version="1.13.0.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Mvc" version="5.2.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Razor" version="3.2.0" targetFramework="net45" />
<package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net45" />
<package id="Microsoft.AspNet.WebPages" version="3.2.0" targetFramework="net45" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
<package id="MvcDonutCaching" version="1.2.3" targetFramework="net45" />
<package id="MvcSiteMapProvider.MVC5.Core" version="4.6.15" targetFramework="net45" />
<package id="MvcSiteMapProvider.Web" version="4.6.1" targetFramework="net45" />
<package id="Newtonsoft.Json" version="6.0.3" targetFramework="net45" />
<package id="Newtonsoft.Json.Glimpse" version="1.0.2" targetFramework="net45" />
<package id="Polly" version="2.0.0" targetFramework="net45" />
<package id="RavenDB.Client" version="2.5.2851" targetFramework="net45" />
<package id="Serilog" version="1.4.9" targetFramework="net45" />
<package id="Serilog.Sinks.Glimpse" version="1.4.9" targetFramework="net45" />
<package id="Serilog.Sinks.Seq" version="1.4.9" targetFramework="net45" />
<package id="SimpleMvcSitemap" version="0.4.0" targetFramework="net45" />
<package id="T4AppSettings" version="1.1.0" targetFramework="net45" />
<package id="WebActivatorEx" version="2.0.1" targetFramework="net45" />
<package id="WebGrease" version="1.5.2" targetFramework="net45" />
</packages>
using System.Web.Mvc;
using System.Web.Routing;
namespace GhuntleyWeb
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.LowercaseUrls = true;
// routes must be defined via attribute routing.
routes.MapMvcAttributeRoutes();
// default route that displays 404 page if attribute routing fails.
//routes.MapRoute(
// "Default",
// "{*url}",
// new {controller = "Error", action = "NotFound"}
// );
//routes.MapRoute("Default", "{controller}/{action}/{id}",
// new {controller = "Home", action = "Index", id = UrlParameter.Optional}
// );
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<!--
For more information on how to configure your ASP.NET application, please visit
http://go.microsoft.com/fwlink/?LinkId=301880
-->
<configuration>
<configSections>
<section name="glimpse" type="Glimpse.Core.Configuration.Section, Glimpse.Core" />
</configSections>
<appSettings>
<add key="BlogPostsDirectory" value="~/App_Data" />
<add key="webpages:Version" value="3.0.0.0" />
<add key="webpages:Enabled" value="false" />
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5" />
<httpRuntime targetFramework="4.5" />
<!-- Glimpse: This can be commented in to add additional data to the Trace tab when using WebForms
<trace writeToDiagnosticsTrace="true" enabled="true" pageOutput="false"/> -->
<httpModules>
<add name="Glimpse" type="Glimpse.AspNet.HttpModule, Glimpse.AspNet" />
</httpModules>
<httpHandlers>
<add path="glimpse.axd" verb="GET" type="Glimpse.AspNet.HttpHandler, Glimpse.AspNet" />
</httpHandlers>
<!-- MVCDonutCaching: See https://github.com/moonpyk/mvcdonutcaching -->
<caching>
<outputCacheSettings>
<outputCacheProfiles>
<add name="OneDay" duration="86400" varyByParam="*" />
</outputCacheProfiles>
</outputCacheSettings>
</caching>
</system.web>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-5.2.0.0" newVersion="5.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Autofac" publicKeyToken="17863af14b0044da" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.4.0.0" newVersion="3.4.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<glimpse defaultRuntimePolicy="On" endpointBaseUri="~/Glimpse.axd">
<runtimePolicies>
<ignoredTypes>
<!-- Enable Glimpse to function on remote webservers (ie: not jailed to localhost, note: ensure access to glimpse.axd is locked down.) -->
<!-- <add type="Glimpse.AspNet.Policy.LocalPolicy, Glimpse.AspNet" /> -->
</ignoredTypes>
</runtimePolicies>
</glimpse>
<system.webServer>
<httpErrors errorMode="Custom">
<remove statusCode="400"/>
<error statusCode="400" path="/Error/BadRequest" responseMode="ExecuteURL"/>
<remove statusCode="404"/>
<error statusCode="404" path="/Error/NotFound" responseMode="ExecuteURL"/>
<remove statusCode="500"/>
<error statusCode="500" path="/Error/InternalServerError" responseMode="ExecuteURL"/>
</httpErrors>
<!-- Enable WOFF - see https://stackoverflow.com/questions/9021946/add-mime-mapping-in-web-config-for-iis-express -->
<staticContent>
<remove fileExtension=".woff" />
<mimeMap fileExtension=".woff" mimeType="application/font-woff" />
</staticContent>
<validation validateIntegratedModeConfiguration="false" />
<modules>
<add name="Glimpse" type="Glimpse.AspNet.HttpModule, Glimpse.AspNet" preCondition="integratedMode" />
<remove name="UrlRoutingModule-4.0" />
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" />
</modules>
<handlers>
<add name="Glimpse" path="glimpse.axd" verb="GET" type="Glimpse.AspNet.HttpHandler, Glimpse.AspNet" preCondition="integratedMode" />
</handlers>
</system.webServer>
</configuration>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment