Add RoutesValues to HttpRequest (#1042)
This commit is contained in:
parent
e8d5a85c99
commit
5f75c07bbf
|
|
@ -4,6 +4,7 @@
|
|||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
|
||||
namespace Microsoft.AspNetCore.Http
|
||||
{
|
||||
|
|
@ -117,5 +118,11 @@ namespace Microsoft.AspNetCore.Http
|
|||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract Task<IFormCollection> ReadFormAsync(CancellationToken cancellationToken = new CancellationToken());
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of route values for this request.
|
||||
/// </summary>
|
||||
/// <returns>The collection of route values for this request.</returns>
|
||||
public virtual RouteValueDictionary RouteValues { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,34 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
|
||||
namespace Microsoft.AspNetCore.Http.Features
|
||||
{
|
||||
/// <summary>
|
||||
/// A feature for routing values. Use <see cref="HttpContext.Features"/>
|
||||
/// to access the values associated with the current request.
|
||||
/// </summary>
|
||||
public class RouteValuesFeature : IRouteValuesFeature
|
||||
{
|
||||
private RouteValueDictionary _routeValues;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the <see cref="RouteValueDictionary"/> associated with the currrent
|
||||
/// request.
|
||||
/// </summary>
|
||||
public RouteValueDictionary RouteValues
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_routeValues == null)
|
||||
{
|
||||
_routeValues = new RouteValueDictionary();
|
||||
}
|
||||
|
||||
return _routeValues;
|
||||
}
|
||||
set => _routeValues = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ using System.IO;
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
|
||||
namespace Microsoft.AspNetCore.Http.Internal
|
||||
|
|
@ -17,6 +18,7 @@ namespace Microsoft.AspNetCore.Http.Internal
|
|||
private readonly static Func<IFeatureCollection, IQueryFeature> _newQueryFeature = f => new QueryFeature(f);
|
||||
private readonly static Func<HttpRequest, IFormFeature> _newFormFeature = r => new FormFeature(r);
|
||||
private readonly static Func<IFeatureCollection, IRequestCookiesFeature> _newRequestCookiesFeature = f => new RequestCookiesFeature(f);
|
||||
private readonly static Func<IFeatureCollection, IRouteValuesFeature> _newRouteValuesFeature = f => new RouteValuesFeature();
|
||||
|
||||
private HttpContext _context;
|
||||
private FeatureReferences<FeatureInterfaces> _features;
|
||||
|
|
@ -52,6 +54,9 @@ namespace Microsoft.AspNetCore.Http.Internal
|
|||
private IRequestCookiesFeature RequestCookiesFeature =>
|
||||
_features.Fetch(ref _features.Cache.Cookies, _newRequestCookiesFeature);
|
||||
|
||||
private IRouteValuesFeature RouteValuesFeature =>
|
||||
_features.Fetch(ref _features.Cache.RouteValues, _newRouteValuesFeature);
|
||||
|
||||
public override PathString PathBase
|
||||
{
|
||||
get { return new PathString(HttpRequestFeature.PathBase); }
|
||||
|
|
@ -151,12 +156,19 @@ namespace Microsoft.AspNetCore.Http.Internal
|
|||
return FormFeature.ReadFormAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public override RouteValueDictionary RouteValues
|
||||
{
|
||||
get { return RouteValuesFeature.RouteValues; }
|
||||
set { RouteValuesFeature.RouteValues = value; }
|
||||
}
|
||||
|
||||
struct FeatureInterfaces
|
||||
{
|
||||
public IHttpRequestFeature Request;
|
||||
public IQueryFeature Query;
|
||||
public IFormFeature Form;
|
||||
public IRequestCookiesFeature Cookies;
|
||||
public IRouteValuesFeature RouteValues;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Xunit;
|
||||
|
||||
|
|
@ -194,6 +195,57 @@ namespace Microsoft.AspNetCore.Http.Internal
|
|||
Assert.Equal(new[] { "name2=value2" }, cookieHeaders);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RouteValues_GetAndSet()
|
||||
{
|
||||
var context = new DefaultHttpContext();
|
||||
var request = context.Request;
|
||||
|
||||
var routeValuesFeature = context.Features.Get<IRouteValuesFeature>();
|
||||
// No feature set for initial DefaultHttpRequest
|
||||
Assert.Null(routeValuesFeature);
|
||||
|
||||
// Route values returns empty collection by default
|
||||
Assert.Empty(request.RouteValues);
|
||||
|
||||
// Get and set value on request route values
|
||||
request.RouteValues["new"] = "setvalue";
|
||||
Assert.Equal("setvalue", request.RouteValues["new"]);
|
||||
|
||||
routeValuesFeature = context.Features.Get<IRouteValuesFeature>();
|
||||
// Accessing DefaultHttpRequest.RouteValues creates feature
|
||||
Assert.NotNull(routeValuesFeature);
|
||||
|
||||
request.RouteValues = new RouteValueDictionary(new { key = "value" });
|
||||
// Can set DefaultHttpRequest.RouteValues
|
||||
Assert.NotNull(request.RouteValues);
|
||||
Assert.Equal("value", request.RouteValues["key"]);
|
||||
|
||||
// DefaultHttpRequest.RouteValues uses feature
|
||||
Assert.Equal(routeValuesFeature.RouteValues, request.RouteValues);
|
||||
|
||||
// Setting route values to null sets empty collection on request
|
||||
routeValuesFeature.RouteValues = null;
|
||||
Assert.Empty(request.RouteValues);
|
||||
|
||||
var customRouteValuesFeature = new CustomRouteValuesFeature
|
||||
{
|
||||
RouteValues = new RouteValueDictionary(new { key = "customvalue" })
|
||||
};
|
||||
context.Features.Set<IRouteValuesFeature>(customRouteValuesFeature);
|
||||
// Can override DefaultHttpRequest.RouteValues with custom feature
|
||||
Assert.Equal(customRouteValuesFeature.RouteValues, request.RouteValues);
|
||||
|
||||
// Can clear feature
|
||||
context.Features.Set<IRouteValuesFeature>(null);
|
||||
Assert.Empty(request.RouteValues);
|
||||
}
|
||||
|
||||
private class CustomRouteValuesFeature : IRouteValuesFeature
|
||||
{
|
||||
public RouteValueDictionary RouteValues { get; set; }
|
||||
}
|
||||
|
||||
private static HttpRequest CreateRequest(IHeaderDictionary headers)
|
||||
{
|
||||
var context = new DefaultHttpContext();
|
||||
|
|
|
|||
Loading…
Reference in New Issue