62 Commits

Author SHA1 Message Date
Tommy Parnell
3f7ca24155 bump major version #major 2023-10-19 18:41:03 -04:00
Tommy Parnell
628f66b82a Merge pull request #25 from TerribleDev/pr-24
PR-24
2023-10-19 18:28:48 -04:00
Tommy Parnell
abb2c1d18b exclude macos ds_store, and format code 2023-10-19 18:26:35 -04:00
Tommy Parnell
c67a34f993 Merge remote-tracking branch 'origin/master' into pr-24 2023-10-19 18:25:54 -04:00
Tony Valenti
697a745510 Simplified tests and added automatic encoding of name/value pairs. 2023-10-19 17:03:45 -05:00
Tony Valenti
7e303fd08b Better Logo and it is transparent. (#22) #patch 2023-10-08 12:41:04 -04:00
Tony Valenti
737c647cbe Better Logo and it is transparent. 2023-07-12 18:25:03 -05: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
Tommy Parnell
8b053f0f77 minor doc comment 2016-11-12 16:58:01 -05:00
Tommy Parnell
b68af327ab Merge pull request #8 from TerribleDev/1.1
1.1
2016-11-12 16:52:02 -05:00
Tommy Parnell
68bf719c27 Merge pull request #7 from TerribleDev/dictOfParams
Dict of params
2016-11-12 16:49:50 -05:00
Tommy Parnell
3ff3165a42 add exception throw test 2016-11-12 16:40:22 -05:00
Tommy Parnell
16f96b9b27 add dictionary of params 2016-11-12 16:38:10 -05:00
Tommy Parnell
04e2090a95 Merge pull request #5 from TerribleDev/documentation
add docs issue #4
2016-11-12 16:25:34 -05:00
Tommy Parnell
6e3e23061a add docs issue #4 2016-11-12 14:17:46 -05:00
Tommy Parnell
91579a1700 fix nuget package url 2016-11-09 09:35:56 -05:00
Tommy Parnell
d6c78f2193 retarget to 4.5 2016-11-09 09:32:44 -05:00
Tommy Parnell
dbb9f5b404 english 2016-11-09 07:28:29 -05:00
Tommy Parnell
5bfe876f57 add comma 2016-11-09 07:28:08 -05:00
Tommy Parnell
6a31a1968e readme 2016-11-09 07:27:32 -05:00
29 changed files with 723 additions and 302 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

7
.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.
@@ -243,3 +244,9 @@ ModelManifest.xml
# FAKE - F# Make # FAKE - F# Make
.fake/ .fake/
.idea
coverage.opencover.xml
coverage.json
coverage.info
.DS_Store
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,11 +1,16 @@
## 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 builds ontop of trusty UriBuilder, and does not use custom Uri generators, or have outside dependencies. 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!
## 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 This lets you do things like
```csharp ```csharp
new UriBuilder() new UriBuilder()
@@ -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,11 +31,54 @@ or
new UriBuilder("https://awesome.com/yo) new UriBuilder("https://awesome.com/yo)
.WithParameter("id", "5") .WithParameter("id", "5")
.Uri
.ToString(); .ToString();
``` ```
result: `https://awesome.com/yo?id=5` result: `https://awesome.com/yo?id=5`
## Getting started you can even pass a dictionary of parameters
```csharp
var dictionary = new Dictionary<string, string>()
{
["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();
```
result: `http://awesome.com/?yo=dawg%3C`
#### 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`
Just install the nuget package `install-package UriBuilder.Fluent` and thats it. The extension methods should be avalbile to you!

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

@@ -16,7 +16,7 @@ namespace FluentUriBuilder.Tests
{ {
var url = new UriBuilder("http://awesome.com") var url = new UriBuilder("http://awesome.com")
.WithPathSegment(pathWithSlashes); .WithPathSegment(pathWithSlashes);
Assert.Equal("http://awesome.com/" + expectedPath, url.Uri.ToString()); Assert.Equal("http://awesome.com/" + expectedPath, url.ToUriString());
} }
[Fact] [Fact]
@@ -25,7 +25,7 @@ namespace FluentUriBuilder.Tests
var url = new UriBuilder("http://awesome.com") var url = new UriBuilder("http://awesome.com")
.WithPathSegment("yodawg") .WithPathSegment("yodawg")
.WithPathSegment("/immahslash/"); .WithPathSegment("/immahslash/");
Assert.Equal("http://awesome.com/yodawg/immahslash/", url.Uri.ToString()); Assert.Equal("http://awesome.com/yodawg/immahslash/", url.ToUriString());
} }
[Fact] [Fact]
@@ -33,7 +33,28 @@ namespace FluentUriBuilder.Tests
{ {
var url = new UriBuilder("http://awesome.com") var url = new UriBuilder("http://awesome.com")
.WithParameter("awesome", "yodawg"); .WithParameter("awesome", "yodawg");
Assert.Equal("http://awesome.com/?awesome=yodawg", url.Uri.ToString()); Assert.Equal("http://awesome.com/?awesome=yodawg", url.ToUriString());
}
[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.ToUriString());
}
[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]
@@ -41,7 +62,7 @@ namespace FluentUriBuilder.Tests
{ {
var url = new UriBuilder("http://awesome.com") var url = new UriBuilder("http://awesome.com")
.WithParameter("awesome", "cool", "dawg"); .WithParameter("awesome", "cool", "dawg");
Assert.Equal("http://awesome.com/?awesome=cool,dawg", url.Uri.ToString()); Assert.Equal("http://awesome.com/?awesome=cool,dawg", url.ToUriString());
} }
[Fact] [Fact]
@@ -49,7 +70,7 @@ namespace FluentUriBuilder.Tests
{ {
var url = new UriBuilder("http://awesome.com") var url = new UriBuilder("http://awesome.com")
.WithParameter("awesome", new List<int>() { 1, 2 }.Cast<object>()); .WithParameter("awesome", new List<int>() { 1, 2 }.Cast<object>());
Assert.Equal("http://awesome.com/?awesome=1,2", url.Uri.ToString()); Assert.Equal("http://awesome.com/?awesome=1,2", url.ToUriString());
} }
[Fact] [Fact]
@@ -57,28 +78,68 @@ namespace FluentUriBuilder.Tests
{ {
var url = new UriBuilder("http://awesome.com") var url = new UriBuilder("http://awesome.com")
.WithParameter("awesome"); .WithParameter("awesome");
Assert.Equal("http://awesome.com/?awesome", url.Uri.ToString()); Assert.Equal("http://awesome.com/?awesome", url.ToUriString());
}
[Fact]
public void TestAddFragmentArray()
{
var url = new UriBuilder("http://awesome.com")
.WithFragment("awesome", "cool", "dawg");
Assert.Equal("http://awesome.com/#awesome=cool,dawg", url.ToUriString());
}
[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.ToUriString());
}
[Fact]
public void TestAddFragmentNoValue()
{
var url = new UriBuilder("http://awesome.com")
.WithFragment("awesome");
Assert.Equal("http://awesome.com/#awesome", url.ToUriString());
} }
[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.ToUriString());
url = new UriBuilder("http://awesome.com:443")
.WithoutDefaultPort();
Assert.Equal("http://awesome.com:443/", url.ToUriString());
url = new UriBuilder("https://awesome.com:443")
.WithoutDefaultPort();
Assert.Equal("https://awesome.com/", url.ToUriString());
} }
[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]
@@ -104,7 +165,7 @@ namespace FluentUriBuilder.Tests
.WithParameter("awesome", "yodawg") .WithParameter("awesome", "yodawg")
.WithParameter("fun", null) .WithParameter("fun", null)
.WithParameter("cool", string.Empty); .WithParameter("cool", string.Empty);
Assert.Equal("http://awesome.com/?awesome=yodawg&fun&cool", url.Uri.ToString()); Assert.Equal("http://awesome.com/?awesome=yodawg&fun&cool", url.ToUriString());
} }
[Fact] [Fact]
@@ -114,7 +175,64 @@ namespace FluentUriBuilder.Tests
.WithParameter("awesome", "yodawg") .WithParameter("awesome", "yodawg")
.WithParameter("supg", "no2") .WithParameter("supg", "no2")
.WithParameter("supgf", "no22"); .WithParameter("supgf", "no22");
Assert.Equal("http://awesome.com/?awesome=yodawg&supg=no2&supgf=no22", url.Uri.ToString()); Assert.Equal("http://awesome.com/?awesome=yodawg&supg=no2&supgf=no22", url.ToUriString());
} }
[Fact]
public void AddDictOfParams()
{
var dictionary = new Dictionary<string, string>()
{
["yo"] = "dawg",
["troll"] = "toll",
["hammer"] = string.Empty
};
var url = new UriBuilder("http://awesome.com")
.WithParameter(dictionary);
Assert.Equal("http://awesome.com/?yo=dawg&troll=toll&hammer", url.ToUriString());
}
[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.ToUriString());
}
[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.ToUriString());
}
[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.ToUriString());
}
[Fact]
public void TestToEscapedString()
{
var url = new UriBuilder("http://awesome.com")
.WithParameter("yo", "dawg<");
Assert.Equal("http://awesome.com/?yo=dawg<", url.ToUriString());
}
} }
} }

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,10 +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((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,52 +1,189 @@
using System; using System.Collections.Generic;
using System.Collections.Generic; using System.Data.SqlTypes;
using System.IO;
using System.Linq; 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>
/// 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.
/// </summary>
/// <param name="bld"></param>
/// <param name="key"></param>
/// <param name="values"></param>
/// <exception cref="ArgumentNullException"></exception>
/// <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);
public static UriBuilder WithParameter(this UriBuilder bld, string key, IEnumerable<object> valuesEnum) /// <summary>
/// Appends query strings from a list of key-value pairs (usually a dictionary).
/// </summary>
/// <param name="bld"></param>
/// <param name="parameterDictionary"></param>
/// <exception cref="ArgumentNullException"></exception>
/// <returns></returns>
public static UriBuilder WithParameter(this UriBuilder bld, IEnumerable<KeyValuePair<string, string>> parameterDictionary)
{ {
if(string.IsNullOrWhiteSpace(key)) if (bld == null)
{ {
throw new ArgumentNullException(nameof(key)); throw new ArgumentNullException(nameof(bld));
} }
if(valuesEnum == null) if (parameterDictionary == null)
{ {
valuesEnum = new string[0]; throw new ArgumentNullException(nameof(parameterDictionary));
} }
var isfirst = string.IsNullOrWhiteSpace(bld.Query); foreach (var item in parameterDictionary)
var intitialValue = isfirst ? "" : $"{bld.Query.TrimStart('?')}&";
var sb = new StringBuilder($"{intitialValue}{key}");
var validValueHit = false;
foreach(var value in valuesEnum)
{ {
var toSValue = value?.ToString(); bld.WithParameter(item.Key, item.Value);
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(',');
return bld; return bld;
} }
/// <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.
/// </summary>
/// <param name="bld"></param>
/// <param name="key"></param>
/// <param name="valuesEnum"></param>
/// <exception cref="ArgumentNullException"></exception>
/// <returns></returns>
public static UriBuilder WithParameter(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.Query) ? "" : $"{bld.Query.TrimStart('?')}&";
bld.Query = intitialValue.AppendKeyValue(key, valuesEnum);
return bld;
}
/// <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)
{
throw new ArgumentNullException(nameof(bld));
}
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;
}
/// <summary>
/// Sets the port to be the port number
/// </summary>
/// <param name="bld"></param>
/// <param name="port"></param>
/// <exception cref="ArgumentOutOfRangeException">Throws if port is less than one</exception>
/// <exception cref="ArgumentNullException"></exception>
/// <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>
/// appends a path segment to the path. Can be called multiple times to append multiple segments
/// </summary>
/// <param name="bld"></param>
/// <param name="pathSegment"></param>
/// <exception cref="ArgumentNullException">You pass a string as a path segment</exception>
/// <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));
} }
@@ -55,24 +192,115 @@ namespace System
return bld; return bld;
} }
/// <summary>
/// Sets your Uri Scheme
/// </summary>
/// <param name="bld"></param>
/// <param name="scheme"></param>
/// <exception cref="ArgumentNullException">You must pass a scheme</exception>
/// <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;
} }
/// <summary>
///
/// </summary>
/// <param name="bld"></param>
/// <param name="host"></param>
/// <exception cref="ArgumentNullException">You must pass a ho0st</exception>
/// <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>
/// Use Https?
/// </summary>
/// <param name="bld"></param>
/// <param name="predicate">default true, if false sets scheme to http</param>
/// <exception cref="ArgumentNullException"></exception>
/// <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>
/// Returns the Uri string
/// </summary>
/// <param name="bld"></param>
/// <exception cref="ArgumentNullException"></exception>
/// <returns></returns>
public static string ToUriString(this UriBuilder bld) => 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 encodedKey = Uri.EscapeDataString(key);
var sb = new StringBuilder($"{intitialValue}{encodedKey}");
var Values = (
from x in valuesEnum
let v = x?.ToString()
where !string.IsNullOrWhiteSpace(v)
select Uri.EscapeDataString(v)
).ToArray();
if (Values.Length > 0)
{
sb.Append("=");
sb.Append(string.Join(",", Values));
}
return sb.ToString();
}
} }
} }

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/tparnell8/TurboLinks.Net",
"summary": "Fluent extensions for UriBuilder",
"tags": [
"Url building",
"Uri",
"Uri building",
"fluent",
"extension"
]
},
"dependencies": {
"NETStandard.Library": "1.6.0"
},
"authors": [
"Tommy Parnell"
],
"frameworks": {
"netstandard1.3": {
"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