├── .gitattributes
├── .gitignore
├── .nuget
└── NuGet.Config
├── DynamicRest.UnitTests
├── DynamicRest.UnitTests.csproj
├── Fluent
│ └── RestClientBuilderTests.cs
├── Json
│ └── JsonResponsesTest.cs
├── RestClients
│ ├── HttpVerbRequestBuilderTests.cs
│ └── TemplatedUriRequestBuilderTests.cs
├── Simulators
│ └── ResponseSimulatorTests.cs
├── TestDoubles
│ ├── FakeHttpRequestFactory.cs
│ ├── FakeHttpWebRequestWrapper.cs
│ ├── FakeHttpWebResponseWrapper.cs
│ └── FakeWebProxy.cs
└── Xml
│ └── XmlResponsesTests.cs
├── DynamicRest.sln
├── DynamicRest
├── BinaryResponseProcessor.cs
├── DynamicParsingException.cs
├── DynamicRest.csproj
├── Fluent
│ ├── IRestClientBuilder.cs
│ └── RestClientBuilder.cs
├── HTTPInterfaces
│ ├── HttpVerb.cs
│ ├── HttpWebRequestWrappers
│ │ ├── HttpWebRequestFactory.cs
│ │ ├── HttpWebRequestWrapper.cs
│ │ └── HttpWebResponseWrapper.cs
│ ├── IHttpRequest.cs
│ ├── IHttpRequestFactory.cs
│ ├── IHttpResponse.cs
│ └── WebWrappers
│ │ ├── HttpWebRequestWrapper.cs
│ │ ├── HttpWebResponseWrapper.cs
│ │ └── RequestFactory.cs
├── Helpers
│ └── HttpVerbHelpers.cs
├── HttpVerbRequestBuilder.cs
├── IBuildDynamicResults.cs
├── IBuildRequests.cs
├── IProcessResponses.cs
├── IRestUriTransformer.cs
├── Json
│ ├── JsonArray.cs
│ ├── JsonObject.cs
│ ├── JsonReader.cs
│ └── JsonWriter.cs
├── ParametersStore.cs
├── ResponseProcessor.cs
├── RestCallback.cs
├── RestClient.cs
├── RestOperation.cs
├── RestService.cs
├── StandardResultBuilder.cs
├── TemplatedUriBuilder.cs
├── TemplatedUriRequestBuilder.cs
└── Xml
│ ├── XmlNode.cs
│ ├── XmlNodeList.cs
│ └── XmlString.cs
├── License.txt
├── README.md
└── Samples
├── AmazonSample.cs
├── AmazonUriSigner.cs
├── BingSearchSample.cs
├── GoogleSearchSample.cs
├── JsonSample.cs
├── Program.cs
├── Samples.csproj
└── Services.cs
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | build/
21 | bld/
22 | [Bb]in/
23 | [Oo]bj/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | artifacts/
46 |
47 | *_i.c
48 | *_p.c
49 | *_i.h
50 | *.ilk
51 | *.meta
52 | *.obj
53 | *.pch
54 | *.pdb
55 | *.pgc
56 | *.pgd
57 | *.rsp
58 | *.sbr
59 | *.tlb
60 | *.tli
61 | *.tlh
62 | *.tmp
63 | *.tmp_proj
64 | *.log
65 | *.vspscc
66 | *.vssscc
67 | .builds
68 | *.pidb
69 | *.svclog
70 | *.scc
71 |
72 | # Chutzpah Test files
73 | _Chutzpah*
74 |
75 | # Visual C++ cache files
76 | ipch/
77 | *.aps
78 | *.ncb
79 | *.opensdf
80 | *.sdf
81 | *.cachefile
82 |
83 | # Visual Studio profiler
84 | *.psess
85 | *.vsp
86 | *.vspx
87 | *.sap
88 |
89 | # TFS 2012 Local Workspace
90 | $tf/
91 |
92 | # Guidance Automation Toolkit
93 | *.gpState
94 |
95 | # ReSharper is a .NET coding add-in
96 | _ReSharper*/
97 | *.[Rr]e[Ss]harper
98 | *.DotSettings.user
99 |
100 | # JustCode is a .NET coding add-in
101 | .JustCode
102 |
103 | # TeamCity is a build add-in
104 | _TeamCity*
105 |
106 | # DotCover is a Code Coverage Tool
107 | *.dotCover
108 |
109 | # NCrunch
110 | _NCrunch_*
111 | .*crunch*.local.xml
112 | nCrunchTemp_*
113 |
114 | # MightyMoose
115 | *.mm.*
116 | AutoTest.Net/
117 |
118 | # Web workbench (sass)
119 | .sass-cache/
120 |
121 | # Installshield output folder
122 | [Ee]xpress/
123 |
124 | # DocProject is a documentation generator add-in
125 | DocProject/buildhelp/
126 | DocProject/Help/*.HxT
127 | DocProject/Help/*.HxC
128 | DocProject/Help/*.hhc
129 | DocProject/Help/*.hhk
130 | DocProject/Help/*.hhp
131 | DocProject/Help/Html2
132 | DocProject/Help/html
133 |
134 | # Click-Once directory
135 | publish/
136 |
137 | # Publish Web Output
138 | *.[Pp]ublish.xml
139 | *.azurePubxml
140 | # TODO: Comment the next line if you want to checkin your web deploy settings
141 | # but database connection strings (with potential passwords) will be unencrypted
142 | *.pubxml
143 | *.publishproj
144 |
145 | # NuGet Packages
146 | *.nupkg
147 | # The packages folder can be ignored because of Package Restore
148 | **/packages/*
149 | # except build/, which is used as an MSBuild target.
150 | !**/packages/build/
151 | # Uncomment if necessary however generally it will be regenerated when needed
152 | #!**/packages/repositories.config
153 |
154 | # Windows Azure Build Output
155 | csx/
156 | *.build.csdef
157 |
158 | # Windows Azure Emulator
159 | efc/
160 | rfc/
161 |
162 | # Windows Store app package directory
163 | AppPackages/
164 |
165 | # Visual Studio cache files
166 | # files ending in .cache can be ignored
167 | *.[Cc]ache
168 | # but keep track of directories ending in .cache
169 | !*.[Cc]ache/
170 |
171 | # Others
172 | ClientBin/
173 | [Ss]tyle[Cc]op.*
174 | ~$*
175 | *~
176 | *.dbmdl
177 | *.dbproj.schemaview
178 | *.pfx
179 | *.publishsettings
180 | node_modules/
181 | orleans.codegen.cs
182 |
183 | # RIA/Silverlight projects
184 | Generated_Code/
185 |
186 | # Backup & report files from converting an old project file
187 | # to a newer Visual Studio version. Backup files are not needed,
188 | # because we have git ;-)
189 | _UpgradeReport_Files/
190 | Backup*/
191 | UpgradeLog*.XML
192 | UpgradeLog*.htm
193 |
194 | # SQL Server files
195 | *.mdf
196 | *.ldf
197 |
198 | # Business Intelligence projects
199 | *.rdl.data
200 | *.bim.layout
201 | *.bim_*.settings
202 |
203 | # Microsoft Fakes
204 | FakesAssemblies/
205 |
206 | # GhostDoc plugin setting file
207 | *.GhostDoc.xml
208 |
209 | # Node.js Tools for Visual Studio
210 | .ntvs_analysis.dat
211 |
212 | # Visual Studio 6 build log
213 | *.plg
214 |
215 | # Visual Studio 6 workspace options file
216 | *.opt
217 |
218 | # Visual Studio LightSwitch build output
219 | **/*.HTMLClient/GeneratedArtifacts
220 | **/*.DesktopClient/GeneratedArtifacts
221 | **/*.DesktopClient/ModelManifest.xml
222 | **/*.Server/GeneratedArtifacts
223 | **/*.Server/ModelManifest.xml
224 | _Pvt_Extensions
225 |
226 | # Paket dependency manager
227 | .paket/paket.exe
228 |
229 | # FAKE - F# Make
230 | .fake/
--------------------------------------------------------------------------------
/.nuget/NuGet.Config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/DynamicRest.UnitTests/DynamicRest.UnitTests.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net452
5 |
6 | false
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/DynamicRest.UnitTests/Fluent/RestClientBuilderTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 | using DynamicRest.Fluent;
4 | using DynamicRest.UnitTests.TestDoubles;
5 | using Machine.Specifications;
6 |
7 | namespace DynamicRest.UnitTests.Fluent {
8 | [Subject(typeof(RestClientBuilder))]
9 | public class When_a_rest_client_is_created_with_a_rest_client_builder_using_default_values {
10 | static IRestClientBuilder restClientBuilder;
11 | static dynamic builtClient;
12 | static FakeHttpRequestFactory fakeHttpRequestFactory;
13 |
14 | Establish context = () =>
15 | {
16 | restClientBuilder = new RestClientBuilder();
17 | };
18 |
19 | Because the_rest_client_is_built_and_executed = () =>
20 | {
21 | fakeHttpRequestFactory = new FakeHttpRequestFactory();
22 | builtClient = restClientBuilder
23 | .WithRequestBuilder(new HttpVerbRequestBuilder(fakeHttpRequestFactory))
24 | .WithOAuth2Token("token")
25 | .WithUri("http://www.google.com")
26 | .WithBody("My body")
27 | .WithUserAgent("useragent")
28 | .Build();
29 |
30 | builtClient.Post();
31 | };
32 |
33 | It should_have_xml_as_content_type = () =>
34 | fakeHttpRequestFactory.CreatedRequest.ContentType.ShouldEqual("application/xml");
35 | It should_have_xml_as_accept = () =>
36 | fakeHttpRequestFactory.CreatedRequest.Accept.ShouldEqual("application/xml");
37 | It should_have_the_allow_auto_redirect_flag_set_to_false = () =>
38 | fakeHttpRequestFactory.CreatedRequest.AllowAutoRedirect.ShouldEqual(false);
39 | It should_have_the_expected_user_agent = () =>
40 | fakeHttpRequestFactory.CreatedRequest.UserAgent.ShouldEqual("useragent");
41 | }
42 |
43 | [Subject(typeof(RestClientBuilder))]
44 | public class When_a_rest_client_is_created_with_a_rest_client_builder_without_OAuth2_token
45 | {
46 | static IRestClientBuilder restClientBuilder;
47 | static dynamic builtClient;
48 |
49 | static FakeHttpRequestFactory fakeHttpRequestFactory;
50 |
51 | Establish context = () =>
52 | {
53 | restClientBuilder = new RestClientBuilder();
54 | };
55 |
56 | Because the_rest_client_is_built_and_executed = () =>
57 | {
58 | fakeHttpRequestFactory = new FakeHttpRequestFactory();
59 | builtClient = restClientBuilder
60 | .WithRequestBuilder(new HttpVerbRequestBuilder(fakeHttpRequestFactory))
61 | .WithUri("http://www.google.com")
62 | .WithBody("My body")
63 | .Build();
64 |
65 | builtClient.Post();
66 | };
67 |
68 | It should_have_xml_as_content_type = () =>
69 | fakeHttpRequestFactory.CreatedRequest.ContentType.ShouldEqual("application/xml");
70 | It should_have_xml_as_accept = () =>
71 | fakeHttpRequestFactory.CreatedRequest.Accept.ShouldEqual("application/xml");
72 | It should_have_the_allow_auto_redirect_flag_set_to_false = () =>
73 | fakeHttpRequestFactory.CreatedRequest.AllowAutoRedirect.ShouldEqual(false);
74 | It should_have_no_OAuth_header = () =>
75 | fakeHttpRequestFactory.CreatedRequest.Headers.Keys.ShouldNotContain(HttpRequestHeader.Authorization.ToString());
76 | }
77 |
78 | [Subject(typeof(RestClientBuilder))]
79 | public class When_a_rest_client_is_created_with_a_rest_client_builder {
80 |
81 | static IRestClientBuilder restClientBuilder;
82 | static dynamic builtClient;
83 |
84 | static FakeHttpRequestFactory fakeHttpRequestFactory;
85 |
86 | Establish context = () => {
87 | restClientBuilder = new RestClientBuilder();
88 | };
89 |
90 | Because the_rest_client_is_built_and_executed = () => {
91 | fakeHttpRequestFactory = new FakeHttpRequestFactory();
92 | builtClient = restClientBuilder
93 | .WithRequestBuilder(new HttpVerbRequestBuilder(fakeHttpRequestFactory))
94 | .WithOAuth2Token("token")
95 | .WithContentType("application/vnd.data+xml")
96 | .WithUri("http://www.google.com")
97 | .WithBody("My body")
98 | .WithAcceptHeader("application/xml")
99 | .WithResponseProcessor(new ResponseProcessor(new StandardResultBuilder(RestService.Xml)))
100 | .WithAutoRedirect(true)
101 | .WithAcceptEncodingHeader("gzip")
102 | .Build();
103 |
104 | builtClient.Post();
105 | };
106 |
107 | It should_have_the_correct_content_type_header = () =>
108 | fakeHttpRequestFactory.CreatedRequest.ContentType.ShouldEqual("application/vnd.data+xml");
109 | It should_have_the_correct_uri = () =>
110 | fakeHttpRequestFactory.CreatedRequest.RequestURI.ShouldEqual(new Uri("http://www.google.com"));
111 | It should_have_the_correct_body = () =>
112 | fakeHttpRequestFactory.CreatedRequest.RequestBody.ShouldEqual("My body");
113 | It should_have_the_correct_accept_header = () =>
114 | fakeHttpRequestFactory.CreatedRequest.Accept.ShouldEqual("application/xml");
115 | It should_have_the_correct_token = () =>
116 | fakeHttpRequestFactory.CreatedRequest.Headers[HttpRequestHeader.Authorization].ShouldEqual("Bearer token");
117 | It should_have_the_allow_auto_redirect_flag_set_to_false = () =>
118 | fakeHttpRequestFactory.CreatedRequest.AllowAutoRedirect.ShouldEqual(true);
119 | It should_have_the_accept_encode_header = () =>
120 | fakeHttpRequestFactory.CreatedRequest.Headers[HttpRequestHeader.AcceptEncoding].ShouldEqual("gzip");
121 | }
122 |
123 | [Subject(typeof(RestClientBuilder))]
124 | public class When_a_rest_client_is_created_with_a_rest_client_builder_with_timeout
125 | {
126 | static IRestClientBuilder restClientBuilder;
127 | static dynamic builtClient;
128 |
129 | static FakeHttpRequestFactory fakeHttpRequestFactory;
130 |
131 | Establish context = () =>
132 | {
133 | restClientBuilder = new RestClientBuilder();
134 | };
135 |
136 | Because the_rest_client_is_built_and_executed = () =>
137 | {
138 | fakeHttpRequestFactory = new FakeHttpRequestFactory();
139 | builtClient = restClientBuilder
140 | .WithRequestBuilder(new HttpVerbRequestBuilder(fakeHttpRequestFactory))
141 | .WithUri("http://www.google.com")
142 | .WithTimeout(timeout)
143 | .Build();
144 |
145 | builtClient.Post();
146 | };
147 |
148 | It should_have_the_correct_timeout = () =>
149 | fakeHttpRequestFactory.CreatedRequest.Timeout.ShouldEqual(timeout);
150 |
151 | static int timeout = 100;
152 | }
153 |
154 | [Subject(typeof(RestClientBuilder))]
155 | public class When_a_rest_client_is_created_with_a_rest_client_builder_with_proxy_settings
156 | {
157 | static IRestClientBuilder restClientBuilder;
158 | static dynamic builtClient;
159 | static FakeHttpRequestFactory fakeHttpRequestFactory;
160 | static Uri faekUriToGetProxyFor = new Uri("http://www.google.com");
161 | static int timeout = 100;
162 | static FakeWebProxy fakeWebProxy = new FakeWebProxy(new Uri("http://proxy.com:5647"));
163 |
164 | Establish context = () =>
165 | {
166 | restClientBuilder = new RestClientBuilder();
167 | };
168 |
169 | Because the_rest_client_is_built_and_executed = () =>
170 | {
171 | fakeHttpRequestFactory = new FakeHttpRequestFactory();
172 | builtClient = restClientBuilder
173 | .WithRequestBuilder(new HttpVerbRequestBuilder(fakeHttpRequestFactory))
174 | .WithUri(faekUriToGetProxyFor.AbsoluteUri)
175 | .WithProxy(fakeWebProxy)
176 | .Build();
177 |
178 | builtClient.Post();
179 | };
180 |
181 | It should_have_the_correct_proxy_uri = () =>
182 | fakeHttpRequestFactory.CreatedRequest.Proxy.GetProxy(faekUriToGetProxyFor).AbsoluteUri.ShouldEqual(fakeWebProxy.GetProxy(faekUriToGetProxyFor).AbsoluteUri);
183 | It should_have_the_correct_proxy_host = () =>
184 | fakeHttpRequestFactory.CreatedRequest.Proxy.GetProxy(faekUriToGetProxyFor).Host.ShouldEqual(fakeWebProxy.GetProxy(faekUriToGetProxyFor).Host);
185 | It should_have_the_correct_proxy_port = () =>
186 | fakeHttpRequestFactory.CreatedRequest.Proxy.GetProxy(faekUriToGetProxyFor).Port.ShouldEqual(fakeWebProxy.GetProxy(faekUriToGetProxyFor).Port);
187 | }
188 | }
--------------------------------------------------------------------------------
/DynamicRest.UnitTests/Json/JsonResponsesTest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using DynamicRest.Json;
3 | using Machine.Specifications;
4 |
5 | namespace DynamicRest.UnitTests.Json {
6 |
7 | [Subject(typeof(StandardResultBuilder))]
8 | public class When_a_response_contains_a_collection {
9 |
10 | static StandardResultBuilder _resultBuilder;
11 | static dynamic _response;
12 |
13 | Establish context = () =>
14 | {
15 | _resultBuilder = new StandardResultBuilder(RestService.Json);
16 | };
17 |
18 | Because the_response_is_created = () => { _response = _resultBuilder.CreateResult(_json); };
19 |
20 | It should_contain_the_media_0_url = () => (_response.item.media[0].url as string).ShouldEqual("http://media0url");
21 | It should_contain_the_media_1_url = () => (_response.item.media[1].url as string).ShouldEqual("http://media1url");
22 | It should_contain_the_image_0_url = () => (_response.item.images.image[0].src as string).ShouldEqual("http://image0url");
23 | It should_contain_the_image_1_url = () => (_response.item.images.image[1].src as string).ShouldEqual("http://image1url");
24 | It should_contain_the_link_using_array_access = () => (_response.item.link[0] as string).ShouldEqual("http://www.bbc.co.uk/go/rss/int/news/-/news/world-africa-12673956");
25 |
26 | static string _json = @"{
27 | item: {
28 | title:'Gaddafi renews attack on rebels',
29 | description:'Forces loyal to Libyan leader Col Muammar Gaddafi launch fresh air strikes on the rebel-held Ras Lanuf, as they try to retake the oil-rich town.',
30 | link:[
31 | 'http://www.bbc.co.uk/go/rss/int/news/-/news/world-africa-12673956'
32 | ],
33 | guid:'http://www.bbc.co.uk/news/world-africa-12673956',
34 | pubdate:'Tue, 08 Mar 2011 11:21:16 GMT',
35 | media:[
36 | { url:'http://media0url' , src: 'dfsdfdfsfsd'},
37 | { url:'http://media1url' , src: 'dfsdfdfsfsd'}
38 | ],
39 | images:{
40 | image:[
41 | { src:'http://image0url' },
42 | { src:'http://image1url' }
43 | ]
44 | }
45 | }
46 | }";
47 | }
48 |
49 | [Subject(typeof(JsonObject))]
50 | public class When_accessing_a_non_existing_property_on_a_json_property {
51 |
52 | static StandardResultBuilder _resultBuilder;
53 | static dynamic _response;
54 |
55 | Establish context = () =>
56 | {
57 | _resultBuilder = new StandardResultBuilder(RestService.Json);
58 | _response = _resultBuilder.CreateResult(_json);
59 | };
60 |
61 | Because the_response_is_created = () => { _thrownException = Catch.Exception(() => { var junk = _response.item.desc; }); };
62 |
63 | It should_give_an_exception_with_a_sensible_error_message_from_json_object = () =>
64 | _thrownException.Message.ShouldEqual("No member named 'desc' found in the response.");
65 |
66 | static string _json = @"{
67 | item: {
68 | title:'Gaddafi renews attack on rebels',
69 | description:'Forces loyal to Libyan leader Col Muammar Gaddafi launch fresh air strikes on the rebel-held Ras Lanuf, as they try to retake the oil-rich town.',
70 | link:['http://www.bbc.co.uk/go/rss/int/news/-/news/world-africa-12673956'],
71 | guid:'http://www.bbc.co.uk/news/world-africa-12673956',
72 | pubdate:'Tue, 08 Mar 2011 11:21:16 GMT',
73 | media:[
74 | { url:'http://media0url' , src: 'dfsdfdfsfsd'},
75 | { url:'http://media1url' , src: 'dfsdfdfsfsd'}
76 | ],
77 | images:{
78 | image:[
79 | { src:'http://image0url' },
80 | { src:'http://image1url' }
81 | ]
82 | }
83 | }
84 | }";
85 |
86 | private static Exception _thrownException;
87 | }
88 |
89 |
90 | [Subject(typeof(JsonObject))]
91 | public class When_accessing_a_non_existing_property_on_a_json_array {
92 |
93 | static StandardResultBuilder _resultBuilder;
94 | static Exception _thrownException;
95 | static dynamic _response;
96 | static string _json;
97 |
98 | Establish context = () =>
99 | {
100 | _json = @"{
101 | item:{
102 | images:[
103 | { src:'http://image0url' },
104 | { src:'http://image1url' }
105 | ]
106 | }
107 | }";
108 |
109 | _resultBuilder = new StandardResultBuilder(RestService.Json);
110 | _response = _resultBuilder.CreateResult(_json);
111 | };
112 |
113 | Because the_response_is_created = () => { _thrownException = Catch.Exception(() => { var junk = _response.item.images.doesntexist; }); };
114 |
115 | It should_give_an_exception_with_a_sensible_error_message_from_json_object = () =>
116 | _thrownException.Message.ShouldEqual("No member named 'doesntexist' found in the response.");
117 | }
118 |
119 | [Subject(typeof(StandardResultBuilder))]
120 | public class When_a_response_is_empty
121 | {
122 |
123 | static StandardResultBuilder _resultBuilder;
124 | static dynamic _response;
125 |
126 | Establish context = () =>
127 | {
128 | _resultBuilder = new StandardResultBuilder(RestService.Json);
129 | };
130 |
131 | Because the_response_is_created = () => { _response = _resultBuilder.CreateResult(_json); };
132 |
133 | It should_return_empty_json_object = () => (_response as JsonObject).ShouldEqual(new JsonObject());
134 |
135 | static string _json = @"";
136 | }
137 | }
--------------------------------------------------------------------------------
/DynamicRest.UnitTests/RestClients/HttpVerbRequestBuilderTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Net;
3 | using DynamicRest.HTTPInterfaces;
4 | using DynamicRest.UnitTests.TestDoubles;
5 | using Machine.Specifications;
6 |
7 | namespace DynamicRest.UnitTests.RestClients {
8 |
9 | [Subject(typeof(HttpVerbRequestBuilder))]
10 | public class When_i_use_the_client_to_put_a_request {
11 | private const string TestUri = "http://api.huddle.local/v2/tasks/123456";
12 | private static dynamic client;
13 | private static FakeHttpRequestFactory requestFactory;
14 | private static string oAuth2Token = "{my_token}";
15 |
16 | Establish context = () =>
17 | {
18 | requestFactory = new FakeHttpRequestFactory();
19 |
20 | var httpVerbRequestBuilder = new HttpVerbRequestBuilder(requestFactory) { Uri = TestUri };
21 | httpVerbRequestBuilder.SetOAuth2AuthorizationHeader(oAuth2Token);
22 | client = new RestClient(httpVerbRequestBuilder, new ResponseProcessor(new StandardResultBuilder(RestService.Xml)));
23 | };
24 |
25 | Because we_make_get_call_to_an_api_via_rest_client = () => client.Post();
26 |
27 | It should_build_the_expected_uri = () => TestUri.ShouldEqual(requestFactory.CreatedRequest.RequestURI.ToString());
28 | It should_set_the_correct_http_verb_on_the_request = () => requestFactory.CreatedRequest.HttpVerb.ShouldEqual(HttpVerb.POST);
29 | It should_set_the_correct_authorization_header_on_the_request = () => requestFactory.CreatedRequest.Headers[HttpRequestHeader.Authorization].ShouldEqual(
30 | $"Bearer {oAuth2Token}");
31 | }
32 |
33 | [Subject(typeof(HttpVerbRequestBuilder))]
34 | public class When_i_use_the_client_to_get_a_request {
35 | private const string TestUri = "http://api.huddle.local/v2/tasks/123456";
36 | private static dynamic client;
37 | private static FakeHttpRequestFactory requestFactory;
38 |
39 | Establish context = () =>
40 | {
41 | requestFactory = new FakeHttpRequestFactory();
42 |
43 | var httpVerbRequestBuilder = new HttpVerbRequestBuilder(requestFactory) { Uri = TestUri };
44 | client = new RestClient(httpVerbRequestBuilder, new ResponseProcessor(new StandardResultBuilder(RestService.Xml)));
45 | };
46 |
47 | Because we_make_get_call_to_an_api_via_rest_client = () => client.Get();
48 |
49 | It should_build_the_expected_uri = () => TestUri.ShouldEqual(requestFactory.CreatedRequest.RequestURI.ToString());
50 | It should_set_the_correct_http_verb_on_the_request = () => requestFactory.CreatedRequest.HttpVerb.ShouldEqual(HttpVerb.GET);
51 | }
52 |
53 | [Subject(typeof(HttpVerbRequestBuilder))]
54 | public class When_i_set_an_invalid_operation_on_the_client {
55 | private const string TestUri = "http://api.huddle.local/v2/tasks/123456";
56 | private static dynamic client;
57 | private static dynamic exception;
58 | private static FakeHttpRequestFactory requestFactory;
59 |
60 | Establish context = () =>
61 | {
62 | requestFactory = new FakeHttpRequestFactory();
63 |
64 | var httpVerbRequestBuilder = new HttpVerbRequestBuilder(requestFactory) { Uri = TestUri };
65 | client = new RestClient(httpVerbRequestBuilder, new ResponseProcessor(new StandardResultBuilder(RestService.Xml)));
66 | };
67 |
68 | Because we_make_get_call_to_an_api_via_rest_client = () => exception = Catch.Exception(() => client.NotHttp());
69 |
70 | It should_throw_an_exception = () => ((Exception) exception).ShouldBeAssignableTo();
71 | }
72 |
73 | [Subject(typeof(HttpVerbRequestBuilder))]
74 | public class When_i_set_an_xml_body_on_the_request {
75 | private const string ContentType = @"application\xml+";
76 | private static FakeHttpRequestFactory requestFactory;
77 | private static dynamic client;
78 | private static string requestBody = "";
79 |
80 | Establish context = () =>
81 | {
82 | requestFactory = new FakeHttpRequestFactory();
83 |
84 | var httpVerbRequestBuilder = new HttpVerbRequestBuilder(requestFactory) { Body = requestBody, ContentType = ContentType, Uri = "http://api.huddle.com" };
85 | client = new RestClient(httpVerbRequestBuilder, new ResponseProcessor(new StandardResultBuilder(RestService.Xml)));
86 | };
87 |
88 | Because we_set_an_xml_body_on_the_test = () => client.Post();
89 |
90 | It should_set_the_body_of_the_request = () => requestFactory.CreatedRequest.RequestBody.ShouldEqual(requestBody);
91 | It should_set_the_content_type_of_the_request = () => requestFactory.CreatedRequest.ContentType.ShouldEqual(ContentType);
92 | }
93 |
94 | [Subject(typeof(HttpVerbRequestBuilder))]
95 | public class When_the_autofollow_option_is_set_to_true {
96 | private const string TestUri = "http://api.huddle.local/v2/tasks/123456";
97 | private static dynamic client;
98 | private static FakeHttpRequestFactory requestFactory;
99 |
100 | Establish context = () =>
101 | {
102 | requestFactory = new FakeHttpRequestFactory();
103 |
104 | var httpVerbRequestBuilder = new HttpVerbRequestBuilder(requestFactory) { Uri = TestUri, AllowAutoRedirect = true };
105 | client = new RestClient(httpVerbRequestBuilder, new ResponseProcessor(new StandardResultBuilder(RestService.Xml)));
106 | };
107 |
108 | Because we_make_get_call_to_an_api_via_rest_client = () => client.Get();
109 |
110 | It should_set_the_auto_follow_option_to_true_on_the_request = () => requestFactory.CreatedRequest.AllowAutoRedirect.ShouldEqual(true);
111 | }
112 |
113 | [Subject(typeof(HttpVerbRequestBuilder))]
114 | public class When_the_autofollow_option_is_set_to_false {
115 | private const string TestUri = "http://api.huddle.local/v2/tasks/123456";
116 | private static dynamic client;
117 | private static FakeHttpRequestFactory requestFactory;
118 |
119 | Establish context = () =>
120 | {
121 | requestFactory = new FakeHttpRequestFactory();
122 |
123 | var httpVerbRequestBuilder = new HttpVerbRequestBuilder(requestFactory) { Uri = TestUri, AllowAutoRedirect = false };
124 | client = new RestClient(httpVerbRequestBuilder, new ResponseProcessor(new StandardResultBuilder(RestService.Xml)));
125 | };
126 |
127 | Because we_make_get_call_to_an_api_via_rest_client = () => client.Get();
128 |
129 | It should_set_the_auto_follow_option_to_false_on_the_request = () => requestFactory.CreatedRequest.AllowAutoRedirect.ShouldEqual(false);
130 | }
131 |
132 | [Subject(typeof(HttpVerbRequestBuilder))]
133 | public class When_the_autofollow_option_is_not_explicitly_set {
134 | private const string TestUri = "http://api.huddle.local/v2/tasks/123456";
135 | private static dynamic client;
136 | private static FakeHttpRequestFactory requestFactory;
137 |
138 | Establish context = () =>
139 | {
140 | requestFactory = new FakeHttpRequestFactory();
141 |
142 | var httpVerbRequestBuilder = new HttpVerbRequestBuilder(requestFactory) { Uri = TestUri };
143 | client = new RestClient(httpVerbRequestBuilder, new ResponseProcessor(new StandardResultBuilder(RestService.Xml)));
144 | };
145 |
146 | Because we_make_get_call_to_an_api_via_rest_client = () => client.Get();
147 |
148 | It should_default_the_auto_follow_option_to_false_on_the_request = () => requestFactory.CreatedRequest.AllowAutoRedirect.ShouldEqual(false);
149 | }
150 |
151 | [Subject(typeof(HttpVerbRequestBuilder))]
152 | public class When_i_use_the_client_to_delete_a_request
153 | {
154 | private const string TestUri = "http://api.huddle.local/v2/tasks/123456";
155 | private static dynamic client;
156 | private static FakeHttpRequestFactory requestFactory;
157 | private static string oAuth2Token = "{my_token}";
158 |
159 | Establish context = () =>
160 | {
161 | requestFactory = new FakeHttpRequestFactory();
162 |
163 | var httpVerbRequestBuilder = new HttpVerbRequestBuilder(requestFactory) { Uri = TestUri };
164 | httpVerbRequestBuilder.SetOAuth2AuthorizationHeader(oAuth2Token);
165 | client = new RestClient(httpVerbRequestBuilder, new ResponseProcessor(new StandardResultBuilder(RestService.Xml)));
166 | };
167 |
168 | Because we_make_get_call_to_an_api_via_rest_client = () => client.Delete();
169 |
170 | It should_build_the_expected_uri = () => TestUri.ShouldEqual(requestFactory.CreatedRequest.RequestURI.ToString());
171 | It should_set_the_correct_http_verb_on_the_request = () => requestFactory.CreatedRequest.HttpVerb.ShouldEqual(HttpVerb.DELETE);
172 | It should_set_the_correct_authorization_header_on_the_request = () => requestFactory.CreatedRequest.Headers[HttpRequestHeader.Authorization].ShouldEqual(string.Format("Bearer {0}", oAuth2Token));
173 | }
174 |
175 | }
--------------------------------------------------------------------------------
/DynamicRest.UnitTests/RestClients/TemplatedUriRequestBuilderTests.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using DynamicRest.Json;
3 | using DynamicRest.UnitTests.TestDoubles;
4 | using Machine.Specifications;
5 |
6 | namespace DynamicRest.UnitTests.RestClients {
7 |
8 | [Subject(typeof(TemplatedUriRequestBuilder))]
9 | public class When_using_a_templated_uri_with_an_operation {
10 | private const string AmazonUriTemplate = "http://ecs.amazonaws.com/onca/xml?Service=AWSECommerceService&Version=2009-03-31&Operation={operation}&AssociateTag=myamzn-20";
11 | private const string ExpectedUri = "http://ecs.amazonaws.com/onca/xml?Service=AWSECommerceService&Version=2009-03-31&Operation=ItemSearch&AssociateTag=myamzn-20";
12 | private static dynamic client;
13 | private static FakeHttpRequestFactory requestFactory;
14 |
15 | Establish context = () =>
16 | {
17 | requestFactory = new FakeHttpRequestFactory();
18 | var templatedUriRequestBuilder = new TemplatedUriRequestBuilder(requestFactory) { Uri = AmazonUriTemplate };
19 | client = new RestClient(templatedUriRequestBuilder, new ResponseProcessor(new StandardResultBuilder(RestService.Xml)));
20 | };
21 |
22 | Because we_make_get_call_to_an_api_via_rest_client = () => client.ItemSearch();
23 |
24 | It should_merge_operationname_parameters_into_the_uri_template = () => ExpectedUri.ShouldEqual(requestFactory.CreatedRequest.RequestURI.ToString());
25 | }
26 |
27 | [Subject(typeof(TemplatedUriRequestBuilder))]
28 | public class When_using_a_templated_uri_with_an_operation_and_options {
29 | private const string AmazonUriTemplate = "http://ecs.amazonaws.com/onca/xml?Service=AWSECommerceService&Version=2009-03-31&Operation={operation}&AssociateTag=myamzn-20";
30 | private const string ExpectedUri = "http://ecs.amazonaws.com/onca/xml?Service=AWSECommerceService&Version=2009-03-31&Operation=ItemSearch&AssociateTag=myamzn-20&SearchIndex=Books&Keywords=Dynamic+Programming";
31 | private static dynamic client;
32 | private static dynamic searchOptions;
33 | private static FakeHttpRequestFactory requestFactory;
34 |
35 | Establish context = () =>
36 | {
37 | requestFactory = new FakeHttpRequestFactory();
38 | var templatedUriRequestBuilder = new TemplatedUriRequestBuilder(requestFactory) { Uri = AmazonUriTemplate };
39 | client = new RestClient(templatedUriRequestBuilder, new ResponseProcessor(new StandardResultBuilder(RestService.Xml)));
40 |
41 | searchOptions = new JsonObject();
42 | searchOptions.SearchIndex = "Books";
43 | searchOptions.Keywords = "Dynamic Programming";
44 | };
45 |
46 | Because we_make_get_call_to_an_api_via_rest_client = () => client.ItemSearch(searchOptions);
47 |
48 | It should_merge_operation_and_option_parameters_into_the_uri_template = () => ExpectedUri.ShouldEqual(requestFactory.CreatedRequest.RequestURI.ToString());
49 | }
50 |
51 | [Subject(typeof(TemplatedUriRequestBuilder))]
52 | public class When_using_a_templated_uri_with_ids_in_uri {
53 | private const string BingSearchUri = "http://api.bing.net/json.aspx?AppId={appID}&Version=2.2&Market=en-US";
54 | private const string ExpectedUri = "http://api.bing.net/json.aspx?AppId=12345&Version=2.2&Market=en-US";
55 | private const string BingApiKey = "12345";
56 | private static FakeHttpRequestFactory requestFactory;
57 | private static dynamic client;
58 |
59 | Establish context = () =>
60 | {
61 | requestFactory = new FakeHttpRequestFactory();
62 | var templatedUriRequestBuilder = new TemplatedUriRequestBuilder(requestFactory) { Uri = BingSearchUri };
63 | client = new RestClient(templatedUriRequestBuilder, new ResponseProcessor(new StandardResultBuilder(RestService.Json)));
64 | client.appID = BingApiKey;
65 | };
66 |
67 | Because we_make_a_call_to_an_api_via_rest_client = () => client.Invoke();
68 |
69 | It should_merge_properties_into_the_uri_template = () => ExpectedUri.ShouldEqual(requestFactory.CreatedRequest.RequestURI.ToString());
70 | }
71 |
72 | [Subject(typeof(TemplatedUriRequestBuilder))]
73 | public class When_using_a_templated_uri_with_ids_and_missing_ids {
74 | private static FakeHttpRequestFactory requestFactory;
75 | private static dynamic bing;
76 | private const string BingSearchUri = "http://api.bing.net/json.aspx?AppId={appID}&Version=2.2&Market=en-US";
77 | private const string ExpectedUri = "http://api.bing.net/json.aspx?AppId=12345&Version=2.2&Market=en-US";
78 | private const string BingApiKey = "12345";
79 | private static Exception exception;
80 |
81 | Establish context = () =>
82 | {
83 | requestFactory = new FakeHttpRequestFactory();
84 | var templatedUriRequestBuilder = new TemplatedUriRequestBuilder(requestFactory) { Uri = BingSearchUri };
85 | bing = new RestClient(templatedUriRequestBuilder, new ResponseProcessor(new StandardResultBuilder(RestService.Json)));
86 | };
87 |
88 | Because we_make_a_call_to_an_api_via_rest_client = () => exception = Catch.Exception(() => bing.Invoke());
89 |
90 | It should_throw_an_exception = () => exception.ShouldBeAssignableTo(typeof (ArgumentException));
91 |
92 | It should_contain_helpful_error_message = () => exception.Message.ShouldEqual("You are missing one or more expected template parameters in the uri: http://api.bing.net/json.aspx?AppId={appID}&Version=2.2&Market=en-US");
93 | }
94 |
95 | [Subject(typeof(TemplatedUriRequestBuilder))]
96 | public class When_using_a_templated_uri_with_ids_in_uri_and_options {
97 | private static FakeHttpRequestFactory requestFactory;
98 | private static dynamic bing;
99 | private static dynamic searchOptions;
100 | private const string BingSearchUri = "http://api.bing.net/json.aspx?AppId={appID}&Version=2.2&Market=en-US";
101 | private const string ExpectedUri = "http://api.bing.net/json.aspx?AppId=12345&Version=2.2&Market=en-US&Query=seattle&Sources=Web+Image&Web.Count=4&Image.Count=2";
102 | private const string BingApiKey = "12345";
103 |
104 | Establish context = () =>
105 | {
106 | requestFactory = new FakeHttpRequestFactory();
107 | var templatedUriRequestBuilder = new TemplatedUriRequestBuilder(requestFactory) { Uri = BingSearchUri };
108 | bing = new RestClient(templatedUriRequestBuilder, new ResponseProcessor(new StandardResultBuilder(RestService.Json)));
109 | bing.appID = BingApiKey;
110 |
111 | searchOptions = new JsonObject();
112 | searchOptions.Query = "seattle";
113 | searchOptions.Sources = new[] {"Web", "Image"};
114 | searchOptions.Web = new JsonObject("Count", 4);
115 | searchOptions.Image = new JsonObject("Count", 2);
116 | };
117 |
118 | Because we_make_a_call_to_an_api_via_rest_client = () => bing.Invoke(searchOptions);
119 |
120 | It should_merge_properties_into_the_uri_template = () => ExpectedUri.ShouldEqual(requestFactory.CreatedRequest.RequestURI.ToString());
121 | }
122 |
123 | [Subject(typeof(TemplatedUriRequestBuilder))]
124 | public class When_using_a_templated_uri_with_ids_in_uri_and_operation_and_options {
125 | private static dynamic flickr;
126 | private static dynamic searchOptions;
127 | private static FakeHttpRequestFactory requestFactory;
128 | private const string FlickrSearchApi = "http://api.flickr.com/services/rest/?method=flickr.{operation}&api_key={apiKey}&format=json&nojsoncallback=1";
129 | private const string ExpectedUri = "http://api.flickr.com/services/rest/?method=flickr.Photos.Search&api_key=123456&format=json&nojsoncallback=1";
130 | private const string FlickrApiKey = "123456";
131 |
132 | private Establish context = () =>
133 | {
134 | requestFactory = new FakeHttpRequestFactory();
135 | var templatedUriRequestBuilder = new TemplatedUriRequestBuilder(requestFactory) { Uri = FlickrSearchApi };
136 | flickr = new RestClient(templatedUriRequestBuilder, new ResponseProcessor(new StandardResultBuilder(RestService.Json)));
137 | flickr.apiKey = FlickrApiKey;
138 |
139 | dynamic searchOptions = new JsonObject();
140 | searchOptions.tags = "seattle";
141 | searchOptions.per_page = 4;
142 | };
143 |
144 | Because we_make_a_call_to_an_api_via_the_rest_client = () => flickr.Photos.Search(searchOptions);
145 |
146 | It should_merge_properties_into_the_uri_template = () => ExpectedUri.ShouldEqual(requestFactory.CreatedRequest.RequestURI.ToString());
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/DynamicRest.UnitTests/Simulators/ResponseSimulatorTests.cs:
--------------------------------------------------------------------------------
1 | using System.Net;
2 | using System.Runtime.Serialization;
3 | using DynamicRest.Fluent;
4 | using DynamicRest.UnitTests.TestDoubles;
5 | using Machine.Specifications;
6 |
7 | namespace DynamicRest.UnitTests.Simulators
8 | {
9 | [Subject(typeof(RestClientBuilder))]
10 | public class When_a_rest_client_is_created_with_a_rest_client_builder_passing_in_an_expected_response
11 | {
12 | static IRestClientBuilder restClientBuilder;
13 | private static RestOperation _response;
14 | static dynamic builtClient;
15 |
16 | static FakeHttpRequestFactory fakeHttpRequestFactory;
17 |
18 | Establish context = () =>
19 | {
20 | restClientBuilder = new RestClientBuilder();
21 | };
22 |
23 | Because the_rest_client_is_built_and_executed = () =>
24 | {
25 | fakeHttpRequestFactory = new FakeHttpRequestFactory();
26 | var responseContent = new FakeHttpWebResponseWrapper.ResponseContent("application/vnd.data+xml");
27 | resultAsString = "Test";
28 | responseContent.SetContent(resultAsString);
29 | fakeHttpRequestFactory.SetResponse(new FakeHttpWebResponseWrapper
30 | {
31 | Headers = new WebHeaderCollection(),
32 | StatusCode = HttpStatusCode.OK,
33 | Content = responseContent
34 |
35 | });
36 |
37 | _response = restClientBuilder
38 | .WithRequestBuilder(new HttpVerbRequestBuilder(fakeHttpRequestFactory))
39 | .WithUri("http://www.google.com")
40 | .Build()
41 | .Get();
42 | };
43 |
44 | It should_return_a_value_built_from_interpreting_the_response = () =>ShouldExtensionMethods.ShouldEqual(_response.Result.message.Value, "Test");
45 | It should_return_the_original_string_in_the_response = () => ShouldExtensionMethods.ShouldEqual(_response.ResponseText, resultAsString);
46 |
47 | static string resultAsString;
48 | }
49 |
50 |
51 | [Subject(typeof(RestClientBuilder))]
52 | public class When_a_rest_client_is_created_with_a_rest_client_builder_passing_in_a_templated_response
53 | {
54 | static IRestClientBuilder restClientBuilder;
55 | private static RestOperation _response;
56 | static dynamic builtClient;
57 |
58 | static FakeHttpRequestFactory fakeHttpRequestFactory;
59 |
60 | Establish context = () =>
61 | {
62 | restClientBuilder = new RestClientBuilder();
63 | };
64 |
65 | Because the_rest_client_is_built_and_executed = () =>
66 | {
67 | fakeHttpRequestFactory = new FakeHttpRequestFactory();
68 | var responseContent = new FakeHttpWebResponseWrapper.ResponseContent("application/vnd.data+xml");
69 | responseContent.SetContent(new Result { Message = "Test" });
70 | fakeHttpRequestFactory.SetResponse(new FakeHttpWebResponseWrapper
71 | {
72 | Headers = new WebHeaderCollection(),
73 | StatusCode = HttpStatusCode.OK,
74 | Content = responseContent
75 | });
76 |
77 | _response = restClientBuilder
78 | .WithRequestBuilder(new HttpVerbRequestBuilder(fakeHttpRequestFactory))
79 | .WithUri("http://www.google.com")
80 | .Build()
81 | .Get();
82 | };
83 |
84 | It should_return_a_value_built_from_interpreting_the_response = () => ShouldExtensionMethods.ShouldEqual(_response.Result.Message.Value, "Test");
85 | }
86 | public class Result
87 | {
88 | public string Message { get; set; }
89 | }
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/DynamicRest.UnitTests/TestDoubles/FakeHttpRequestFactory.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using DynamicRest.HTTPInterfaces;
3 |
4 | namespace DynamicRest.UnitTests.TestDoubles {
5 |
6 | internal class FakeHttpRequestFactory : IHttpRequestFactory {
7 | private IHttpResponse _httpResponse;
8 |
9 | internal FakeHttpWebRequestWrapper CreatedRequest {get; set; }
10 |
11 | public IHttpRequest Create(Uri uri) {
12 | CreatedRequest = new FakeHttpWebRequestWrapper(uri);
13 | if (_httpResponse != null)
14 | {
15 | CreatedRequest.Response = _httpResponse;
16 | }
17 | return CreatedRequest;
18 | }
19 |
20 | public void SetResponse(IHttpResponse httpResponse)
21 | {
22 | _httpResponse = httpResponse;
23 | }
24 | }
25 | }
--------------------------------------------------------------------------------
/DynamicRest.UnitTests/TestDoubles/FakeHttpWebRequestWrapper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Net;
4 | using DynamicRest.HTTPInterfaces;
5 |
6 | namespace DynamicRest.UnitTests.TestDoubles
7 | {
8 | public class FakeHttpWebRequestWrapper : IHttpRequest {
9 |
10 | private readonly Uri _uri;
11 | private WebHeaderCollection _headers;
12 | private IHttpResponse _response;
13 |
14 | public FakeHttpWebRequestWrapper(Uri uri) {
15 | _uri = uri;
16 | }
17 |
18 | public Uri RequestURI {
19 | get { return _uri; }
20 | }
21 |
22 | public string Accept { get; set; }
23 | public string ContentType { get; private set; }
24 | public bool AllowAutoRedirect { get; set; }
25 | public string UserAgent { get; set; }
26 | public int Timeout { get; set; }
27 | public IWebProxy Proxy { get; set; }
28 | public HttpVerb HttpVerb { get; set; }
29 |
30 | public WebHeaderCollection Headers {
31 | get {
32 | return _headers;
33 | }
34 | }
35 |
36 | public string RequestBody { get; private set; }
37 |
38 | public IHttpResponse Response
39 | {
40 | set {
41 | _response = value;
42 | }
43 | }
44 |
45 | public void AddCredentials(ICredentials credentials) {
46 |
47 | }
48 |
49 | public void AddHeaders(WebHeaderCollection headers) {
50 | _headers = headers;
51 | }
52 |
53 | public void AddRequestBody(string contentType, string content) {
54 | RequestBody = content;
55 | ContentType = contentType;
56 | }
57 |
58 | public void BeginGetResponse(Action