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

Commit af279f6

Browse files
committed
#65 Add a QueryBuilder.
1 parent 80ffd26 commit af279f6

File tree

7 files changed

+279
-1
lines changed

7 files changed

+279
-1
lines changed

HttpAbstractions.sln

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio 14
4-
VisualStudioVersion = 14.0.21806.0
4+
VisualStudioVersion = 14.0.21916.0
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{A5A15F1C-885A-452A-A731-B0173DDBD913}"
77
EndProject
@@ -29,6 +29,10 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Http.Exten
2929
EndProject
3030
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.Http.Extensions.Tests", "test\Microsoft.AspNet.Http.Extensions.Tests\Microsoft.AspNet.Http.Extensions.Tests.kproj", "{AE25EF21-7F91-4B86-B73E-AF746821D339}"
3131
EndProject
32+
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.WebUtilities", "src\Microsoft.AspNet.WebUtilities\Microsoft.AspNet.WebUtilities.kproj", "{A2FB7838-0031-4FAD-BA3E-83C30B3AF406}"
33+
EndProject
34+
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNet.WebUtilities.Tests", "test\Microsoft.AspNet.WebUtilities.Tests\Microsoft.AspNet.WebUtilities.Tests.kproj", "{93C10E50-BCBB-4D8E-9492-D46E1396225B}"
35+
EndProject
3236
Global
3337
GlobalSection(SolutionConfigurationPlatforms) = preSolution
3438
Debug|Any CPU = Debug|Any CPU
@@ -149,6 +153,26 @@ Global
149153
{AE25EF21-7F91-4B86-B73E-AF746821D339}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
150154
{AE25EF21-7F91-4B86-B73E-AF746821D339}.Release|Mixed Platforms.Build.0 = Release|Any CPU
151155
{AE25EF21-7F91-4B86-B73E-AF746821D339}.Release|x86.ActiveCfg = Release|Any CPU
156+
{A2FB7838-0031-4FAD-BA3E-83C30B3AF406}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
157+
{A2FB7838-0031-4FAD-BA3E-83C30B3AF406}.Debug|Any CPU.Build.0 = Debug|Any CPU
158+
{A2FB7838-0031-4FAD-BA3E-83C30B3AF406}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
159+
{A2FB7838-0031-4FAD-BA3E-83C30B3AF406}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
160+
{A2FB7838-0031-4FAD-BA3E-83C30B3AF406}.Debug|x86.ActiveCfg = Debug|Any CPU
161+
{A2FB7838-0031-4FAD-BA3E-83C30B3AF406}.Release|Any CPU.ActiveCfg = Release|Any CPU
162+
{A2FB7838-0031-4FAD-BA3E-83C30B3AF406}.Release|Any CPU.Build.0 = Release|Any CPU
163+
{A2FB7838-0031-4FAD-BA3E-83C30B3AF406}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
164+
{A2FB7838-0031-4FAD-BA3E-83C30B3AF406}.Release|Mixed Platforms.Build.0 = Release|Any CPU
165+
{A2FB7838-0031-4FAD-BA3E-83C30B3AF406}.Release|x86.ActiveCfg = Release|Any CPU
166+
{93C10E50-BCBB-4D8E-9492-D46E1396225B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
167+
{93C10E50-BCBB-4D8E-9492-D46E1396225B}.Debug|Any CPU.Build.0 = Debug|Any CPU
168+
{93C10E50-BCBB-4D8E-9492-D46E1396225B}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
169+
{93C10E50-BCBB-4D8E-9492-D46E1396225B}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
170+
{93C10E50-BCBB-4D8E-9492-D46E1396225B}.Debug|x86.ActiveCfg = Debug|Any CPU
171+
{93C10E50-BCBB-4D8E-9492-D46E1396225B}.Release|Any CPU.ActiveCfg = Release|Any CPU
172+
{93C10E50-BCBB-4D8E-9492-D46E1396225B}.Release|Any CPU.Build.0 = Release|Any CPU
173+
{93C10E50-BCBB-4D8E-9492-D46E1396225B}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
174+
{93C10E50-BCBB-4D8E-9492-D46E1396225B}.Release|Mixed Platforms.Build.0 = Release|Any CPU
175+
{93C10E50-BCBB-4D8E-9492-D46E1396225B}.Release|x86.ActiveCfg = Release|Any CPU
152176
EndGlobalSection
153177
GlobalSection(SolutionProperties) = preSolution
154178
HideSolutionNode = FALSE
@@ -165,5 +189,7 @@ Global
165189
{16219571-3268-4D12-8689-12B7163DBA13} = {F31FF137-390C-49BF-A3BD-7C6ED3597C21}
166190
{CCC4363E-81E2-4058-94DD-00494E9E992A} = {A5A15F1C-885A-452A-A731-B0173DDBD913}
167191
{AE25EF21-7F91-4B86-B73E-AF746821D339} = {F31FF137-390C-49BF-A3BD-7C6ED3597C21}
192+
{A2FB7838-0031-4FAD-BA3E-83C30B3AF406} = {A5A15F1C-885A-452A-A731-B0173DDBD913}
193+
{93C10E50-BCBB-4D8E-9492-D46E1396225B} = {F31FF137-390C-49BF-A3BD-7C6ED3597C21}
168194
EndGlobalSection
169195
EndGlobal
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<PropertyGroup>
4+
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">12.0</VisualStudioVersion>
5+
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
6+
</PropertyGroup>
7+
<PropertyGroup>
8+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
9+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
10+
</PropertyGroup>
11+
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.Props" Condition="'$(VSToolsPath)' != ''" />
12+
<PropertyGroup Label="Globals">
13+
<ProjectGuid>a2fb7838-0031-4fad-ba3e-83c30b3af406</ProjectGuid>
14+
<OutputType>Library</OutputType>
15+
<RootNamespace>Microsoft.AspNet.WebUtilities</RootNamespace>
16+
</PropertyGroup>
17+
<PropertyGroup Condition="$(OutputType) == 'Console'">
18+
<DebuggerFlavor>ConsoleDebugger</DebuggerFlavor>
19+
</PropertyGroup>
20+
<PropertyGroup Condition="$(OutputType) == 'Web'">
21+
<DebuggerFlavor>WebDebugger</DebuggerFlavor>
22+
</PropertyGroup>
23+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'" Label="Configuration">
24+
</PropertyGroup>
25+
<PropertyGroup>
26+
<SchemaVersion>2.0</SchemaVersion>
27+
</PropertyGroup>
28+
<ItemGroup>
29+
<Content Include="project.json" />
30+
</ItemGroup>
31+
<ItemGroup>
32+
<Compile Include="QueryBuilder.cs" />
33+
</ItemGroup>
34+
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
35+
</Project>
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Collections;
6+
using System.Collections.Generic;
7+
using System.Text;
8+
using Microsoft.AspNet.Http;
9+
10+
namespace Microsoft.AspNet.WebUtilities
11+
{
12+
// The IEnumerable interface is required for the collection initialization syntax: new QueryBuilder() { { "key", "value" } };
13+
public class QueryBuilder : IEnumerable<KeyValuePair<string, string>>
14+
{
15+
private IList<KeyValuePair<string, string>> _params;
16+
17+
public QueryBuilder()
18+
{
19+
_params = new List<KeyValuePair<string, string>>();
20+
}
21+
22+
public QueryBuilder(IEnumerable<KeyValuePair<string, string>> parameters)
23+
{
24+
_params = new List<KeyValuePair<string, string>>(parameters);
25+
}
26+
27+
public void Add(string key, string value)
28+
{
29+
_params.Add(new KeyValuePair<string, string>(key, value));
30+
}
31+
32+
public override string ToString()
33+
{
34+
var builder = new StringBuilder();
35+
bool first = true;
36+
for (int i = 0; i < _params.Count; i++)
37+
{
38+
var pair = _params[i];
39+
builder.Append(first ? "?" : "&");
40+
first = false;
41+
builder.Append(Uri.EscapeDataString(pair.Key));
42+
builder.Append("=");
43+
builder.Append(Uri.EscapeDataString(pair.Value));
44+
}
45+
46+
return builder.ToString();
47+
}
48+
49+
public QueryString ToQueryString()
50+
{
51+
return new QueryString(ToString());
52+
}
53+
54+
public override int GetHashCode()
55+
{
56+
return ToQueryString().GetHashCode();
57+
}
58+
59+
public override bool Equals(object obj)
60+
{
61+
return ToQueryString().Equals(obj);
62+
}
63+
64+
public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
65+
{
66+
return _params.GetEnumerator();
67+
}
68+
69+
IEnumerator IEnumerable.GetEnumerator()
70+
{
71+
return _params.GetEnumerator();
72+
}
73+
}
74+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"version": "1.0.0-*",
3+
"dependencies": {
4+
"Microsoft.AspNet.Http": "1.0.0-*"
5+
},
6+
"frameworks": {
7+
"net45": {},
8+
"k10": {
9+
"dependencies": {
10+
"System.Runtime": "4.0.20.0"
11+
}
12+
}
13+
}
14+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<PropertyGroup>
4+
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">12.0</VisualStudioVersion>
5+
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
6+
</PropertyGroup>
7+
<PropertyGroup>
8+
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
9+
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
10+
</PropertyGroup>
11+
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.Props" Condition="'$(VSToolsPath)' != ''" />
12+
<PropertyGroup Label="Globals">
13+
<ProjectGuid>93c10e50-bcbb-4d8e-9492-d46e1396225b</ProjectGuid>
14+
<OutputType>Library</OutputType>
15+
<RootNamespace>Microsoft.AspNet.WebUtilities.Tests</RootNamespace>
16+
</PropertyGroup>
17+
<PropertyGroup Condition="$(OutputType) == 'Console'">
18+
<DebuggerFlavor>ConsoleDebugger</DebuggerFlavor>
19+
</PropertyGroup>
20+
<PropertyGroup Condition="$(OutputType) == 'Web'">
21+
<DebuggerFlavor>WebDebugger</DebuggerFlavor>
22+
</PropertyGroup>
23+
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'" Label="Configuration">
24+
</PropertyGroup>
25+
<PropertyGroup>
26+
<SchemaVersion>2.0</SchemaVersion>
27+
</PropertyGroup>
28+
<ItemGroup>
29+
<Content Include="project.json" />
30+
</ItemGroup>
31+
<ItemGroup>
32+
<Compile Include="QueryBuilderTests.cs" />
33+
</ItemGroup>
34+
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
35+
</Project>
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using Xunit;
7+
8+
namespace Microsoft.AspNet.WebUtilities
9+
{
10+
public class QueryBuilderTests
11+
{
12+
[Fact]
13+
public void EmptyQuery_NoQuestionMark()
14+
{
15+
var builder = new QueryBuilder();
16+
Assert.Equal(string.Empty, builder.ToString());
17+
}
18+
19+
[Fact]
20+
public void AddSimple_NoEncoding()
21+
{
22+
var builder = new QueryBuilder();
23+
builder.Add("key", "value");
24+
Assert.Equal("?key=value", builder.ToString());
25+
}
26+
27+
[Fact]
28+
public void AddSpace_PercentEncoded()
29+
{
30+
var builder = new QueryBuilder();
31+
builder.Add("key", "value 1");
32+
Assert.Equal("?key=value%201", builder.ToString());
33+
}
34+
35+
[Fact]
36+
public void AddReservedCharacters_PercentEncoded()
37+
{
38+
var builder = new QueryBuilder();
39+
builder.Add("key&", "value#");
40+
Assert.Equal("?key%26=value%23", builder.ToString());
41+
}
42+
43+
[Fact]
44+
public void AddMultipleValues_AddedInOrder()
45+
{
46+
var builder = new QueryBuilder();
47+
builder.Add("key1", "value1");
48+
builder.Add("key2", "value2");
49+
builder.Add("key3", "value3");
50+
Assert.Equal("?key1=value1&key2=value2&key3=value3", builder.ToString());
51+
}
52+
53+
[Fact]
54+
public void AddMultipleValuesViaConstructor_AddedInOrder()
55+
{
56+
var builder = new QueryBuilder(new[]
57+
{
58+
new KeyValuePair<string, string>("key1", "value1"),
59+
new KeyValuePair<string, string>("key2", "value2"),
60+
new KeyValuePair<string, string>("key3", "value3"),
61+
});
62+
Assert.Equal("?key1=value1&key2=value2&key3=value3", builder.ToString());
63+
}
64+
65+
[Fact]
66+
public void AddMultipleValuesViaInitializer_AddedInOrder()
67+
{
68+
var builder = new QueryBuilder()
69+
{
70+
{ "key1", "value1" },
71+
{ "key2", "value2" },
72+
{ "key3", "value3" },
73+
};
74+
Assert.Equal("?key1=value1&key2=value2&key3=value3", builder.ToString());
75+
}
76+
}
77+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"dependencies": {
3+
"Microsoft.AspNet.Http": "",
4+
"Microsoft.AspNet.WebUtilities": "",
5+
"Xunit.KRunner": "1.0.0-*"
6+
},
7+
"commands": {
8+
"test": "Xunit.KRunner"
9+
},
10+
"frameworks": {
11+
"net45": {
12+
"dependencies": {
13+
"System.Runtime": ""
14+
}
15+
}
16+
}
17+
}

0 commit comments

Comments
 (0)