// 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 System;
using System.Collections;
using System.Collections.Generic;
using Microsoft.Extensions.Internal;
namespace Microsoft.AspNetCore.Routing
{
///
/// An type for route values.
///
public class RouteValueDictionary : IDictionary, IReadOnlyDictionary
{
///
/// Creates an empty .
///
public RouteValueDictionary()
{
}
///
/// Creates a initialized with the specified .
///
/// An object to initialize the dictionary. The value can be of type
/// or
/// or an object with public properties as key-value pairs.
///
///
/// If the value is a dictionary or other ,
/// then its entries are copied. Otherwise the object is interpreted as a set of key-value pairs where the
/// property names are keys, and property values are the values, and copied into the dictionary.
/// Only public instance non-index properties are considered.
///
public RouteValueDictionary(object values)
{
var otherDictionary = values as RouteValueDictionary;
if (otherDictionary != null)
{
if (otherDictionary.InnerDictionary != null)
{
InnerDictionary = new Dictionary(
otherDictionary.InnerDictionary.Count,
StringComparer.OrdinalIgnoreCase);
foreach (var kvp in otherDictionary.InnerDictionary)
{
InnerDictionary[kvp.Key] = kvp.Value;
}
return;
}
else if (otherDictionary.Properties != null)
{
Properties = otherDictionary.Properties;
Value = otherDictionary.Value;
return;
}
else
{
return;
}
}
var keyValuePairCollection = values as IEnumerable>;
if (keyValuePairCollection != null)
{
InnerDictionary = new Dictionary(StringComparer.OrdinalIgnoreCase);
foreach (var kvp in keyValuePairCollection)
{
InnerDictionary[kvp.Key] = kvp.Value;
}
return;
}
if (values != null)
{
Properties = PropertyHelper.GetVisibleProperties(values);
Value = values;
return;
}
}
private Dictionary InnerDictionary { get; set; }
private PropertyHelper[] Properties { get; }
private object Value { get; }
///
public object this[string key]
{
get
{
if (string.IsNullOrEmpty(key))
{
throw new ArgumentNullException(nameof(key));
}
object value;
TryGetValue(key, out value);
return value;
}
set
{
if (string.IsNullOrEmpty(key))
{
throw new ArgumentNullException(nameof(key));
}
EnsureWritable();
InnerDictionary[key] = value;
}
}
///
/// Gets the comparer for this dictionary.
///
///
/// This will always be a reference to
///
public IEqualityComparer Comparer => StringComparer.OrdinalIgnoreCase;
///
public int Count => InnerDictionary?.Count ?? Properties?.Length ?? 0;
///
bool ICollection>.IsReadOnly => false;
///
public ICollection Keys
{
get
{
EnsureWritable();
return InnerDictionary.Keys;
}
}
IEnumerable IReadOnlyDictionary.Keys
{
get
{
EnsureWritable();
return InnerDictionary.Keys;
}
}
///
public ICollection