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

Introduce StringValues to replace string[] usage. #378

Merged
merged 2 commits into from
Aug 28, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

??

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": { }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not run on .NET Core 5.0?

}
}
68 changes: 9 additions & 59 deletions src/Microsoft.AspNet.Http.Abstractions/IHeaderDictionary.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,83 +2,33 @@
// 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>
new ICollection<string> Keys { get; }

/// <summary>
/// Get the associated values from the collection separated into individual values.
/// Quoted values will not be split, and the quotes will be removed.
/// </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);

/// <summary>
/// Add a new value. Appends to the header 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);

/// <summary>
/// Quotes any values containing comas, and then coma joins all of the values with any existing values.
/// </summary>
/// <param name="key">The header name.</param>
/// <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>
/// <param name="key">The header name.</param>
/// <param name="values">The header values.</param>
void SetCommaSeparatedValues(string key, params string[] values);
}
}
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
52 changes: 52 additions & 0 deletions src/Microsoft.AspNet.Http.Extensions/HeaderDictionaryExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
// 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.AspNet.Http.Internal;
using Microsoft.Framework.Primitives;

namespace Microsoft.AspNet.Http
{
public static class HeaderDictionaryExtensions
{
/// <summary>
/// Add new values. Each item remains a separate array entry.
/// </summary>
/// <param name="key">The header name.</param>
/// <param name="value">The header value.</param>
public static void Append(this IHeaderDictionary headers, string key, StringValues value)
{
ParsingHelpers.AppendHeaderUnmodified(headers, key, value);
}

/// <summary>
/// Quotes any values containing comas, and then coma joins all of the values with any existing values.
/// </summary>
/// <param name="key">The header name.</param>
/// <param name="values">The header values.</param>
public static void AppendCommaSeparatedValues(this IHeaderDictionary headers, string key, params string[] values)
{
ParsingHelpers.AppendHeaderJoined(headers, key, values);
}

/// <summary>
/// Get the associated values from the collection separated into individual values.
/// Quoted values will not be split, and the quotes will be removed.
/// </summary>
/// <param name="key">The header name.</param>
/// <returns>the associated values from the collection separated into individual values, or StringValues.Empty if the key is not present.</returns>
public static string[] GetCommaSeparatedValues(this IHeaderDictionary headers, string key)
{
return ParsingHelpers.GetHeaderSplit(headers, key);
}

/// <summary>
/// Quotes any values containing comas, and then coma joins all of the values.
/// </summary>
/// <param name="key">The header name.</param>
/// <param name="values">The header values.</param>
public static void SetCommaSeparatedValues(this IHeaderDictionary headers, string key, params string[] values)
{
ParsingHelpers.SetHeaderJoined(headers, key, values);
}
}
}
Loading