44 Commits
1.2 ... 2.1.1

Author SHA1 Message Date
Tony Valenti
7e303fd08b Better Logo and it is transparent. (#22) #patch 2023-10-08 12:41:04 -04:00
Tommy Parnell
730ee07822 add tuple api back that was accidentally removed (#21) 2023-07-12 15:51:23 -04:00
Tommy Parnell
ccf3a7a688 I hate ci #major 2023-07-12 15:37:39 -04:00
Tommy Parnell
3f7df6e00e #major Add overload for IEnumerable<KeyValuePair<string, string>>
#major

* Added overload for IEnumerable<KeyValuePair<string, string>>
* Updated to netstandard 2.0
* Added package icon
2023-07-12 15:31:44 -04:00
Tommy Parnell
22f9a8e64b update tests add github actions 2023-07-12 14:18:56 -04:00
Tony Valenti
6c9a2904a6 Use NetStandard instead of explicit versions. 2023-07-12 08:43:34 -05:00
Tony Valenti
d8bd1ce612 Updated Appveyor. I think. 2023-07-11 21:52:01 -05:00
Tony Valenti
aa1e0600da Updated versions
Added overload for IEnumerable<KeyValuePair<string, string>>
Added icon
Standardized {'s around validation
2023-07-11 21:48:44 -05:00
Tommy Parnell
819235eedb Merge pull request #17 from TerribleDev/nullchk
null checks
2018-04-14 18:06:28 -04:00
Tommy Parnell
d3a9225930 null checks 2018-04-14 18:00:53 -04:00
Tommy Parnell
638d077c03 Merge pull request #15 from adriangodong/fixed-bad-fragment-char
Fixed bad fragment char
2017-10-20 02:06:47 -04:00
Adrian Godong
b9e6ad6a8b Added more tests to cover WithFragment(). 2017-10-19 23:02:58 -07:00
Adrian Godong
542561d778 Fixed bad fragment marker char. 2017-10-19 23:02:43 -07:00
Tommy Parnell
dc1b82f0ab Merge pull request #14 from adriangodong/add-fragment-extensions
Add extension methods to add URL fragments
2017-10-19 23:44:17 -04:00
Adrian Godong
8c036b0986 Refactored key value encoding into a separate method. 2017-10-19 20:40:21 -07:00
Adrian Godong
d5caf139e9 Added extension methods to add fragments. 2017-10-19 20:17:08 -07:00
Tommy Parnell
ccc3f229d0 fix readme 2017-07-06 10:50:38 -04:00
Tommy Parnell
4bf5ed64dc remove debug type 2017-07-05 17:49:20 -04:00
Tommy Parnell
59887c06c0 fix nuget key 2017-07-05 17:46:03 -04:00
Tommy Parnell
1a82f9db70 Merge pull request #13 from TerribleDev/newproj
Newproj
2017-07-05 17:42:13 -04:00
Tommy Parnell
8b66bdcd92 remove code coverage for now 2017-07-05 17:39:27 -04:00
Tommy Parnell
4ce00cf6bb oldstyle 2017-07-05 17:37:03 -04:00
Tommy Parnell
edfb21960a one more try 2017-07-05 17:33:55 -04:00
Tommy Parnell
4db92f4965 try a seperate build for coverage 2017-07-05 17:31:26 -04:00
Tommy Parnell
65b437f5f3 target multi frame 2017-07-05 17:27:09 -04:00
Tommy Parnell
a75d4fab2a try again 2017-07-05 17:23:38 -04:00
Tommy Parnell
63c25a8c6e add test adapter back 2017-07-05 17:09:51 -04:00
Tommy Parnell
87e9cb4b85 fix xunit 2017-07-05 17:05:52 -04:00
Tommy Parnell
fa1e78cb24 full pdb files 2017-07-05 17:02:49 -04:00
Tommy Parnell
ad7ff272a6 fix script 2017-07-05 16:53:27 -04:00
Tommy Parnell
58f03ea1af build in release 2017-07-05 16:52:26 -04:00
Tommy Parnell
00f8f60971 build with full for coveralls 2017-07-05 16:51:15 -04:00
Tommy Parnell
84742e8f47 build with full for coveralls 2017-07-05 16:51:00 -04:00
Tommy Parnell
bb75e3006e fix coverage script 2017-07-05 16:40:56 -04:00
Tommy Parnell
68956cded5 dont download core 2017-07-05 16:39:51 -04:00
Tommy Parnell
ec67f8ad1d fix ref 2017-07-05 16:38:58 -04:00
Tommy Parnell
2011b935d9 use new proj 2017-07-05 16:37:42 -04:00
Peter Dolkens
526f7b04c8 Fix expected values 2017-07-05 12:00:24 +01:00
Peter Dolkens
9dc6c4a466 Add support for WithoutDefaultPort as WithPort doesn't allow "-1" to be sent to hide DefaultPorts 2017-07-05 11:57:23 +01:00
khyteang-lim
9b1d037a88 Added ToEscapeString() and ToEscapeDataString() (#11)
* Added ToEscapeString() and ToEscapeDataString(), added desciption in readme, and added unit tests

* added changes from PR feedback
2017-01-30 17:42:11 -05:00
Tommy Parnell
be92d91ef6 readd 461 2016-12-13 13:47:17 -05:00
Tommy Parnell
a1527c058c add path and query 2016-12-13 13:44:06 -05:00
Tommy Parnell
908d0e2433 target 45 2016-12-13 10:57:40 -05:00
Tommy Parnell
e9f3e5ed8b target 40 2016-12-06 07:48:41 -05:00
29 changed files with 618 additions and 301 deletions

44
.github/workflows/pr.yml vendored Normal file
View File

@@ -0,0 +1,44 @@
name: PR Build
on:
pull_request:
branches:
- master
jobs:
# dotnet test
build-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET Core
uses: actions/setup-dotnet@v3
with:
dotnet-version: 7.x.x
- name: Build
run: make build
- name: Test
run: make test
pack:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET Core
uses: actions/setup-dotnet@v3
with:
dotnet-version: 7.x.x
- name: Pack
run: VERSION=0.0.1 make pack
- name: Upload Build Artifacts
uses: actions/upload-artifact@v3
with:
name: pr-build-${{ github.event.pull_request.number }}-${{ github.sha }}
path: ./output/**
check-format:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET Core
uses: actions/setup-dotnet@v3
with:
dotnet-version: 7.x.x
- name: Check Format
run: make check-format

73
.github/workflows/publish.yml vendored Normal file
View File

@@ -0,0 +1,73 @@
name: Publish
on:
push:
branches:
- master
jobs:
check-format:
environment: master
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup .NET Core
uses: actions/setup-dotnet@v3
with:
dotnet-version: 7.x.x
- name: Check Format
run: make check-format
test:
environment: master
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup .NET Core
uses: actions/setup-dotnet@v3
with:
dotnet-version: 7.x.x
- name: Build
run: make build
- name: Test
run: make test
- name: Upload Coveralls
uses: coverallsapp/github-action@master
with:
github-token: ${{ secrets.GITHUB_TOKEN }}
path-to-lcov: ./src/UriBuilder.Fluent.UnitTests/coverage.info
tag:
needs: [check-format, test]
outputs:
tagVersion: ${{ steps.tagVersion.outputs.new_tag }}
runs-on: ubuntu-latest
environment: master
steps:
- name: Checkout source code
uses: actions/checkout@v3
- name: Bump version and push tag
uses: anothrNick/github-tag-action@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
WITH_V: false
DEFAULT_BUMP: minor
id: tagVersion
build:
env:
VERSION: ${{ needs.tag.outputs.tagVersion }}
NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }}
runs-on: ubuntu-latest
environment: master
needs: [check-format, test, tag]
steps:
- uses: actions/checkout@v2
- name: Setup .NET Core
uses: actions/setup-dotnet@v3
with:
dotnet-version: 7.x.x
- name: Build and Pack
run: make pack
- name: Upload Build Artifacts
uses: actions/upload-artifact@v3
with:
name: release-build-${{ needs.tag.outputs.tagVersion }}
path: ./output/**
- name: Publish to NuGet
run: make publish

8
.gitignore vendored
View File

@@ -148,6 +148,7 @@ publish/
# NuGet Packages # NuGet Packages
*.nupkg *.nupkg
*.snupkg
# The packages folder can be ignored because of Package Restore # The packages folder can be ignored because of Package Restore
**/packages/* **/packages/*
# except build/, which is used as an MSBuild target. # except build/, which is used as an MSBuild target.
@@ -242,4 +243,9 @@ ModelManifest.xml
.paket/paket.exe .paket/paket.exe
# FAKE - F# Make # FAKE - F# Make
.fake/ .fake/
.idea
coverage.opencover.xml
coverage.json
coverage.info
output

23
.vscode/launch.json vendored
View File

@@ -1,23 +0,0 @@
{
"version": "0.2.0",
"configurations": [
{
"name": ".NET Core Launch (console)",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build",
"program": "${workspaceRoot}/bin/Debug/<target-framework>/<project-name.dll>",
"args": [],
"cwd": "${workspaceRoot}",
"externalConsole": false,
"stopAtEntry": false,
"internalConsoleOptions": "openOnSessionStart"
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command.pickProcess}"
}
]
}

3
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"dotnet.defaultSolution": "UriBuilder.Fluent.sln"
}

16
.vscode/tasks.json vendored
View File

@@ -1,16 +0,0 @@
{
"version": "0.1.0",
"command": "dotnet",
"isShellCommand": true,
"args": [],
"tasks": [
{
"taskName": "build",
"args": [
""
],
"isBuildCommand": true,
"problemMatcher": "$msCompile"
}
]
}

View File

@@ -1,11 +0,0 @@
if($env:APPVEYOR_REPO_TAG -eq "true")
{
"do not publish coverall data on tag builds"
return
}
nuget install OpenCover -Version 4.6.519 -OutputDirectory tools
nuget install coveralls.net -Version 0.7.0 -OutputDirectory tools
.\tools\OpenCover.4.6.519\tools\OpenCover.Console.exe -target:"C:\Program Files\dotnet\dotnet.exe" -targetargs:" test "".\src\UriBuilder.Fluent.UnitTests"" -f net461" -register:user -filter:"+[UriBuilder*]* -[*Tests]*" -returntargetcode -output:opencover_results.xml
.\tools\coveralls.net.0.7.0\tools\csmacnz.Coveralls.exe --opencover -i .\opencover_results.xml

21
Makefile Normal file
View File

@@ -0,0 +1,21 @@
clean:
dotnet clean && rm -rf ./**/bin ./**/obj && rm -rf output
build: clean restore
dotnet build --no-restore
restore: clean
dotnet restore
test:
dotnet test /p:CollectCoverage=true
release-build: clean restore
dotnet build -c Release --no-restore
pack: release-build
dotnet pack src/UriBuilder.Fluent/UriBuilder.Fluent.csproj --configuration Release --output output
publish:
dotnet nuget push output/*.nupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key $(NUGET_API_KEY)
dotnet nuget push output/*.snupkg --source https://api.nuget.org/v3/index.json --skip-duplicate --api-key $(NUGET_API_KEY)
coveralls-push:
dotnet tool install -g coveralls.net
coverallsnet --opencover -i UriBuilder.Fluent.UnitTests/coverage.opencover.xml --useRelativePaths
check-format:
dotnet format --verify-no-changes
default: clean build

View File

@@ -1,10 +1,15 @@
## UriBuilder.Fluent # UriBuilder.Fluent
[![Coverage Status](https://coveralls.io/repos/github/TerribleDev/UriBuilder.Fluent/badge.svg)](https://coveralls.io/github/TerribleDev/UriBuilder.Fluent) [![Build status](https://ci.appveyor.com/api/projects/status/cp704w3bgaerufxm/branch/master?svg=true)](https://ci.appveyor.com/project/tparnell8/uribuilder-fluent/branch/master) [![Coverage Status](https://coveralls.io/repos/github/TerribleDev/UriBuilder.Fluent/badge.svg)](https://coveralls.io/github/TerribleDev/UriBuilder.Fluent) [![Build status](https://ci.appveyor.com/api/projects/status/cp704w3bgaerufxm/branch/master?svg=true)](https://ci.appveyor.com/project/tparnell8/uribuilder-fluent/branch/master)
This places extension methods over System.UriBuilder to help deal with query string parameters, and create more of a fluent interface. Unlike other projects, this NetStandardLibrary compliant package builds ontop of trusty UriBuilder, does not use custom Uri generators, or have outside dependencies. Unit tests continue to be a first class citizen! This places extension methods over System.UriBuilder to help deal with query string parameters, and create more of a fluent interface. Unlike other projects, this NetStandardLibrary compliant package builds ontop of trusty UriBuilder, does not use custom Uri generators, or have outside dependencies. Unit tests continue to be a first class citizen!
This lets you do things like ## Getting started
Just install the nuget package `install-package UriBuilder.Fluent` and thats it. The extension methods should be available to you!
## Code Example
This lets you do things like
```csharp ```csharp
@@ -14,10 +19,9 @@ new UriBuilder()
.WithHost("awesome.com") .WithHost("awesome.com")
.WithPathSegment("seg") .WithPathSegment("seg")
.UseHttps() .UseHttps()
.Uri
.ToString() .ToString()
``` ```
result: `https://awesome.com/seg?awesome=yodawg&fun=cool,yay` result: `https://awesome.com/seg?awesome=yodawg&fun=cool,yay`
@@ -27,6 +31,7 @@ or
new UriBuilder("https://awesome.com/yo) new UriBuilder("https://awesome.com/yo)
.WithParameter("id", "5") .WithParameter("id", "5")
.Uri
.ToString(); .ToString();
``` ```
@@ -35,16 +40,44 @@ result: `https://awesome.com/yo?id=5`
you can even pass a dictionary of parameters you can even pass a dictionary of parameters
```csharp ```csharp
var dictionary = new Dictionary<string, string>()
{ var dictionary = new Dictionary<string, string>()
["yo"] = "dawg" {
}; ["yo"] = "dawg"
new UriBuilder("http://awesome.com") };
.WithParameter(dictionary);
http://awesome.com/?yo=dawg new UriBuilder("http://awesome.com")
.WithParameter(dictionary);
```
result: `http://awesome.com/?yo=dawg`
### ToEscapeString() vs. ToEscapeDataString()
There are two extension methods for performing Uri encoding.
#### ToEscapeString()
Performs encoding only on the Uri query string and returns the Uri as a string.
```csharp
var uri = new UriBuilder("https://awesome.com")
.WithParameter("yo", "dawg<")
.ToEscapeString();
``` ```
## Getting started result: `http://awesome.com/?yo=dawg%3C`
Just install the nuget package `install-package UriBuilder.Fluent` and thats it. The extension methods should be available to you! #### ToEscapeDataString()
Performs encoding on the whole Uri and returns the Uri as a string.
```csharp
var uri = new UriBuilder("https://awesome.com")
.WithParameter("yo", "dawg<")
.ToEscapeDataString();
```
result: `http%3A%2F%2Fawesome.com%2F%3Fyo%3Ddawg%3C`

View File

@@ -1,41 +1,34 @@
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14 # Visual Studio Version 17
VisualStudioVersion = 14.0.25420.1 VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{B4EB6F69-0F56-4875-95AD-E4DEB5D18A74}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{BE84C3E5-BA06-4A89-A786-62423FF4A87F}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{AC680F4D-C1B2-4F06-8464-CC987B1F0008}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UriBuilder.Fluent", "src\UriBuilder.Fluent\UriBuilder.Fluent.csproj", "{81D561B6-AB75-4A65-B770-20EEF16E6AF7}"
ProjectSection(SolutionItems) = preProject
appveyor.yml = appveyor.yml
global.json = global.json
Readme.md = Readme.md
EndProjectSection
EndProject EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "UriBuilder.Fluent", "src\UriBuilder.Fluent\UriBuilder.Fluent.xproj", "{B8458F59-DEBD-4844-AA29-EE3B4388AA7A}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UriBuilder.Fluent.UnitTests", "src\UriBuilder.Fluent.UnitTests\UriBuilder.Fluent.UnitTests.csproj", "{87BEA737-87E0-4114-986F-6080FA58B187}"
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "UriBuilder.Fluent.UnitTests", "src\UriBuilder.Fluent.UnitTests\UriBuilder.Fluent.UnitTests.xproj", "{F421A9EE-180C-413E-A0CD-665295825646}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU Release|Any CPU = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B8458F59-DEBD-4844-AA29-EE3B4388AA7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B8458F59-DEBD-4844-AA29-EE3B4388AA7A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B8458F59-DEBD-4844-AA29-EE3B4388AA7A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B8458F59-DEBD-4844-AA29-EE3B4388AA7A}.Release|Any CPU.Build.0 = Release|Any CPU
{F421A9EE-180C-413E-A0CD-665295825646}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F421A9EE-180C-413E-A0CD-665295825646}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F421A9EE-180C-413E-A0CD-665295825646}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F421A9EE-180C-413E-A0CD-665295825646}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{81D561B6-AB75-4A65-B770-20EEF16E6AF7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{81D561B6-AB75-4A65-B770-20EEF16E6AF7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{81D561B6-AB75-4A65-B770-20EEF16E6AF7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{81D561B6-AB75-4A65-B770-20EEF16E6AF7}.Release|Any CPU.Build.0 = Release|Any CPU
{87BEA737-87E0-4114-986F-6080FA58B187}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{87BEA737-87E0-4114-986F-6080FA58B187}.Debug|Any CPU.Build.0 = Debug|Any CPU
{87BEA737-87E0-4114-986F-6080FA58B187}.Release|Any CPU.ActiveCfg = Release|Any CPU
{87BEA737-87E0-4114-986F-6080FA58B187}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution GlobalSection(NestedProjects) = preSolution
{B8458F59-DEBD-4844-AA29-EE3B4388AA7A} = {B4EB6F69-0F56-4875-95AD-E4DEB5D18A74} {81D561B6-AB75-4A65-B770-20EEF16E6AF7} = {BE84C3E5-BA06-4A89-A786-62423FF4A87F}
{F421A9EE-180C-413E-A0CD-665295825646} = {B4EB6F69-0F56-4875-95AD-E4DEB5D18A74} {87BEA737-87E0-4114-986F-6080FA58B187} = {BE84C3E5-BA06-4A89-A786-62423FF4A87F}
EndGlobalSection EndGlobalSection
EndGlobal EndGlobal

BIN
UriBulider.Fluent.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -1,34 +0,0 @@
configuration: Release
version: 1.0.{build}
nuget:
account_feed: true
project_feed: true
artifacts:
- path: 'src\**\*.nupkg'
init:
- git config --global core.autocrlf true
before_build:
- ps: invoke-webrequest https://go.microsoft.com/fwlink/?LinkID=827524 -OutFile core.exe
- ps: .\core.exe /install /quiet /norestart
build_script:
- ps: dotnet restore
- ps: dotnet build -c Release .\src\UriBuilder.Fluent
- ps: dotnet build -c Release .\src\UriBuilder.Fluent.UnitTests
test_script:
- ps: dotnet test -c Release .\src\UriBuilder.Fluent.UnitTests
- ps: .\Coverage.ps1
- ps: .\update-projectjson.ps1
- ps: dotnet restore
- ps: dotnet pack -c Release .\src\UriBuilder.Fluent
deploy:
- provider: NuGet
api_key:
secure: QuVcKEvDkLsmdemVpoGBXiTymN46CzvczrDpTHNf1+tTIjOGufptGDmBD9r5LVtn
on:
appveyor_repo_tag: true

View File

@@ -1,6 +1,7 @@
{ {
"projects": [ "src", "test" ],
"sdk": { "sdk": {
"version": "1.0.0-preview2-003131" "version": "7.0.0",
"rollForward": "latestMajor",
"allowPrerelease": false
} }
} }

View File

@@ -35,6 +35,27 @@ namespace FluentUriBuilder.Tests
.WithParameter("awesome", "yodawg"); .WithParameter("awesome", "yodawg");
Assert.Equal("http://awesome.com/?awesome=yodawg", url.Uri.ToString()); Assert.Equal("http://awesome.com/?awesome=yodawg", url.Uri.ToString());
} }
[Fact]
public void TestAddUrlParameterAsTupleList()
{
var url = new UriBuilder("http://awesome.com")
.WithParameter(new List<(string, string)>()
{
("awesome", "yodawg")
});
Assert.Equal("http://awesome.com/?awesome=yodawg", url.Uri.ToString());
}
[Fact]
public void PathAndQuery()
{
var url = new UriBuilder().WithPathSegment("/awesome/v1/").WithParameter("awesome", "cool").PathAndQuery();
Assert.Equal("/awesome/v1/?awesome=cool", url);
url = new UriBuilder().WithPathSegment("/awesome/v1").WithParameter("awesome", "cool").PathAndQuery();
Assert.Equal("/awesome/v1?awesome=cool", url);
url = new UriBuilder().WithPathSegment("/awesome/v1").PathAndQuery();
Assert.Equal("/awesome/v1", url);
}
[Fact] [Fact]
public void TestAddParameterArray() public void TestAddParameterArray()
@@ -60,25 +81,65 @@ namespace FluentUriBuilder.Tests
Assert.Equal("http://awesome.com/?awesome", url.Uri.ToString()); Assert.Equal("http://awesome.com/?awesome", url.Uri.ToString());
} }
[Fact]
public void TestAddFragmentArray()
{
var url = new UriBuilder("http://awesome.com")
.WithFragment("awesome", "cool", "dawg");
Assert.Equal("http://awesome.com/#awesome=cool,dawg", url.Uri.ToString());
}
[Fact]
public void TestAddFragmentArrayint()
{
var url = new UriBuilder("http://awesome.com")
.WithFragment("awesome", new List<int>() { 1, 2 }.Cast<object>());
Assert.Equal("http://awesome.com/#awesome=1,2", url.Uri.ToString());
}
[Fact]
public void TestAddFragmentNoValue()
{
var url = new UriBuilder("http://awesome.com")
.WithFragment("awesome");
Assert.Equal("http://awesome.com/#awesome", url.Uri.ToString());
}
[Fact] [Fact]
public void WithPort() public void WithPort()
{ {
var url = new UriBuilder().WithPort(22); var url = new UriBuilder().WithPort(22);
Assert.Equal(url.Port, 22); Assert.Equal(22, url.Port);
}
[Fact]
public void WithoutDefaultPort()
{
var url = new UriBuilder("http://awesome.com:80")
.WithoutDefaultPort();
Assert.Equal("http://awesome.com/", url.Uri.ToString());
url = new UriBuilder("http://awesome.com:443")
.WithoutDefaultPort();
Assert.Equal("http://awesome.com:443/", url.Uri.ToString());
url = new UriBuilder("https://awesome.com:443")
.WithoutDefaultPort();
Assert.Equal("https://awesome.com/", url.Uri.ToString());
} }
[Fact] [Fact]
public void WithHttps() public void WithHttps()
{ {
var url = new UriBuilder().UseHttps(true); var url = new UriBuilder().UseHttps(true);
Assert.Equal(url.Scheme, "https"); Assert.Equal("https", url.Scheme);
} }
[Fact] [Fact]
public void WithHttp() public void WithHttp()
{ {
var url = new UriBuilder().UseHttps(false); var url = new UriBuilder().UseHttps(false);
Assert.Equal(url.Scheme, "http"); Assert.Equal("http", url.Scheme);
} }
[Fact] [Fact]
@@ -86,7 +147,7 @@ namespace FluentUriBuilder.Tests
{ {
//the jesus scheme? //the jesus scheme?
var url = new UriBuilder().WithScheme("jesus"); var url = new UriBuilder().WithScheme("jesus");
Assert.Equal(url.Scheme, "jesus"); Assert.Equal("jesus", url.Scheme);
} }
[Fact] [Fact]
@@ -94,7 +155,7 @@ namespace FluentUriBuilder.Tests
{ {
//the jesus scheme? //the jesus scheme?
var url = new UriBuilder().WithHost("yodawg.com"); var url = new UriBuilder().WithHost("yodawg.com");
Assert.Equal(url.Host, "yodawg.com"); Assert.Equal("yodawg.com", url.Host);
} }
[Fact] [Fact]
@@ -130,5 +191,55 @@ namespace FluentUriBuilder.Tests
.WithParameter(dictionary); .WithParameter(dictionary);
Assert.Equal("http://awesome.com/?yo=dawg&troll=toll&hammer", url.Uri.ToString()); Assert.Equal("http://awesome.com/?yo=dawg&troll=toll&hammer", url.Uri.ToString());
} }
[Fact]
public void AddFragmentWithNoValue()
{
var url = new UriBuilder("http://awesome.com")
.WithFragment("awesome", "yodawg")
.WithFragment("fun", null)
.WithFragment("cool", string.Empty);
Assert.Equal("http://awesome.com/#awesome=yodawg&fun&cool", url.Uri.ToString());
}
[Fact]
public void TestAddTwoUrlFragments()
{
var url = new UriBuilder("http://awesome.com")
.WithFragment("awesome", "yodawg")
.WithFragment("supg", "no2")
.WithFragment("supgf", "no22");
Assert.Equal("http://awesome.com/#awesome=yodawg&supg=no2&supgf=no22", url.Uri.ToString());
}
[Fact]
public void AddDictOfFragments()
{
var dictionary = new Dictionary<string, string>()
{
["yo"] = "dawg",
["troll"] = "toll",
["hammer"] = string.Empty
};
var url = new UriBuilder("http://awesome.com")
.WithFragment(dictionary);
Assert.Equal("http://awesome.com/#yo=dawg&troll=toll&hammer", url.Uri.ToString());
}
[Fact]
public void TestToEscapedString()
{
var url = new UriBuilder("http://awesome.com")
.WithParameter("yo", "dawg<");
Assert.Equal("http://awesome.com/?yo=dawg%3C", url.ToEscapeString());
}
[Fact]
public void TestToEscapedDataString()
{
var url = new UriBuilder("http://awesome.com")
.WithParameter("yo", "dawg<");
Assert.Equal("http%3A%2F%2Fawesome.com%2F%3Fyo%3Ddawg%3C", url.ToEscapeDataString());
}
} }
} }

View File

@@ -1,19 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("UriBuilder.Fluent.UnitTests")]
[assembly: AssemblyTrademark("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("f421a9ee-180c-413e-a0cd-665295825646")]

View File

@@ -13,11 +13,27 @@ namespace FluentUriBuilder.Tests
{ {
var tstObj = new UriBuilder(); var tstObj = new UriBuilder();
Assert.Throws<ArgumentNullException>(() => tstObj.WithParameter(string.Empty, string.Empty)); Assert.Throws<ArgumentNullException>(() => tstObj.WithParameter(string.Empty, string.Empty));
Assert.Throws<ArgumentNullException>(() => tstObj.WithFragment(string.Empty, string.Empty));
Assert.Throws<ArgumentNullException>(() => tstObj.WithPathSegment(null)); Assert.Throws<ArgumentNullException>(() => tstObj.WithPathSegment(null));
Assert.Throws<ArgumentNullException>(() => tstObj.WithScheme(null)); Assert.Throws<ArgumentNullException>(() => tstObj.WithScheme(null));
Assert.Throws<ArgumentNullException>(() => tstObj.WithHost(null)); Assert.Throws<ArgumentNullException>(() => tstObj.WithHost(null));
Assert.Throws<ArgumentNullException>(() => tstObj.WithParameter(parameterDictionary: null)); Assert.Throws<ArgumentNullException>(() => tstObj.WithParameter((IEnumerable<KeyValuePair<string, string>>)null));
Assert.Throws<ArgumentNullException>(() => tstObj.WithParameter((IEnumerable<(string, string)>)null));
Assert.Throws<ArgumentNullException>(() => tstObj.WithFragment(fragmentDictionary: null));
Assert.Throws<ArgumentOutOfRangeException>(() => tstObj.WithPort(-1)); Assert.Throws<ArgumentOutOfRangeException>(() => tstObj.WithPort(-1));
UriBuilder nullPtr = null;
Assert.Throws<ArgumentNullException>(() => nullPtr.WithFragment("yo", "dawg"));
Assert.Throws<ArgumentNullException>(() => nullPtr.WithFragment(new Dictionary<string, string>()));
Assert.Throws<ArgumentNullException>(() => nullPtr.WithParameter("yo", "dawg"));
Assert.Throws<ArgumentNullException>(() => nullPtr.WithPathSegment("yo"));
Assert.Throws<ArgumentNullException>(() => nullPtr.WithScheme("yo"));
Assert.Throws<ArgumentNullException>(() => nullPtr.WithFragment("yo"));
Assert.Throws<ArgumentNullException>(() => nullPtr.WithoutDefaultPort());
Assert.Throws<ArgumentNullException>(() => nullPtr.WithoutDefaultPort());
Assert.Throws<ArgumentNullException>(() => nullPtr.WithPort(1));
Assert.Throws<ArgumentNullException>(() => nullPtr.WithHost("yo"));
Assert.Throws<ArgumentNullException>(() => nullPtr.UseHttps());
Assert.Throws<ArgumentNullException>(() => nullPtr.WithParameter((IEnumerable<(string, string)>)null));
} }
} }
} }

View File

@@ -0,0 +1,33 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>disable</Nullable>
<IsPackable>false</IsPackable>
<CoverletOutputFormat>lcov</CoverletOutputFormat>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.msbuild" Version="6.0.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="3.1.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\UriBuilder.Fluent\UriBuilder.Fluent.csproj" />
</ItemGroup>
</Project>

View File

@@ -1,22 +0,0 @@
<?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)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>f421a9ee-180c-413e-a0cd-665295825646</ProjectGuid>
<RootNamespace>UriBuilder.Fluent.UnitTests</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<ItemGroup>
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
</ItemGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ActiveDebugProfile>Start</ActiveDebugProfile>
</PropertyGroup>
</Project>

View File

@@ -0,0 +1 @@
global using Xunit;

View File

@@ -1,22 +0,0 @@
{
"version": "1.0.0-*",
"testRunner": "xunit",
"dependencies": {
"xunit": "2.2.0-beta2-build3300",
"dotnet-test-xunit": "2.2.0-preview2-build1029",
"UriBuilder.Fluent": "1.0.0-*"
},
"frameworks": {
"net461": {},
"netcoreapp1.0": {
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0"
}
}
}
}
}

View File

@@ -5,10 +5,6 @@ using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following // General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("UriBuilder.Fluent")]
[assembly: AssemblyTrademark("")]
// Setting ComVisible to false makes the types in this assembly not visible // Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from // to COM components. If you need to access a type in this assembly from

View File

@@ -1,12 +1,9 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks;
namespace System namespace System
{ {
public static class TerribleDevUriExtensions public static partial class TerribleDevUriExtensions
{ {
/// <summary> /// <summary>
/// Appends a query string parameter with a key, and many values. Multiple values will be comma seperated. If only 1 value is passed and its null or value, the key will be added to the QS. /// Appends a query string parameter with a key, and many values. Multiple values will be comma seperated. If only 1 value is passed and its null or value, the key will be added to the QS.
@@ -14,20 +11,28 @@ namespace System
/// <param name="bld"></param> /// <param name="bld"></param>
/// <param name="key"></param> /// <param name="key"></param>
/// <param name="values"></param> /// <param name="values"></param>
/// <exception cref="ArgumentNullException"></exception>
/// <returns></returns> /// <returns></returns>
public static UriBuilder WithParameter(this UriBuilder bld, string key, params string[] values) => bld.WithParameter(key, valuesEnum: values); public static UriBuilder WithParameter(this UriBuilder bld, string key, params string[] values) => bld.WithParameter(key, valuesEnum: values);
/// <summary> /// <summary>
/// Appends query strings from dictionary /// Appends query strings from a list of key-value pairs (usually a dictionary).
/// </summary> /// </summary>
/// <param name="bld"></param> /// <param name="bld"></param>
/// <param name="parameterDictionary"></param> /// <param name="parameterDictionary"></param>
/// <exception cref="ArgumentNullException"></exception> /// <exception cref="ArgumentNullException"></exception>
/// <returns></returns> /// <returns></returns>
public static UriBuilder WithParameter(this UriBuilder bld, IDictionary<string, string> parameterDictionary) public static UriBuilder WithParameter(this UriBuilder bld, IEnumerable<KeyValuePair<string, string>> parameterDictionary)
{ {
if(parameterDictionary == null) throw new ArgumentNullException(nameof(parameterDictionary)); if (bld == null)
foreach(var item in parameterDictionary) {
throw new ArgumentNullException(nameof(bld));
}
if (parameterDictionary == null)
{
throw new ArgumentNullException(nameof(parameterDictionary));
}
foreach (var item in parameterDictionary)
{ {
bld.WithParameter(item.Key, item.Value); bld.WithParameter(item.Key, item.Value);
} }
@@ -40,30 +45,85 @@ namespace System
/// <param name="bld"></param> /// <param name="bld"></param>
/// <param name="key"></param> /// <param name="key"></param>
/// <param name="valuesEnum"></param> /// <param name="valuesEnum"></param>
/// <exception cref="ArgumentNullException"></exception>
/// <returns></returns> /// <returns></returns>
public static UriBuilder WithParameter(this UriBuilder bld, string key, IEnumerable<object> valuesEnum) public static UriBuilder WithParameter(this UriBuilder bld, string key, IEnumerable<object> valuesEnum)
{ {
if(string.IsNullOrWhiteSpace(key)) if (bld == null)
{
throw new ArgumentNullException(nameof(bld));
}
if (string.IsNullOrWhiteSpace(key))
{ {
throw new ArgumentNullException(nameof(key)); throw new ArgumentNullException(nameof(key));
} }
if(valuesEnum == null) if (valuesEnum == null)
{ {
valuesEnum = new string[0]; valuesEnum = new string[0];
} }
var intitialValue = string.IsNullOrWhiteSpace(bld.Query) ? "" : $"{bld.Query.TrimStart('?')}&"; var intitialValue = string.IsNullOrWhiteSpace(bld.Query) ? "" : $"{bld.Query.TrimStart('?')}&";
var sb = new StringBuilder($"{intitialValue}{key}"); bld.Query = intitialValue.AppendKeyValue(key, valuesEnum);
var validValueHit = false; return bld;
foreach(var value in valuesEnum) }
/// <summary>
/// Appends a fragments parameter with a key, and many values. Multiple values will be comma seperated. If only 1 value is passed and its null or value, the key will be added to the fragment.
/// </summary>
/// <param name="bld"></param>
/// <param name="key"></param>
/// <param name="values"></param>
/// <exception cref="ArgumentNullException"></exception>
/// <returns></returns>
public static UriBuilder WithFragment(this UriBuilder bld, string key, params string[] values) => bld.WithFragment(key, valuesEnum: values);
/// <summary>
/// Appends fragments from dictionary
/// </summary>
/// <param name="bld"></param>
/// <param name="fragmentDictionary"></param>
/// <exception cref="ArgumentNullException"></exception>
/// <returns></returns>
public static UriBuilder WithFragment(this UriBuilder bld, IDictionary<string, string> fragmentDictionary)
{
if (bld == null)
{ {
var toSValue = value?.ToString(); throw new ArgumentNullException(nameof(bld));
if(string.IsNullOrWhiteSpace(toSValue)) continue;
// we can't just have an = sign since its valid to have query string paramters with no value;
if(!validValueHit) toSValue = "=" + value;
validValueHit = true;
sb.Append($"{toSValue},");
} }
bld.Query = sb.ToString().TrimEnd(','); if (fragmentDictionary == null)
{
throw new ArgumentNullException(nameof(fragmentDictionary));
}
foreach (var item in fragmentDictionary)
{
bld.WithFragment(item.Key, item.Value);
}
return bld;
}
/// <summary>
/// Appends a fragments with a key, and many values. Multiple values will be comma seperated. If only 1 value is passed and its null or value, the key will be added to the fragment.
/// </summary>
/// <param name="bld"></param>
/// <param name="key"></param>
/// <param name="valuesEnum"></param>
/// <exception cref="ArgumentNullException"></exception>
/// <returns></returns>
public static UriBuilder WithFragment(this UriBuilder bld, string key, IEnumerable<object> valuesEnum)
{
if (bld == null)
{
throw new ArgumentNullException(nameof(bld));
}
if (string.IsNullOrWhiteSpace(key))
{
throw new ArgumentNullException(nameof(key));
}
if (valuesEnum == null)
{
valuesEnum = new string[0];
}
var intitialValue = string.IsNullOrWhiteSpace(bld.Fragment) ? "" : $"{bld.Fragment.TrimStart('#')}&";
bld.Fragment = intitialValue.AppendKeyValue(key, valuesEnum);
return bld; return bld;
} }
@@ -73,14 +133,40 @@ namespace System
/// <param name="bld"></param> /// <param name="bld"></param>
/// <param name="port"></param> /// <param name="port"></param>
/// <exception cref="ArgumentOutOfRangeException">Throws if port is less than one</exception> /// <exception cref="ArgumentOutOfRangeException">Throws if port is less than one</exception>
/// <exception cref="ArgumentNullException"></exception>
/// <returns></returns> /// <returns></returns>
public static UriBuilder WithPort(this UriBuilder bld, int port) public static UriBuilder WithPort(this UriBuilder bld, int port)
{ {
if(port < 1) throw new ArgumentOutOfRangeException(nameof(port)); if (bld == null)
{
throw new ArgumentNullException(nameof(bld));
}
if (port < 1)
{
throw new ArgumentOutOfRangeException(nameof(port));
}
bld.Port = port; bld.Port = port;
return bld; return bld;
} }
/// <summary>
/// Removes the port number for default ports
/// </summary>
/// <param name="bld"></param>
/// <returns></returns>
public static UriBuilder WithoutDefaultPort(this UriBuilder bld)
{
if (bld == null)
{
throw new ArgumentNullException(nameof(bld));
}
if (bld.Uri.IsDefaultPort)
{
bld.Port = -1;
}
return bld;
}
/// <summary> /// <summary>
/// appends a path segment to the path. Can be called multiple times to append multiple segments /// appends a path segment to the path. Can be called multiple times to append multiple segments
/// </summary> /// </summary>
@@ -90,7 +176,11 @@ namespace System
/// <returns></returns> /// <returns></returns>
public static UriBuilder WithPathSegment(this UriBuilder bld, string pathSegment) public static UriBuilder WithPathSegment(this UriBuilder bld, string pathSegment)
{ {
if(string.IsNullOrWhiteSpace(pathSegment)) if (bld == null)
{
throw new ArgumentNullException(nameof(bld));
}
if (string.IsNullOrWhiteSpace(pathSegment))
{ {
throw new ArgumentNullException(nameof(pathSegment)); throw new ArgumentNullException(nameof(pathSegment));
} }
@@ -108,7 +198,14 @@ namespace System
/// <returns></returns> /// <returns></returns>
public static UriBuilder WithScheme(this UriBuilder bld, string scheme) public static UriBuilder WithScheme(this UriBuilder bld, string scheme)
{ {
if(string.IsNullOrWhiteSpace(scheme)) throw new ArgumentNullException(nameof(scheme)); if (bld == null)
{
throw new ArgumentNullException(nameof(bld));
}
if (string.IsNullOrWhiteSpace(scheme))
{
throw new ArgumentNullException(nameof(scheme));
}
bld.Scheme = scheme; bld.Scheme = scheme;
return bld; return bld;
} }
@@ -122,21 +219,71 @@ namespace System
/// <returns></returns> /// <returns></returns>
public static UriBuilder WithHost(this UriBuilder bld, string host) public static UriBuilder WithHost(this UriBuilder bld, string host)
{ {
if(string.IsNullOrWhiteSpace(host)) throw new ArgumentNullException(nameof(host)); if (bld == null)
{
throw new ArgumentNullException(nameof(bld));
}
if (string.IsNullOrWhiteSpace(host))
{
throw new ArgumentNullException(nameof(host));
}
bld.Host = host; bld.Host = host;
return bld; return bld;
} }
public static string PathAndQuery(this UriBuilder bld) => (bld.Path + bld.Query);
/// <summary> /// <summary>
/// Use Https? /// Use Https?
/// </summary> /// </summary>
/// <param name="bld"></param> /// <param name="bld"></param>
/// <param name="predicate">default true, if false sets scheme to http</param> /// <param name="predicate">default true, if false sets scheme to http</param>
/// <exception cref="ArgumentNullException"></exception>
/// <returns></returns> /// <returns></returns>
public static UriBuilder UseHttps(this UriBuilder bld, bool predicate = true) public static UriBuilder UseHttps(this UriBuilder bld, bool predicate = true)
{ {
if (bld == null)
{
throw new ArgumentNullException(nameof(bld));
}
bld.Scheme = predicate ? "https" : "http"; bld.Scheme = predicate ? "https" : "http";
return bld; return bld;
} }
/// <summary>
/// Escape Url query string
/// </summary>
/// <param name="bld"></param>
/// <exception cref="ArgumentNullException"></exception>
/// <returns></returns>
public static string ToEscapeString(this UriBuilder bld) => Uri.EscapeUriString(bld.Uri.ToString());
/// <summary>
/// Escape the whole Url string
/// </summary>
/// <param name="bld"></param>
/// <exception cref="ArgumentNullException"></exception>
/// <returns></returns>
public static string ToEscapeDataString(this UriBuilder bld) => Uri.EscapeDataString(bld.Uri.ToString());
/// <summary>
/// Appends x-www-form-urlencoded key and valuesEnum into initialValue.
/// </summary>
/// <exception cref="ArgumentNullException"></exception>
private static string AppendKeyValue(this string intitialValue, string key, IEnumerable<object> valuesEnum)
{
var sb = new StringBuilder($"{intitialValue}{key}");
var validValueHit = false;
foreach (var value in valuesEnum)
{
var toSValue = value?.ToString();
if (string.IsNullOrWhiteSpace(toSValue)) continue;
// we can't just have an = sign since its valid to have query string paramters with no value;
if (!validValueHit) toSValue = "=" + value;
validValueHit = true;
sb.Append($"{toSValue},");
}
return sb.ToString().TrimEnd(',');
}
} }
} }

View File

@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace System
{
public static partial class TerribleDevUriExtensions
{
/// <summary>
/// Appends query strings from dictionary
/// </summary>
/// <param name="bld"></param>
/// <param name="parameterDictionary"></param>
/// <exception cref="ArgumentNullException"></exception>
/// <returns></returns>
public static UriBuilder WithParameter(this UriBuilder bld, IEnumerable<(string, string)> parameterDictionary)
{
if (bld == null)
{
throw new ArgumentNullException(nameof(bld));
}
if (parameterDictionary == null) throw new ArgumentNullException(nameof(parameterDictionary));
foreach (var item in parameterDictionary)
{
bld.WithParameter(item.Item1, item.Item2);
}
return bld;
}
}
}

View File

@@ -0,0 +1,31 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Authors>Tommy Parnell</Authors>
<AssemblyName>UriBuilder.Fluent</AssemblyName>
<PackageId>UriBuilder.Fluent</PackageId>
<PackageTags>Url building;Uri;Uri building;fluent;extension</PackageTags>
<PackageProjectUrl>https://github.com/TerribleDev/UriBuilder.Fluent</PackageProjectUrl>
<PackageIcon>UriBulider.Fluent.png</PackageIcon>
<PackageIconUrl />
<TargetFramework>netstandard2.0</TargetFramework>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<EmbedUntrackedSources>true</EmbedUntrackedSources>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<PackageReleaseNotes>
This package adds extension methods over System.UriBuilder to help deal with query string parameters and create more of a fluent interface.
Unlike other projects, this NetStandardLibrary compliant package builds ontop of trusty UriBuilder, does not use custom Uri generators, and has no outside dependencies!
</PackageReleaseNotes>
</PropertyGroup>
<ItemGroup>
<None Include="..\..\Readme.md" Pack="true" PackagePath="\" />
<None Include="..\..\UriBulider.Fluent.png" Pack="true" PackagePath="\" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="All" />
</ItemGroup>
</Project>

View File

@@ -1,21 +0,0 @@
<?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)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>b8458f59-debd-4844-aa29-ee3b4388aa7a</ProjectGuid>
<RootNamespace>UriBuilder.Fluent</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
<TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ActiveDebugProfile>Start</ActiveDebugProfile>
</PropertyGroup>
</Project>

View File

@@ -1,28 +0,0 @@
{
"version": "1.0.0-*",
"packOptions": {
"owners": [
"Tommy Parnell"
],
"projectUrl": "https://github.com/TerribleDev/UriBuilder.Fluent",
"summary": "Fluent extensions for UriBuilder",
"tags": [
"Url building",
"Uri",
"Uri building",
"fluent",
"extension"
]
},
"dependencies": {
"NETStandard.Library": "1.6.0"
},
"authors": [
"Tommy Parnell"
],
"frameworks": {
"netstandard1.1": {
"imports": "dnxcore50"
}
}
}

View File

@@ -1,16 +0,0 @@
$projectJsonFileLocation = "src/UriBuilder.Fluent/project.json"
$newVersion = $env:APPVEYOR_REPO_TAG_NAME
if($newVersion -eq $null)
{
$newVersion = "1.0.0-${env:APPVEYOR_BUILD_NUMBER}"
}
if($newVersion -eq $null)
{
return
}
Write-Host "$projectJsonFileLocation will be update with new version '$newVersion'"
$json = (Get-Content $projectJsonFileLocation -Raw) | ConvertFrom-Json
$json.version = $newVersion
$json | ConvertTo-Json -depth 100 | Out-File $projectJsonFileLocation