Skip to content
This repository has been archived by the owner on Nov 20, 2018. It is now read-only.

Commit

Permalink
#361 Introduce StringValues to replace string[] usage.
Browse files Browse the repository at this point in the history
  • Loading branch information
Tratcher committed Aug 28, 2015
1 parent 15687ab commit 456277f
Show file tree
Hide file tree
Showing 45 changed files with 1,008 additions and 389 deletions.
49 changes: 48 additions & 1 deletion HttpAbstractions.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
VisualStudioVersion = 14.0.22823.1
VisualStudioVersion = 14.0.23107.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{A5A15F1C-885A-452A-A731-B0173DDBD913}"
EndProject
Expand Down Expand Up @@ -43,6 +43,14 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.Framework.WebEnco
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Html.Abstractions", "src\Microsoft.AspNet.Html.Abstractions\Microsoft.AspNet.Html.Abstractions.xproj", "{68A28E4A-3ADE-4187-9625-4FF185887CB3}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "samples", "samples", "{982F09D8-621E-4872-BA7B-BBDEA47D1EFD}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "SampleApp", "samples\SampleApp\SampleApp.xproj", "{1D0764B4-1DEB-4232-A714-D4B7E846918A}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.Framework.Primitives", "src\Microsoft.Framework.Primitives\Microsoft.Framework.Primitives.xproj", "{E5FACCD4-6327-43AA-80A9-AE6F4A3BFE6A}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.Framework.Primitives.Tests", "test\Microsoft.Framework.Primitives.Tests\Microsoft.Framework.Primitives.Tests.xproj", "{61F72E92-B3AE-4A10-B838-44F80AED40AE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -245,6 +253,42 @@ Global
{68A28E4A-3ADE-4187-9625-4FF185887CB3}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{68A28E4A-3ADE-4187-9625-4FF185887CB3}.Release|x86.ActiveCfg = Release|Any CPU
{68A28E4A-3ADE-4187-9625-4FF185887CB3}.Release|x86.Build.0 = Release|Any CPU
{1D0764B4-1DEB-4232-A714-D4B7E846918A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1D0764B4-1DEB-4232-A714-D4B7E846918A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1D0764B4-1DEB-4232-A714-D4B7E846918A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{1D0764B4-1DEB-4232-A714-D4B7E846918A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{1D0764B4-1DEB-4232-A714-D4B7E846918A}.Debug|x86.ActiveCfg = Debug|Any CPU
{1D0764B4-1DEB-4232-A714-D4B7E846918A}.Debug|x86.Build.0 = Debug|Any CPU
{1D0764B4-1DEB-4232-A714-D4B7E846918A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1D0764B4-1DEB-4232-A714-D4B7E846918A}.Release|Any CPU.Build.0 = Release|Any CPU
{1D0764B4-1DEB-4232-A714-D4B7E846918A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{1D0764B4-1DEB-4232-A714-D4B7E846918A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{1D0764B4-1DEB-4232-A714-D4B7E846918A}.Release|x86.ActiveCfg = Release|Any CPU
{1D0764B4-1DEB-4232-A714-D4B7E846918A}.Release|x86.Build.0 = Release|Any CPU
{E5FACCD4-6327-43AA-80A9-AE6F4A3BFE6A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E5FACCD4-6327-43AA-80A9-AE6F4A3BFE6A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E5FACCD4-6327-43AA-80A9-AE6F4A3BFE6A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{E5FACCD4-6327-43AA-80A9-AE6F4A3BFE6A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{E5FACCD4-6327-43AA-80A9-AE6F4A3BFE6A}.Debug|x86.ActiveCfg = Debug|Any CPU
{E5FACCD4-6327-43AA-80A9-AE6F4A3BFE6A}.Debug|x86.Build.0 = Debug|Any CPU
{E5FACCD4-6327-43AA-80A9-AE6F4A3BFE6A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E5FACCD4-6327-43AA-80A9-AE6F4A3BFE6A}.Release|Any CPU.Build.0 = Release|Any CPU
{E5FACCD4-6327-43AA-80A9-AE6F4A3BFE6A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{E5FACCD4-6327-43AA-80A9-AE6F4A3BFE6A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{E5FACCD4-6327-43AA-80A9-AE6F4A3BFE6A}.Release|x86.ActiveCfg = Release|Any CPU
{E5FACCD4-6327-43AA-80A9-AE6F4A3BFE6A}.Release|x86.Build.0 = Release|Any CPU
{61F72E92-B3AE-4A10-B838-44F80AED40AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{61F72E92-B3AE-4A10-B838-44F80AED40AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{61F72E92-B3AE-4A10-B838-44F80AED40AE}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{61F72E92-B3AE-4A10-B838-44F80AED40AE}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{61F72E92-B3AE-4A10-B838-44F80AED40AE}.Debug|x86.ActiveCfg = Debug|Any CPU
{61F72E92-B3AE-4A10-B838-44F80AED40AE}.Debug|x86.Build.0 = Debug|Any CPU
{61F72E92-B3AE-4A10-B838-44F80AED40AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{61F72E92-B3AE-4A10-B838-44F80AED40AE}.Release|Any CPU.Build.0 = Release|Any CPU
{61F72E92-B3AE-4A10-B838-44F80AED40AE}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{61F72E92-B3AE-4A10-B838-44F80AED40AE}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{61F72E92-B3AE-4A10-B838-44F80AED40AE}.Release|x86.ActiveCfg = Release|Any CPU
{61F72E92-B3AE-4A10-B838-44F80AED40AE}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand All @@ -268,5 +312,8 @@ Global
{7AE2731D-43CD-4CF8-850A-4914DE2CE930} = {F31FF137-390C-49BF-A3BD-7C6ED3597C21}
{BE9112CB-D87D-4080-9CC3-24492D49CBE6} = {A5A15F1C-885A-452A-A731-B0173DDBD913}
{68A28E4A-3ADE-4187-9625-4FF185887CB3} = {A5A15F1C-885A-452A-A731-B0173DDBD913}
{1D0764B4-1DEB-4232-A714-D4B7E846918A} = {982F09D8-621E-4872-BA7B-BBDEA47D1EFD}
{E5FACCD4-6327-43AA-80A9-AE6F4A3BFE6A} = {A5A15F1C-885A-452A-A731-B0173DDBD913}
{61F72E92-B3AE-4A10-B838-44F80AED40AE} = {F31FF137-390C-49BF-A3BD-7C6ED3597C21}
EndGlobalSection
EndGlobal
30 changes: 30 additions & 0 deletions samples/SampleApp/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
using System;
using System.Diagnostics;
using Microsoft.Framework.Primitives;

namespace SampleApp
{
public class Program
{
public void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
Stopwatch timer = new Stopwatch();
timer.Start();
string myString;
string[] myArray;
StringValues myValues;
for (int j = 0; j < 100000000; j++)
{
myString = new string('a', 40);
myArray = new[] { myString };
// myValues = new StringValues(myString);
myValues = new StringValues(myArray);
}
timer.Stop();
Console.WriteLine(timer.Elapsed + ", " + Environment.WorkingSet);
}
}
}
}
20 changes: 20 additions & 0 deletions samples/SampleApp/SampleApp.xproj
Original file line number Diff line number Diff line change
@@ -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>1d0764b4-1deb-4232-a714-d4b7e846918a</ProjectGuid>
<RootNamespace>SampleApp</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>
15 changes: 15 additions & 0 deletions samples/SampleApp/project.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"version": "1.0.0-*",

"dependencies": {
"Microsoft.AspNet.Http": "1.0.0-*"
},

"commands": {
"SampleApp": "SampleApp"
},

"frameworks": {
"dnx451": { }
}
}
45 changes: 12 additions & 33 deletions src/Microsoft.AspNet.Http.Abstractions/IHeaderDictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,30 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Framework.Primitives;

namespace Microsoft.AspNet.Http
{
/// <summary>
/// Represents request and response headers
/// </summary>
public interface IHeaderDictionary : IReadableStringCollection, IDictionary<string, string[]>
public interface IHeaderDictionary : IReadableStringCollection, IDictionary<string, StringValues>
{
// This property is duplicated to resolve an ambiguity between IReadableStringCollection and IDictionary<string, StringValues>
/// <summary>
/// Get or sets the associated value from the collection as a single string.
///
/// </summary>
/// <param name="key">The header name.</param>
/// <returns>the associated value from the collection as a single string or null if the key is not present.</returns>
new string this[string key] { get; set; }
/// <param name="key"></param>
/// <returns>The stored value, or StringValues.Empty if the key is not present.</returns>
new StringValues this[string key] { get; set; }

// This property is duplicated to resolve an ambiguity between IReadableStringCollection.Count and IDictionary<string, string[]>.Count
// This property is duplicated to resolve an ambiguity between IReadableStringCollection.Count and IDictionary<string, StringValues>.Count
/// <summary>
/// Gets the number of elements contained in the collection.
/// </summary>
new int Count { get; }

// This property is duplicated to resolve an ambiguity between IReadableStringCollection.Keys and IDictionary<string, string[]>.Keys
// This property is duplicated to resolve an ambiguity between IReadableStringCollection.Keys and IDictionary<string, StringValues>.Keys
/// <summary>
/// Gets a collection containing the keys.
/// </summary>
Expand All @@ -36,21 +37,14 @@ public interface IHeaderDictionary : IReadableStringCollection, IDictionary<stri
/// </summary>
/// <param name="key">The header name.</param>
/// <returns>the associated values from the collection separated into individual values, or null if the key is not present.</returns>
IList<string> GetCommaSeparatedValues(string key);
StringValues GetCommaSeparatedValues(string key);

/// <summary>
/// Add a new value. Appends to the header if already present
/// Add a new value. Appends to the header list if already present
/// </summary>
/// <param name="key">The header name.</param>
/// <param name="value">The header value.</param>
void Append(string key, string value);

/// <summary>
/// Add new values. Each item remains a separate array entry.
/// </summary>
/// <param name="key">The header name.</param>
/// <param name="values">The header values.</param>
void AppendValues(string key, params string[] values);
void Append(string key, StringValues value);

/// <summary>
/// Quotes any values containing comas, and then coma joins all of the values with any existing values.
Expand All @@ -59,21 +53,6 @@ public interface IHeaderDictionary : IReadableStringCollection, IDictionary<stri
/// <param name="values">The header values.</param>
void AppendCommaSeparatedValues(string key, params string[] values);

/// <summary>
/// Sets a specific header value.
/// </summary>
/// <param name="key">The header name.</param>
/// <param name="value">The header value.</param>
[SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Set", Justification = "Re-evaluate later.")]
void Set(string key, string value);

/// <summary>
/// Sets the specified header values without modification.
/// </summary>
/// <param name="key">The header name.</param>
/// <param name="values">The header values.</param>
void SetValues(string key, params string[] values);

/// <summary>
/// Quotes any values containing comas, and then coma joins all of the values.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Microsoft.Framework.Primitives;

namespace Microsoft.AspNet.Http
{
/// <summary>
/// Accessors for headers, query, forms, etc.
/// </summary>
public interface IReadableStringCollection : IEnumerable<KeyValuePair<string, string[]>>
public interface IReadableStringCollection : IEnumerable<KeyValuePair<string, StringValues>>
{
/// <summary>
/// Get the associated value from the collection. Multiple values will be merged.
/// Returns null if the key is not present.
/// Get the associated value from the collection.
/// Returns StringValues.Empty if the key is not present.
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
string this[string key] { get; }
StringValues this[string key] { get; }

/// <summary>
/// Gets the number of elements contained in the collection.
Expand All @@ -35,22 +35,5 @@ public interface IReadableStringCollection : IEnumerable<KeyValuePair<string, st
/// <param name="key"></param>
/// <returns></returns>
bool ContainsKey(string key);

/// <summary>
/// Get the associated value from the collection. Multiple values will be merged.
/// Returns null if the key is not present.
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
[SuppressMessage("Microsoft.Naming", "CA1716:IdentifiersShouldNotMatchKeywords", MessageId = "Get", Justification = "Re-evaluate later.")]
string Get(string key);

/// <summary>
/// Get the associated values from the collection in their original format.
/// Returns null if the key is not present.
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
IList<string> GetValues(string key);
}
}
3 changes: 2 additions & 1 deletion src/Microsoft.AspNet.Http.Abstractions/QueryString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Text;
using Microsoft.Framework.Internal;
using Microsoft.Framework.Primitives;
using Microsoft.Framework.WebEncoders;

namespace Microsoft.AspNet.Http
Expand Down Expand Up @@ -143,7 +144,7 @@ public static QueryString Create(IEnumerable<KeyValuePair<string, string>> param
/// </summary>
/// <param name="parameters"></param>
/// <returns>The resulting QueryString</returns>
public static QueryString Create(IEnumerable<KeyValuePair<string, string[]>> parameters)
public static QueryString Create(IEnumerable<KeyValuePair<string, StringValues>> parameters)
{
var builder = new StringBuilder();
bool first = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System.Reflection;
using Microsoft.AspNet.Http.Headers;
using Microsoft.Framework.Internal;
using Microsoft.Framework.Primitives;
using Microsoft.Net.Http.Headers;

namespace Microsoft.AspNet.Http
Expand Down Expand Up @@ -50,7 +51,7 @@ internal static void SetList<T>([NotNull] this IHeaderDictionary headers, [NotNu
}
else
{
headers.SetValues(name, values.Select(value => value.ToString()).ToArray());
headers[name] = values.Select(value => value.ToString()).ToArray();
}
}

Expand Down Expand Up @@ -98,7 +99,7 @@ internal static T Get<T>([NotNull] this IHeaderDictionary headers, string name)
}

var value = headers[name];
if (string.IsNullOrWhiteSpace(value))
if (StringValues.IsNullOrEmpty(value))
{
return default(T);
}
Expand All @@ -112,11 +113,11 @@ internal static IList<T> GetList<T>([NotNull] this IHeaderDictionary headers, st
if (KnownListParsers.TryGetValue(typeof(T), out temp))
{
var func = (Func<IList<string>, IList<T>>)temp;
return func(headers.GetValues(name));
return func(headers[name]);
}

var values = headers.GetValues(name);
if (values == null || !values.Any())
var values = headers[name];
if (StringValues.IsNullOrEmpty(values))
{
return null;
}
Expand Down Expand Up @@ -158,7 +159,7 @@ private static T GetViaReflection<T>(string value)
return default(T);
}

private static IList<T> GetListViaReflection<T>(IList<string> values)
private static IList<T> GetListViaReflection<T>(StringValues values)
{
// TODO: Cache the reflected type for later? Only if success?
var type = typeof(T);
Expand Down
2 changes: 1 addition & 1 deletion src/Microsoft.AspNet.Http.Extensions/RequestHeaders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ public void Append([NotNull] string name, [NotNull] object value)

public void AppendList<T>([NotNull] string name, [NotNull] IList<T> values)
{
Headers.AppendValues(name, values.Select(value => value.ToString()).ToArray());
Headers.Append(name, values.Select(value => value.ToString()).ToArray());
}
}
}
2 changes: 1 addition & 1 deletion src/Microsoft.AspNet.Http.Extensions/ResponseHeaders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ public void Append([NotNull] string name, [NotNull] object value)

public void AppendList<T>([NotNull] string name, [NotNull] IList<T> values)
{
Headers.AppendValues(name, values.Select(value => value.ToString()).ToArray());
Headers.Append(name, values.Select(value => value.ToString()).ToArray());
}
}
}
3 changes: 2 additions & 1 deletion src/Microsoft.AspNet.Http.Features/IHttpRequestFeature.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System.Collections.Generic;
using System.IO;
using Microsoft.Framework.Primitives;

namespace Microsoft.AspNet.Http.Features
{
Expand All @@ -14,7 +15,7 @@ public interface IHttpRequestFeature
string PathBase { get; set; }
string Path { get; set; }
string QueryString { get; set; }
IDictionary<string, string[]> Headers { get; set; }
IDictionary<string, StringValues> Headers { get; set; }
Stream Body { get; set; }
}
}
Loading

0 comments on commit 456277f

Please sign in to comment.