aspnetcore/test/Microsoft.AspNet.Routing.Tests/Template/TemplateRouteTests.cs

1007 lines
32 KiB
C#

// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNet.Abstractions;
using Xunit;
namespace Microsoft.AspNet.Routing.Template.Tests
{
public class TemplateRouteTests
{
[Fact]
public void MatchSingleRoute()
{
// Arrange
HttpContext context = GetHttpContext("~/Bank/DoAction/123");
TemplateRoute r = CreateRoute("{controller}/{action}/{id}", null);
// Act
var match = r.Match(new RouteContext(context));
// Assert
Assert.NotNull(match);
Assert.Equal("Bank", match.Values["controller"]);
Assert.Equal("DoAction", match.Values["action"]);
Assert.Equal("123", match.Values["id"]);
}
[Fact]
public void NoMatchSingleRoute()
{
// Arrange
HttpContext context = GetHttpContext("~/Bank/DoAction");
TemplateRoute r = CreateRoute("{controller}/{action}/{id}", null);
// Act
var rd = r.Match(new RouteContext(context));
// Assert
Assert.Null(rd);
}
[Fact]
public void MatchSingleRouteWithDefaults()
{
// Arrange
HttpContext context = GetHttpContext("~/Bank/DoAction");
TemplateRoute r = CreateRoute("{controller}/{action}/{id}", new RouteValueDictionary(new { id = "default id" }));
// Act
var rd = r.Match(new RouteContext(context));
// Assert
Assert.Equal("Bank", rd.Values["controller"]);
Assert.Equal("DoAction", rd.Values["action"]);
Assert.Equal("default id", rd.Values["id"]);
}
[Fact]
public void NoMatchSingleRouteWithDefaults()
{
// Arrange
HttpContext context = GetHttpContext("~/Bank");
TemplateRoute r = CreateRoute("{controller}/{action}/{id}", new RouteValueDictionary(new { id = "default id" }));
// Act
var rd = r.Match(new RouteContext(context));
// Assert
Assert.Null(rd);
}
[Fact]
public void MatchRouteWithLiterals()
{
// Arrange
HttpContext context = GetHttpContext("~/moo/111/bar/222");
TemplateRoute r = CreateRoute("moo/{p1}/bar/{p2}", new RouteValueDictionary(new { p2 = "default p2" }));
// Act
var rd = r.Match(new RouteContext(context));
// Assert
Assert.Equal("111", rd.Values["p1"]);
Assert.Equal("222", rd.Values["p2"]);
}
[Fact]
public void MatchRouteWithLiteralsAndDefaults()
{
// Arrange
HttpContext context = GetHttpContext("~/moo/111/bar/");
TemplateRoute r = CreateRoute("moo/{p1}/bar/{p2}", new RouteValueDictionary(new { p2 = "default p2" }));
// Act
var rd = r.Match(new RouteContext(context));
// Assert
Assert.Equal("111", rd.Values["p1"]);
Assert.Equal("default p2", rd.Values["p2"]);
}
[Fact]
public void MatchRouteWithOnlyLiterals()
{
// Arrange
HttpContext context = GetHttpContext("~/moo/bar");
TemplateRoute r = CreateRoute("moo/bar", null);
// Act
var rd = r.Match(new RouteContext(context));
// Assert
Assert.NotNull(rd);
Assert.Equal<int>(0, rd.Values.Count);
}
[Fact]
public void NoMatchRouteWithOnlyLiterals()
{
// Arrange
HttpContext context = GetHttpContext("~/moo/bar");
TemplateRoute r = CreateRoute("moo/bars", null);
// Act
var rd = r.Match(new RouteContext(context));
// Assert
Assert.Null(rd);
}
[Fact]
public void MatchRouteWithExtraSeparators()
{
// Arrange
HttpContext context = GetHttpContext("~/moo/bar/");
TemplateRoute r = CreateRoute("moo/bar", null);
// Act
var rd = r.Match(new RouteContext(context));
// Assert
Assert.NotNull(rd);
Assert.Equal<int>(0, rd.Values.Count);
}
[Fact]
public void MatchRouteUrlWithExtraSeparators()
{
// Arrange
HttpContext context = GetHttpContext("~/moo/bar");
TemplateRoute r = CreateRoute("moo/bar/", null);
// Act
var rd = r.Match(new RouteContext(context));
// Assert
Assert.NotNull(rd);
Assert.Equal<int>(0, rd.Values.Count);
}
[Fact]
public void MatchRouteUrlWithParametersAndExtraSeparators()
{
// Arrange
HttpContext context = GetHttpContext("~/moo/bar");
TemplateRoute r = CreateRoute("{p1}/{p2}/", null);
// Act
var rd = r.Match(new RouteContext(context));
// Assert
Assert.NotNull(rd);
Assert.Equal("moo", rd.Values["p1"]);
Assert.Equal("bar", rd.Values["p2"]);
}
[Fact]
public void NoMatchRouteUrlWithDifferentLiterals()
{
// Arrange
HttpContext context = GetHttpContext("~/moo/bar/boo");
TemplateRoute r = CreateRoute("{p1}/{p2}/baz", null);
// Act
var rd = r.Match(new RouteContext(context));
// Assert
Assert.Null(rd);
}
[Fact]
public void NoMatchLongerUrl()
{
// Arrange
HttpContext context = GetHttpContext("~/moo/bar");
TemplateRoute r = CreateRoute("{p1}", null);
// Act
var rd = r.Match(new RouteContext(context));
// Assert
Assert.Null(rd);
}
[Fact]
public void MatchSimpleFilename()
{
// Arrange
HttpContext context = GetHttpContext("~/default.aspx");
TemplateRoute r = CreateRoute("DEFAULT.ASPX", null);
// Act
var rd = r.Match(new RouteContext(context));
// Assert
Assert.NotNull(rd);
}
private void VerifyRouteMatchesWithContext(string route, string requestUrl)
{
HttpContext context = GetHttpContext(requestUrl);
TemplateRoute r = CreateRoute(route, null);
// Act
var rd = r.Match(new RouteContext(context));
// Assert
Assert.NotNull(rd);
}
[Fact]
public void MatchEvilRoute()
{
VerifyRouteMatchesWithContext("{prefix}x{suffix}", "~/xxxxxxxxxx");
VerifyRouteMatchesWithContext("{prefix}xyz{suffix}", "~/xxxxyzxyzxxxxxxyz");
VerifyRouteMatchesWithContext("{prefix}xyz{suffix}", "~/abcxxxxyzxyzxxxxxxyzxx");
VerifyRouteMatchesWithContext("{prefix}xyz{suffix}", "~/xyzxyzxyzxyzxyz");
VerifyRouteMatchesWithContext("{prefix}xyz{suffix}", "~/xyzxyzxyzxyzxyz1");
VerifyRouteMatchesWithContext("{prefix}xyz{suffix}", "~/xyzxyzxyz");
VerifyRouteMatchesWithContext("{prefix}aa{suffix}", "~/aaaaa");
VerifyRouteMatchesWithContext("{prefix}aaa{suffix}", "~/aaaaa");
}
[Fact]
public void MatchRouteWithExtraDefaultValues()
{
// Arrange
HttpContext context = GetHttpContext("~/v1");
TemplateRoute r = CreateRoute("{p1}/{p2}", new RouteValueDictionary(new { p2 = (string)null, foo = "bar" }));
// Act
var rd = r.Match(new RouteContext(context));
// Assert
Assert.NotNull(rd);
Assert.Equal<int>(3, rd.Values.Count);
Assert.Equal("v1", rd.Values["p1"]);
Assert.Null(rd.Values["p2"]);
Assert.Equal("bar", rd.Values["foo"]);
}
[Fact]
public void MatchPrettyRouteWithExtraDefaultValues()
{
// Arrange
HttpContext context = GetHttpContext("~/date/2007/08");
TemplateRoute r = CreateRoute(
"date/{y}/{m}/{d}",
new RouteValueDictionary(new { controller = "blog", action = "showpost", m = (string)null, d = (string)null }));
// Act
var rd = r.Match(new RouteContext(context));
// Assert
Assert.NotNull(rd);
Assert.Equal<int>(5, rd.Values.Count);
Assert.Equal("blog", rd.Values["controller"]);
Assert.Equal("showpost", rd.Values["action"]);
Assert.Equal("2007", rd.Values["y"]);
Assert.Equal("08", rd.Values["m"]);
Assert.Null(rd.Values["d"]);
}
[Fact]
public void GetRouteDataWithMultiSegmentParamsOnBothEndsMatches()
{
GetRouteDataHelper(
CreateRoute("language/{lang}-{region}", null),
"language/en-US",
new RouteValueDictionary(new { lang = "en", region = "US" }));
}
[Fact]
public void GetRouteDataWithMultiSegmentParamsOnLeftEndMatches()
{
GetRouteDataHelper(
CreateRoute("language/{lang}-{region}a", null),
"language/en-USa",
new RouteValueDictionary(new { lang = "en", region = "US" }));
}
[Fact]
public void GetRouteDataWithMultiSegmentParamsOnRightEndMatches()
{
GetRouteDataHelper(
CreateRoute("language/a{lang}-{region}", null),
"language/aen-US",
new RouteValueDictionary(new { lang = "en", region = "US" }));
}
[Fact]
public void GetRouteDataWithMultiSegmentParamsOnNeitherEndMatches()
{
GetRouteDataHelper(
CreateRoute("language/a{lang}-{region}a", null),
"language/aen-USa",
new RouteValueDictionary(new { lang = "en", region = "US" }));
}
[Fact]
public void GetRouteDataWithMultiSegmentParamsOnNeitherEndDoesNotMatch()
{
GetRouteDataHelper(
CreateRoute("language/a{lang}-{region}a", null),
"language/a-USa",
null);
}
[Fact]
public void GetRouteDataWithMultiSegmentParamsOnNeitherEndDoesNotMatch2()
{
GetRouteDataHelper(
CreateRoute("language/a{lang}-{region}a", null),
"language/aen-a",
null);
}
[Fact]
public void GetRouteDataWithSimpleMultiSegmentParamsOnBothEndsMatches()
{
GetRouteDataHelper(
CreateRoute("language/{lang}", null),
"language/en",
new RouteValueDictionary(new { lang = "en" }));
}
[Fact]
public void GetRouteDataWithSimpleMultiSegmentParamsOnBothEndsTrailingSlashDoesNotMatch()
{
GetRouteDataHelper(
CreateRoute("language/{lang}", null),
"language/",
null);
}
[Fact]
public void GetRouteDataWithSimpleMultiSegmentParamsOnBothEndsDoesNotMatch()
{
GetRouteDataHelper(
CreateRoute("language/{lang}", null),
"language",
null);
}
[Fact]
public void GetRouteDataWithSimpleMultiSegmentParamsOnLeftEndMatches()
{
GetRouteDataHelper(
CreateRoute("language/{lang}-", null),
"language/en-",
new RouteValueDictionary(new { lang = "en" }));
}
[Fact]
public void GetRouteDataWithSimpleMultiSegmentParamsOnRightEndMatches()
{
GetRouteDataHelper(
CreateRoute("language/a{lang}", null),
"language/aen",
new RouteValueDictionary(new { lang = "en" }));
}
[Fact]
public void GetRouteDataWithSimpleMultiSegmentParamsOnNeitherEndMatches()
{
GetRouteDataHelper(
CreateRoute("language/a{lang}a", null),
"language/aena",
new RouteValueDictionary(new { lang = "en" }));
}
[Fact]
public void GetRouteDataWithMultiSegmentStandardMvcRouteMatches()
{
GetRouteDataHelper(
CreateRoute("{controller}.mvc/{action}/{id}", new RouteValueDictionary(new { action = "Index", id = (string)null })),
"home.mvc/index",
new RouteValueDictionary(new { controller = "home", action = "index", id = (string)null }));
}
[Fact]
public void GetRouteDataWithMultiSegmentParamsOnBothEndsWithDefaultValuesMatches()
{
GetRouteDataHelper(
CreateRoute("language/{lang}-{region}", new RouteValueDictionary(new { lang = "xx", region = "yy" })),
"language/-",
null);
}
[Fact]
public void GetRouteDataWithUrlWithMultiSegmentWithRepeatedDots()
{
GetRouteDataHelper(
CreateRoute("{Controller}..mvc/{id}/{Param1}", null),
"Home..mvc/123/p1",
new RouteValueDictionary(new { Controller = "Home", id = "123", Param1 = "p1" }));
}
[Fact]
public void GetRouteDataWithUrlWithTwoRepeatedDots()
{
GetRouteDataHelper(
CreateRoute("{Controller}.mvc/../{action}", null),
"Home.mvc/../index",
new RouteValueDictionary(new { Controller = "Home", action = "index" }));
}
[Fact]
public void GetRouteDataWithUrlWithThreeRepeatedDots()
{
GetRouteDataHelper(
CreateRoute("{Controller}.mvc/.../{action}", null),
"Home.mvc/.../index",
new RouteValueDictionary(new { Controller = "Home", action = "index" }));
}
[Fact]
public void GetRouteDataWithUrlWithManyRepeatedDots()
{
GetRouteDataHelper(
CreateRoute("{Controller}.mvc/../../../{action}", null),
"Home.mvc/../../../index",
new RouteValueDictionary(new { Controller = "Home", action = "index" }));
}
[Fact]
public void GetRouteDataWithUrlWithExclamationPoint()
{
GetRouteDataHelper(
CreateRoute("{Controller}.mvc!/{action}", null),
"Home.mvc!/index",
new RouteValueDictionary(new { Controller = "Home", action = "index" }));
}
[Fact]
public void GetRouteDataWithUrlWithStartingDotDotSlash()
{
GetRouteDataHelper(
CreateRoute("../{Controller}.mvc", null),
"../Home.mvc",
new RouteValueDictionary(new { Controller = "Home" }));
}
[Fact]
public void GetRouteDataWithUrlWithStartingBackslash()
{
GetRouteDataHelper(
CreateRoute(@"\{Controller}.mvc", null),
@"\Home.mvc",
new RouteValueDictionary(new { Controller = "Home" }));
}
[Fact]
public void GetRouteDataWithUrlWithBackslashSeparators()
{
GetRouteDataHelper(
CreateRoute(@"{Controller}.mvc\{id}\{Param1}", null),
@"Home.mvc\123\p1",
new RouteValueDictionary(new { Controller = "Home", id = "123", Param1 = "p1" }));
}
[Fact]
public void GetRouteDataWithUrlWithParenthesesLiterals()
{
GetRouteDataHelper(
CreateRoute(@"(Controller).mvc", null),
@"(Controller).mvc",
new RouteValueDictionary());
}
[Fact]
public void GetRouteDataWithUrlWithTrailingSlashSpace()
{
GetRouteDataHelper(
CreateRoute(@"Controller.mvc/ ", null),
@"Controller.mvc/ ",
new RouteValueDictionary());
}
[Fact]
public void GetRouteDataWithUrlWithTrailingSpace()
{
GetRouteDataHelper(
CreateRoute(@"Controller.mvc ", null),
@"Controller.mvc ",
new RouteValueDictionary());
}
[Fact]
public void GetRouteDataWithCatchAllCapturesDots()
{
// DevDiv Bugs 189892: UrlRouting: Catch all parameter cannot capture url segments that contain the "."
GetRouteDataHelper(
CreateRoute(
"Home/ShowPilot/{missionId}/{*name}",
new RouteValueDictionary(new
{
controller = "Home",
action = "ShowPilot",
missionId = (string)null,
name = (string)null
})),
"Home/ShowPilot/777/12345./foobar",
new RouteValueDictionary(new { controller = "Home", action = "ShowPilot", missionId = "777", name = "12345./foobar" }));
}
[Fact]
public void RouteWithCatchAllClauseCapturesManySlashes()
{
// Arrange
HttpContext context = GetHttpContext("~/v1/v2/v3");
TemplateRoute r = CreateRoute("{p1}/{*p2}", null);
// Act
var rd = r.Match(new RouteContext(context));
// Assert
Assert.NotNull(rd);
Assert.Equal<int>(2, rd.Values.Count);
Assert.Equal("v1", rd.Values["p1"]);
Assert.Equal("v2/v3", rd.Values["p2"]);
}
[Fact]
public void RouteWithCatchAllClauseCapturesTrailingSlash()
{
// Arrange
HttpContext context = GetHttpContext("~/v1/");
TemplateRoute r = CreateRoute("{p1}/{*p2}", null);
// Act
var rd = r.Match(new RouteContext(context));
// Assert
Assert.NotNull(rd);
Assert.Equal<int>(2, rd.Values.Count);
Assert.Equal("v1", rd.Values["p1"]);
Assert.Null(rd.Values["p2"]);
}
[Fact]
public void RouteWithCatchAllClauseCapturesEmptyContent()
{
// Arrange
HttpContext context = GetHttpContext("~/v1");
TemplateRoute r = CreateRoute("{p1}/{*p2}", null);
// Act
var rd = r.Match(new RouteContext(context));
// Assert
Assert.NotNull(rd);
Assert.Equal<int>(2, rd.Values.Count);
Assert.Equal("v1", rd.Values["p1"]);
Assert.Null(rd.Values["p2"]);
}
[Fact]
public void RouteWithCatchAllClauseUsesDefaultValueForEmptyContent()
{
// Arrange
HttpContext context = GetHttpContext("~/v1");
TemplateRoute r = CreateRoute("{p1}/{*p2}", new RouteValueDictionary(new { p2 = "catchall" }));
// Act
var rd = r.Match(new RouteContext(context));
// Assert
Assert.NotNull(rd);
Assert.Equal<int>(2, rd.Values.Count);
Assert.Equal("v1", rd.Values["p1"]);
Assert.Equal("catchall", rd.Values["p2"]);
}
[Fact]
public void RouteWithCatchAllClauseIgnoresDefaultValueForNonEmptyContent()
{
// Arrange
HttpContext context = GetHttpContext("~/v1/hello/whatever");
TemplateRoute r = CreateRoute("{p1}/{*p2}", new RouteValueDictionary(new { p2 = "catchall" }));
// Act
var rd = r.Match(new RouteContext(context));
// Assert
Assert.NotNull(rd);
Assert.Equal<int>(2, rd.Values.Count);
Assert.Equal("v1", rd.Values["p1"]);
Assert.Equal("hello/whatever", rd.Values["p2"]);
}
[Fact]
public void GetRouteDataDoesNotMatchOnlyLeftLiteralMatch()
{
TemplateRoute r = CreateRoute("foo", null);
// DevDiv Bugs 191180: UrlRouting: Wrong route getting matched if a url segment is a substring of the requested url
GetRouteDataHelper(
r,
"fooBAR",
null);
}
[Fact]
public void GetRouteDataDoesNotMatchOnlyRightLiteralMatch()
{
TemplateRoute r = CreateRoute("foo", null);
// DevDiv Bugs 191180: UrlRouting: Wrong route getting matched if a url segment is a substring of the requested url
GetRouteDataHelper(
r,
"BARfoo",
null);
}
[Fact]
public void GetRouteDataDoesNotMatchMiddleLiteralMatch()
{
TemplateRoute r = CreateRoute("foo", null);
// DevDiv Bugs 191180: UrlRouting: Wrong route getting matched if a url segment is a substring of the requested url
GetRouteDataHelper(
r,
"BARfooBAR",
null);
}
[Fact]
public void GetRouteDataDoesMatchesExactLiteralMatch()
{
TemplateRoute r = CreateRoute("foo", null);
// DevDiv Bugs 191180: UrlRouting: Wrong route getting matched if a url segment is a substring of the requested url
GetRouteDataHelper(
r,
"foo",
new RouteValueDictionary());
}
[Fact]
public void GetRouteDataWithWeirdParameterNames()
{
TemplateRoute r = CreateRoute(
"foo/{ }/{.!$%}/{dynamic.data}/{op.tional}",
new RouteValueDictionary() { { " ", "not a space" }, { "op.tional", "default value" }, { "ran!dom", "va@lue" } });
GetRouteDataHelper(
r,
"foo/space/weird/orderid",
new RouteValueDictionary() { { " ", "space" }, { ".!$%", "weird" }, { "dynamic.data", "orderid" }, { "op.tional", "default value" }, { "ran!dom", "va@lue" } });
}
[Fact]
public void GetRouteDataDoesNotMatchRouteWithLiteralSeparatorDefaultsButNoValue()
{
GetRouteDataHelper(
CreateRoute("{controller}/{language}-{locale}", new RouteValueDictionary(new { language = "en", locale = "US" })),
"foo",
null);
}
[Fact]
public void GetRouteDataDoesNotMatchesRouteWithLiteralSeparatorDefaultsAndLeftValue()
{
GetRouteDataHelper(
CreateRoute("{controller}/{language}-{locale}", new RouteValueDictionary(new { language = "en", locale = "US" })),
"foo/xx-",
null);
}
[Fact]
public void GetRouteDataDoesNotMatchesRouteWithLiteralSeparatorDefaultsAndRightValue()
{
GetRouteDataHelper(
CreateRoute("{controller}/{language}-{locale}", new RouteValueDictionary(new { language = "en", locale = "US" })),
"foo/-yy",
null);
}
[Fact]
public void GetRouteDataMatchesRouteWithLiteralSeparatorDefaultsAndValue()
{
GetRouteDataHelper(
CreateRoute("{controller}/{language}-{locale}", new RouteValueDictionary(new { language = "en", locale = "US" })),
"foo/xx-yy",
new RouteValueDictionary { { "language", "xx" }, { "locale", "yy" }, { "controller", "foo" } });
}
[Fact]
public void MatchSetsOptionalParameter()
{
// Arrange
var route = CreateRoute("{controller}/{action?}");
var url = "Home/Index";
// Act
var match = route.Match(new RouteContext(GetHttpContext(url)));
// Assert
Assert.NotNull(match);
Assert.Equal(2, match.Values.Count);
Assert.Equal("Home", match.Values["controller"]);
Assert.Equal("Index", match.Values["action"]);
}
[Fact]
public void MatchDoesNotSetOptionalParameter()
{
// Arrange
var route = CreateRoute("{controller}/{action?}");
var url = "Home";
// Act
var match = route.Match(new RouteContext(GetHttpContext(url)));
// Assert
Assert.NotNull(match);
Assert.Equal(1, match.Values.Count);
Assert.Equal("Home", match.Values["controller"]);
Assert.False(match.Values.ContainsKey("action"));
}
[Fact]
public void MatchMultipleOptionalParameters()
{
// Arrange
var route = CreateRoute("{controller}/{action?}/{id?}");
var url = "Home/Index";
// Act
var match = route.Match(new RouteContext(GetHttpContext(url)));
// Assert
Assert.NotNull(match);
Assert.Equal(2, match.Values.Count);
Assert.Equal("Home", match.Values["controller"]);
Assert.Equal("Index", match.Values["action"]);
Assert.False(match.Values.ContainsKey("id"));
}
private static IRouteValues CreateRouteData()
{
return new RouteValues(new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase));
}
private static RouteValueDictionary CreateRouteValueDictionary()
{
var values = new RouteValueDictionary();
return values;
}
private static void GetRouteDataHelper(TemplateRoute route, string requestPath, RouteValueDictionary expectedValues)
{
// Arrange
HttpContext context = GetHttpContext(requestPath);
// Act
var match = route.Match(new RouteContext(context));
// Assert
if (expectedValues == null)
{
Assert.Null(match);
}
else
{
Assert.NotNull(match);
Assert.Equal<int>(expectedValues.Count, match.Values.Count);
foreach (string key in match.Values.Keys)
{
Assert.Equal(expectedValues[key], match.Values[key]);
}
}
}
internal static HttpContext GetHttpContext(string requestPath)
{
return GetHttpContext(null, requestPath);
}
private static HttpContext GetHttpContext(string appPath, string requestPath)
{
if (!String.IsNullOrEmpty(requestPath) && requestPath[0] == '~')
{
requestPath = requestPath.Substring(1);
}
if (!String.IsNullOrEmpty(requestPath) && requestPath[0] != '/')
{
requestPath = "/" + requestPath;
}
var context = new MockHttpContext();
context.Request.Path = new PathString(requestPath);
context.Request.PathBase = new PathString(appPath);
return context;
}
private static TemplateRoute CreateRoute(string template)
{
return CreateRoute(template, null);
}
private static TemplateRoute CreateRoute(string template, RouteValueDictionary defaults)
{
return new TemplateRoute(new MockRouteEndpoint(), template, defaults);
}
private class MockRouteEndpoint : IRouteEndpoint
{
public Task<bool> Send(HttpContext context)
{
throw new NotImplementedException();
}
}
// This is a placeholder
private class RouteValueDictionary : Dictionary<string, object>
{
public RouteValueDictionary()
: base(StringComparer.OrdinalIgnoreCase)
{
}
public RouteValueDictionary(object obj)
: base(StringComparer.OrdinalIgnoreCase)
{
foreach (var property in obj.GetType().GetProperties())
{
Add(property.Name, property.GetValue(obj));
}
}
}
private class MockHttpContext : HttpContext
{
private readonly Dictionary<Type, object> _features = new Dictionary<Type, object>();
private readonly MockHttpRequest _request;
public MockHttpContext()
{
_request = new MockHttpRequest(this);
}
public override void Dispose()
{
}
public override object GetFeature(Type type)
{
return _features[type];
}
public override IDictionary<object, object> Items
{
get { throw new NotImplementedException(); }
}
public override HttpRequest Request
{
get { return _request; }
}
public override HttpResponse Response
{
get { throw new NotImplementedException(); }
}
public override void SetFeature(Type type, object instance)
{
_features[type] = instance;
}
}
private class MockHttpRequest : HttpRequest
{
private readonly HttpContext _context;
public MockHttpRequest(HttpContext context)
{
_context = context;
}
public override Stream Body
{
get;
set;
}
public override CancellationToken CallCanceled
{
get;
set;
}
public override IReadableStringCollection Cookies
{
get { throw new NotImplementedException(); }
}
public override IHeaderDictionary Headers
{
get { throw new NotImplementedException(); }
}
public override HostString Host
{
get;
set;
}
public override HttpContext HttpContext
{
get { return _context; }
}
public override bool IsSecure
{
get { throw new NotImplementedException(); }
}
public override string Method
{
get;
set;
}
public override PathString Path
{
get;
set;
}
public override PathString PathBase
{
get;
set;
}
public override string Protocol
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public override IReadableStringCollection Query
{
get { throw new NotImplementedException(); }
}
public override QueryString QueryString
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
public override string Scheme
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
}
}
}