diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..940794e
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,288 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+##
+## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
+
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+
+# Visual Studio 2015 cache/options directory
+.vs/
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+
+# .NET Core
+project.lock.json
+project.fragment.lock.json
+artifacts/
+**/Properties/launchSettings.json
+
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+
+# Chutzpah Test files
+_Chutzpah*
+
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.VC.db
+*.VC.VC.opendb
+
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+
+# TFS 2012 Local Workspace
+$tf/
+
+# Guidance Automation Toolkit
+*.gpState
+
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+
+# JustCode is a .NET coding add-in
+.JustCode
+
+# TeamCity is a build add-in
+_TeamCity*
+
+# DotCover is a Code Coverage Tool
+*.dotCover
+
+# Visual Studio code coverage results
+*.coverage
+*.coveragexml
+
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+
+# Web workbench (sass)
+.sass-cache/
+
+# Installshield output folder
+[Ee]xpress/
+
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+
+# Click-Once directory
+publish/
+
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+*.pubxml
+*.publishproj
+
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+# NuGet v3's project.json files produces more ignorable files
+*.nuget.props
+*.nuget.targets
+
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+
+# Microsoft Azure Emulator
+ecf/
+rcf/
+
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+orleans.codegen.cs
+
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+
+# RIA/Silverlight projects
+Generated_Code/
+
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+
+# SQL Server files
+*.mdf
+*.ldf
+*.ndf
+
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+
+# Microsoft Fakes
+FakesAssemblies/
+
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+node_modules/
+
+# Typescript v1 declaration files
+typings/
+
+# Visual Studio 6 build log
+*.plg
+
+# Visual Studio 6 workspace options file
+*.opt
+
+# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
+*.vbw
+
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+
+# FAKE - F# Make
+.fake/
+
+# JetBrains Rider
+.idea/
+*.sln.iml
+
+# CodeRush
+.cr/
+
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+
+# Cake - Uncomment if you are using it
+# tools/**
+# !tools/packages.config
+
+# Telerik's JustMock configuration file
+*.jmconfig
+
+# BizTalk build output
+*.btp.cs
+*.btm.cs
+*.odx.cs
+*.xsd.cs
diff --git a/src/DebugApp/App.config b/src/DebugApp/App.config
new file mode 100644
index 0000000..88fa402
--- /dev/null
+++ b/src/DebugApp/App.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/DebugApp/DebugApp.csproj b/src/DebugApp/DebugApp.csproj
new file mode 100644
index 0000000..61a4e9f
--- /dev/null
+++ b/src/DebugApp/DebugApp.csproj
@@ -0,0 +1,59 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {F2D82A82-100B-4594-B50F-7C7C815C4370}
+ Exe
+ DebugApp
+ DebugApp
+ v4.5.2
+ 512
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll
+
+
+ ..\packages\RestSharp.105.2.3\lib\net452\RestSharp.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/DebugApp/Program.cs b/src/DebugApp/Program.cs
new file mode 100644
index 0000000..69c7c5d
--- /dev/null
+++ b/src/DebugApp/Program.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DebugApp
+{
+ class Program
+ {
+ static void Main(string[] args)
+ {
+ }
+ }
+}
diff --git a/src/DebugApp/Properties/AssemblyInfo.cs b/src/DebugApp/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..41dfbc1
--- /dev/null
+++ b/src/DebugApp/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+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: AssemblyTitle("DebugApp")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("DebugApp")]
+[assembly: AssemblyCopyright("Copyright © 2017")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 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("f2d82a82-100b-4594-b50f-7c7c815c4370")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/src/DebugApp/packages.config b/src/DebugApp/packages.config
new file mode 100644
index 0000000..d186dc1
--- /dev/null
+++ b/src/DebugApp/packages.config
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/DynaWeb.All.sln b/src/DynaWeb.All.sln
new file mode 100644
index 0000000..ae074cc
--- /dev/null
+++ b/src/DynaWeb.All.sln
@@ -0,0 +1,34 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26430.16
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DynaWeb", "DynaWeb\DynaWeb.csproj", "{CE19C882-1AAC-434C-99AF-4A285DA053BA}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DebugApp", "DebugApp\DebugApp.csproj", "{F2D82A82-100B-4594-B50F-7C7C815C4370}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DynaWeb.Core.Tests", "..\test\DynaWeb.Core.Tests\DynaWeb.Core.Tests.csproj", "{50A649C6-FB32-4C6D-A7B6-6EB99DE8547D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {CE19C882-1AAC-434C-99AF-4A285DA053BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CE19C882-1AAC-434C-99AF-4A285DA053BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CE19C882-1AAC-434C-99AF-4A285DA053BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CE19C882-1AAC-434C-99AF-4A285DA053BA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F2D82A82-100B-4594-B50F-7C7C815C4370}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F2D82A82-100B-4594-B50F-7C7C815C4370}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F2D82A82-100B-4594-B50F-7C7C815C4370}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F2D82A82-100B-4594-B50F-7C7C815C4370}.Release|Any CPU.Build.0 = Release|Any CPU
+ {50A649C6-FB32-4C6D-A7B6-6EB99DE8547D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {50A649C6-FB32-4C6D-A7B6-6EB99DE8547D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {50A649C6-FB32-4C6D-A7B6-6EB99DE8547D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {50A649C6-FB32-4C6D-A7B6-6EB99DE8547D}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/src/DynaWeb/Classes/Execution.cs b/src/DynaWeb/Classes/Execution.cs
new file mode 100644
index 0000000..fbb9dd7
--- /dev/null
+++ b/src/DynaWeb/Classes/Execution.cs
@@ -0,0 +1,212 @@
+using RestSharp;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DynaWeb
+{
+ ///
+ /// Provides support for executing WebRequests
+ ///
+ public static class Execute
+ {
+ #region internal methods
+ private static WebResponse ClientRequestMethod(WebClient webClient, WebRequest webRequest)
+ {
+ if (webRequest == null) throw new ArgumentNullException(DynaWeb.Properties.Resources.WebClientRequestNullMessage);
+ // build a client & request to execute
+ WebClient client;
+ WebRequest request = webRequest;
+
+ // check if client is null : this will be the case when executing a WebRequest directly
+ if (webClient == null)
+ {
+ // in that case, an empty WebClient will be constructed with the WebRequest URL as its baseUrl.
+ // the request Resource also needs to be reset, otherwise the URL would be concatenating to itself.
+ client = WebClient.ByUrl(webRequest.URL);
+ request.Resource = "";
+ }
+ else
+ {
+ client = webClient;
+ }
+ client.UserAgent = "DynamoDS";
+
+ // validate the Uri before attempting to execute the request
+ try
+ {
+ var uri = WebClient.BuildUri(client, request);
+ if (string.IsNullOrEmpty(uri) || DynaWeb.Helpers.CheckURI(Helpers.ParseUriFromString(uri)) != true)
+ {
+ //TODO : error handling here is limited, needs checking and expanding.
+ throw new InvalidOperationException("Malformed URL.");
+ }
+ }
+ catch (Exception e)
+ {
+ throw new InvalidOperationException(
+ DynaWeb.Properties.Resources.WebClientBuildUrlFailed +
+ Environment.NewLine +
+ "Error returned was :" + Environment.NewLine +
+ e.Message);
+ }
+
+ // enforce security protocols if needed
+ if (webRequest.ForceSecurityProtocol)
+ {
+ ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
+ ServicePointManager.DefaultConnectionLimit *= 10;
+ }
+
+ // Execute using the wrapped client and wrapped request objects.
+ var startTime = DateTime.Now;
+ var responseFromServer = client.restClient.Execute(webRequest.restRequest);
+ var endTime = DateTime.Now;
+
+ // the server response needs to be handled based on status and any errors raised in UI
+ switch (responseFromServer.ResponseStatus)
+ {
+ case ResponseStatus.None:
+ throw new InvalidOperationException(DynaWeb.Properties.Resources.WebResponseNetworkErrorMessage);
+ case ResponseStatus.Error:
+ throw new InvalidOperationException(DynaWeb.Properties.Resources.WebResponseNetworkErrorMessage);
+ case ResponseStatus.TimedOut:
+ throw new InvalidOperationException(DynaWeb.Properties.Resources.WebRequestTimedOutMessage);
+ case ResponseStatus.Aborted:
+ throw new InvalidOperationException(DynaWeb.Properties.Resources.WebResponseAbortedMessage);
+ default:
+ break;
+ }
+
+ // update the request properties with response data
+ webRequest.response = new WebResponse(responseFromServer);
+ webRequest.response.Time = endTime - startTime;
+
+ return webRequest.response;
+ }
+ #endregion
+
+ #region extension methods
+
+ ///
+ /// Execute the given request, on a client if one is supplied.
+ ///
+ /// The client that will execute the request.
+ /// Note : the WebClient can be NULL when executing a WebRequest directly.
+ /// The request to be executed.
+ /// The string that represents the http method.
+ /// Valid input : GET, DELETE, HEAD, OPTIONS, POST, PUT, MERGE.
+ /// The WebResponse from the server.
+ public static WebResponse ByClientRequestMethod(WebClient webClient, WebRequest webRequest, string method = null)
+ {
+ // initialise method with GET as default
+ webRequest.restRequest.Method = Method.GET;
+ // then try to parse value given (if any). If this fails, method is not changed.
+ if (!string.IsNullOrEmpty(method) && Enum.TryParse(method, true, out Method reqMethod))
+ webRequest.restRequest.Method = reqMethod;
+
+ return ClientRequestMethod(webClient, webRequest);
+ }
+
+ ///
+ /// Execute the given request, on a client if one is supplied, using the standard http GET method.
+ ///
+ /// The request to be executed.
+ /// (optional) The client that will execute the request.
+ /// The response from the server.
+ public static WebResponse GET(WebRequest webRequest, WebClient webClient = null)
+ {
+ webRequest.restRequest.Method = Method.GET;
+ return ClientRequestMethod(webClient, webRequest);
+ }
+
+ ///
+ /// Execute the given request, on a client if one is supplied, using the standard http POST method.
+ ///
+ /// The request to be executed.
+ /// (optional) The client that will execute the request.
+ /// The response from the server.
+ public static WebResponse POST(WebRequest webRequest, WebClient webClient = null)
+ {
+ webRequest.restRequest.Method = Method.POST;
+ return ClientRequestMethod(webClient, webRequest);
+ }
+
+ ///
+ /// Execute the given request, on a client if one is supplied, using the standard http PUT method.
+ ///
+ /// The request to be executed.
+ /// (optional) The client that will execute the request.
+ /// The response from the server.
+ public static WebResponse PUT(WebRequest webRequest, WebClient webClient = null)
+ {
+ webRequest.restRequest.Method = Method.PUT;
+ return ClientRequestMethod(webClient, webRequest);
+ }
+
+ ///
+ /// Execute the given request, on a client if one is supplied, using the standard http DELETE method.
+ ///
+ /// The request to be executed.
+ /// (optional) The client that will execute the request.
+ /// The response from the server.
+ public static WebResponse DELETE(WebRequest webRequest, WebClient webClient = null)
+ {
+ webRequest.restRequest.Method = Method.DELETE;
+ return ClientRequestMethod(webClient, webRequest);
+ }
+
+ ///
+ /// Execute the given request, on a client if one is supplied, using the standard http HEAD method.
+ ///
+ /// The request to be executed.
+ /// (optional) The client that will execute the request.
+ /// The response from the server.
+ public static WebResponse HEAD(WebRequest webRequest, WebClient webClient = null)
+ {
+ webRequest.restRequest.Method = Method.HEAD;
+ return ClientRequestMethod(webClient, webRequest);
+ }
+
+ ///
+ /// Execute the given request, on a client if one is supplied, using the standard http MERGE method.
+ ///
+ /// The request to be executed.
+ /// (optional) The client that will execute the request.
+ /// The response from the server.
+ public static WebResponse MERGE(WebRequest webRequest, WebClient webClient = null)
+ {
+ webRequest.restRequest.Method = Method.MERGE;
+ return ClientRequestMethod(webClient, webRequest);
+ }
+
+ ///
+ /// Execute the given request, on a client if one is supplied, using the standard http OPTIONS method.
+ ///
+ /// The request to be executed.
+ /// (optional) The client that will execute the request.
+ /// The response from the server.
+ public static WebResponse OPTIONS(WebRequest webRequest, WebClient webClient = null)
+ {
+ webRequest.restRequest.Method = Method.OPTIONS;
+ return ClientRequestMethod(webClient, webRequest);
+ }
+
+ ///
+ /// Execute the given request, on a client if one is supplied, using the standard http PATCH method.
+ ///
+ /// The request to be executed.
+ /// (optional) The client that will execute the request.
+ /// The response from the server.
+ public static WebResponse PATCH(WebRequest webRequest, WebClient webClient = null)
+ {
+ webRequest.restRequest.Method = Method.PATCH;
+ return ClientRequestMethod(webClient, webRequest);
+ }
+
+ #endregion
+ }
+}
diff --git a/src/DynaWeb/Classes/WebClient.cs b/src/DynaWeb/Classes/WebClient.cs
new file mode 100644
index 0000000..c5ea67e
--- /dev/null
+++ b/src/DynaWeb/Classes/WebClient.cs
@@ -0,0 +1,252 @@
+using Autodesk.DesignScript.Runtime;
+using RestSharp;
+using System;
+
+namespace DynaWeb
+{
+ ///
+ /// A web client is used to translate request objects into HTTP requests and process the server response.
+ /// The web client also represents a uniquely configured connection to a server or service.
+ ///
+ public class WebClient
+ {
+
+ #region private members
+ ///
+ /// This is the wrapped RestSharp RestClient.
+ ///
+ internal RestClient restClient;
+
+ ///
+ /// This auth token is used to authenticate requests made by the client.
+ /// Use it as the private store for OAuth tokens for example.
+ ///
+ private string authToken;
+
+ ///
+ /// This auth code is used during OAuth authentication flows.
+ ///
+ private string authCode;
+
+ ///
+ /// This string is used to verify responses from the server during authentication flows.
+ ///
+ private string authVerification;
+ #endregion
+
+ #region public client settings
+
+ ///
+ /// This is the base URL for all future requests made by its client.
+ /// This URL is combined with the request resource (ex: DynamoDS/Dynamo/issues) to construct the final URL for request.
+ /// (ex: https://github.com/DynamoDS/Dynamo/issues)
+ /// Should include scheme (ex: http://) and domain (ex: www.dynamobim.org) without trailing slash (/).
+ ///
+ public Uri BaseUrl { get => restClient.BaseUrl; set => restClient.BaseUrl = value; }
+
+ ///
+ /// Optional UserAgent to use for requests made by this client instance. (ex: Dynamo1.3)
+ /// Used by the server to record where the request is coming from.
+ ///
+ public string UserAgent { get => restClient.UserAgent; set => restClient.UserAgent = value; }
+
+ ///
+ /// Timeout in milliseconds to use for requests made by this client instance
+ ///
+ public int Timeout { get => restClient.Timeout; set => restClient.Timeout = value; }
+
+ ///
+ /// Determine whether or not requests that result in HTTP status codes of 3xx should follow returned redirect. Defaults to true.
+ ///
+ public bool FollowRedirects
+ {
+ get => restClient.FollowRedirects;
+ set
+ {
+ restClient.FollowRedirects = value;
+ if (restClient.FollowRedirects == true && MaxRedirects == null)
+ MaxRedirects = 1;
+ }
+ }
+
+ ///
+ /// Maximum number of redirects to follow if FollowRedirects is true. Defaults to 1 if not set.
+ ///
+ public int? MaxRedirects
+ {
+ get
+ {
+ if (FollowRedirects == true) return restClient.MaxRedirects;
+ else return null;
+ }
+ set => restClient.MaxRedirects = value;
+ }
+
+ ///
+ /// Use this to override which node in the JSON response is used as the root/starting point for deserialisation.
+ ///
+ public string JsonTokenOverride { get; set; }
+
+ #endregion
+
+ #region constructors
+
+ ///
+ /// Build a new WebClient using the specified URL as its base.
+ /// A web client is used to translate request objects into HTTP requests and process the server response.
+ /// The web client also represents a uniquely configured connection to a server or service.
+ ///
+ /// The URL to use for all future requests made by this client.
+ /// Should include scheme (ex: http://) and domain (ex: www.dynamobim.org) without trailing slash (/).
+ ///
+ public static WebClient ByUrl(string baseUrl)
+ {
+ return new WebClient(baseUrl, "");
+ }
+
+ ///
+ /// Build a new WebClient using the specified URL as its base.
+ /// A web client is used to translate request objects into HTTP requests and process the server response.
+ /// The web client also represents a uniquely configured connection to a server or service.
+ ///
+ /// The URL to use for all future requests made by this client.
+ /// Should include scheme (ex: http://) and domain (ex: www.dynamobim.org) without trailing slash (/).
+ ///
+ /// The auth token is used to authenticate requests made by the client.
+ /// Use it as the private store for OAuth tokens for example.
+ /// Once the client is created, this cannot be changed.
+ public static WebClient ByUrlToken(string baseUrl, string token)
+ {
+ if (string.IsNullOrEmpty(token)) throw new ArgumentNullException(DynaWeb.Properties.Resources.WebClientTokenNullMessage);
+
+ return new WebClient(baseUrl, token);
+ }
+
+ private WebClient(string baseUrl, string token="")
+ {
+ if (string.IsNullOrEmpty(baseUrl)) throw new ArgumentNullException(DynaWeb.Properties.Resources.WebClientUrlNullMessage);
+
+ this.restClient = new RestClient(baseUrl);
+ this.authToken = token;
+ this.UserAgent = "DynamoDS";
+ }
+
+ #endregion
+
+ #region execution
+
+ ///
+ /// Executes a WebRequest in the context of the client and returns the response from the server.
+ ///
+ /// The WebClient to use for execution of request.
+ /// The web WebRequest to execute.
+ /// The response from the server as a WebResponse object.
+ [CanUpdatePeriodically(true)]
+ public static WebResponse Execute(WebClient client, WebRequest request)
+ {
+ if (client==null) throw new ArgumentNullException(DynaWeb.Properties.Resources.WebClientNullMessage);
+ if (request == null) throw new ArgumentNullException(DynaWeb.Properties.Resources.WebRequestNullMessage);
+
+ request.response = DynaWeb.Execute.ByClientRequestMethod(client, request, request.Method.ToString());
+ return request.response;
+ }
+
+ #endregion
+
+ #region public static methods
+
+ ///
+ /// Assembles the URL to call based on parameters, method and resource.
+ /// Not needed to run the request, but useful for debugging purposes.
+ ///
+ /// The WebClient to update.
+ /// The request to execute
+ /// A string representation of the assembly Uri
+ public static string BuildUri(WebClient client, WebRequest request)
+ {
+ if (request == null) throw new ArgumentNullException(DynaWeb.Properties.Resources.WebClientRequestNullMessage);
+
+ return client.restClient.BuildUri(request.restRequest).ToString();
+ }
+
+ ///
+ /// Set the base URL for this client.
+ ///
+ /// The WebClient to update.
+ /// The value to set BaseUrl to, has to be a valid URL.
+ /// The WebClient supplied with an updated BaseUrl property.
+ public WebClient SetBaseURL(string url)
+ {
+ if (string.IsNullOrEmpty(url)) throw new ArgumentNullException(DynaWeb.Properties.Resources.WebClientUrlNullMessage);
+ if (!Helpers.CheckURI(Helpers.ParseUriFromString(url))) throw new ArgumentNullException(DynaWeb.Properties.Resources.WebUrlInvalidMessage);
+ this.BaseUrl = Helpers.ParseUriFromString(url);
+ return this;
+ }
+
+ ///
+ /// Set the user agent communicated with requests this client sends.
+ ///
+ /// The WebClient to update.
+ /// The value to set the UserAgent to.
+ /// The WebClient supplied with the an UserAgent property.
+ public WebClient SetUserAgent(string userAgent)
+ {
+ if (string.IsNullOrEmpty(userAgent)) throw new ArgumentNullException(DynaWeb.Properties.Resources.WebClientUserAgentNullMessage);
+ this.UserAgent = userAgent;
+ return this;
+ }
+
+ ///
+ /// Set the timeout in milliseconds to use for requests made by this client instance
+ ///
+ /// The WebClient to update.
+ /// The value to set timeout to, expressed in milliseconds.
+ /// The WebClient supplied with an updated Timeout property.
+ public WebClient SetTimeout(int timeout)
+ {
+ if (timeout <= 0) throw new ArgumentNullException(DynaWeb.Properties.Resources.WebClientTimeoutInvalidMessage);
+ this.Timeout = timeout;
+ return this;
+ }
+
+ ///
+ /// Sets the FollowRedirects setting of the client. This controls whether or not requests that result in HTTP status codes of 3xx should follow returned redirect. Default is true.
+ ///
+ /// The WebClient to update.
+ /// True to follow redirects, false to end request.
+ /// The WebClient supplied with an updated FollowRedirects property.
+ public WebClient SetFollowRedirects(bool followRedirects = true)
+ {
+ this.FollowRedirects = followRedirects;
+ return this;
+ }
+
+ ///
+ /// Set the maximum number of redirects to follow if FollowRedirects is true.
+ ///
+ /// The WebClient to update.
+ /// The value to set maximum to, expressed as an integer.
+ /// The WebClient supplied with an updated MaxRedirects property.
+ public WebClient SetMaxRedirects(int maxRedirects)
+ {
+ if (maxRedirects <= 0) throw new ArgumentNullException(DynaWeb.Properties.Resources.WebClientTimeoutInvalidMessage);
+ this.MaxRedirects = maxRedirects;
+ return this;
+ }
+
+ ///
+ /// Set the JsonTokenOverride that is used for deserialisation purposes.
+ ///
+ /// The WebClient to update.
+ /// The value to set JsonTokenOverride to.
+ /// The WebClient supplied with an updated JsonTokenOverride property.
+ public WebClient SetJsonTokenOverride(string jsonToken)
+ {
+ if (string.IsNullOrEmpty(jsonToken)) throw new ArgumentNullException(DynaWeb.Properties.Resources.WebClientTokenNullMessage);
+ this.JsonTokenOverride = jsonToken;
+ return this;
+ }
+
+ #endregion
+ }
+}
diff --git a/src/DynaWeb/Classes/WebRequest.cs b/src/DynaWeb/Classes/WebRequest.cs
new file mode 100644
index 0000000..99a38ef
--- /dev/null
+++ b/src/DynaWeb/Classes/WebRequest.cs
@@ -0,0 +1,501 @@
+using Autodesk.DesignScript.Runtime;
+using RestSharp;
+using System;
+using System.Collections.Generic;
+using System.Net;
+using System.Collections.Specialized;
+using System.IO;
+
+namespace DynaWeb
+{
+ ///
+ /// A web request is the mechanism through which we can communicate with web servers,
+ /// requesting information from them or send data to them.
+ ///
+ public class WebRequest
+ {
+ #region constants
+
+ ///
+ /// The default timeout to wait for a request to return, expressed in miliseconds
+ ///
+ private const int defaultRequestTimeout = 1500;
+
+ ///
+ /// The default number of times to retry a failed request
+ ///
+ private const int defaultRequestAttempts = 3;
+
+ ///
+ /// The default security protocol to default to.
+ /// The protocol is required for interaction with HTTPS endpoints, irrespective of using System.Net or RestSharp libraries.
+ ///
+ private const SecurityProtocolType defaultSecurityProtocol = SecurityProtocolType.Tls12;
+
+ ///
+ /// The default URL to use when constructing a WebRequest by endpoint only.
+ /// This then gets disregarded by the WebClient during execution.
+ ///
+ private const string defaultUrl = "http://www.dynamobim.org";
+
+ #endregion
+
+ #region private/internal properties
+
+ ///
+ /// The encapsulated Restsharp web request
+ ///
+ internal RestRequest restRequest = new RestRequest();
+
+ ///
+ /// The encapsulated response from the server
+ ///
+ internal WebResponse response = new WebResponse(new RestResponse());
+
+ internal Uri url;
+
+ private StringDictionary headers = new StringDictionary();
+ private Dictionary parameters = new Dictionary();
+
+ #endregion
+
+ #region public properties
+
+ ///
+ /// The response the server returned on the last execution of the request.
+ ///
+ public WebResponse Response => this.response;
+
+ ///
+ /// The URL for the request.
+ /// This is ignored when the request is executed by a WebClient node, use the WebRequest "resource" in that case.
+ ///
+ public string URL
+ {
+ get => url.ToString();
+ set { url = Helpers.ParseUriFromString(value.ToString()); }
+ }
+
+ ///
+ /// Set this property to true to force requests to go through a security protocol (TLS1.2).
+ /// This is required when interacting with servers and APIs that require use of HTTPS as a protocol rather than HTTP.
+ ///
+ public bool ForceSecurityProtocol = false;
+
+ #endregion
+
+ #region IRestRequest interface fields
+
+ ///
+ /// Container of all HTTP parameters to be passed with the request.
+ /// See for explanation of the types of parameters that can be passed
+ ///
+ public List Parameters => restRequest.Parameters;
+
+ ///
+ /// Container of all the files to be uploaded with the request.
+ ///
+ public List Files => restRequest.Files;
+
+ ///
+ /// Determines what HTTP method to use for this request.
+ /// Supported methods: GET, POST, PUT, DELETE, HEAD, OPTIONS
+ /// Default is GET
+ ///
+ public Method Method
+ {
+ get => restRequest.Method;
+ set => restRequest.Method = value;
+ }
+
+ ///
+ /// The Resource URL to make the request against, should not include the scheme or domain.
+ /// Ignored when the WebRequest is not executed through a WebClient.
+ /// Do not include leading slash. Combined with web client BaseUrl to assemble final URL:
+ /// {BaseUrl}/{Resource} (BaseUrl is scheme + domain, e.g. http://example.com)
+ ///
+ public string Resource
+ {
+ get => restRequest.Resource;
+ set => restRequest.Resource = value;
+ }
+
+ ///
+ /// Used by the default deserializers to determine where to start deserializing from.
+ /// Can be used to skip container or root elements that do not have corresponding deserialzation targets.
+ /// Example : most APIs return values wrapped in a root "data" element.
+ ///
+ public string RootElement
+ {
+ get => restRequest.RootElement;
+ set => restRequest.RootElement = value;
+ }
+
+ ///
+ /// Timeout in milliseconds to be used for the request.
+ /// This timeout value overrides a timeout set on the Web Client.
+ ///
+ public int Timeout
+ {
+ get => restRequest.Timeout;
+ set => restRequest.Timeout = value;
+ }
+
+ ///
+ /// The number of milliseconds before the writing or reading times out.
+ /// This timeout value overrides a timeout set on a Web Client.
+ ///
+ public int ReadWriteTimeout
+ {
+ get => restRequest.ReadWriteTimeout;
+ set => restRequest.ReadWriteTimeout = value;
+ }
+
+ ///
+ /// How many attempts were made to send this Request?
+ /// This Number is incremented each time the web client sends the request.
+ /// Useful when using Asynchronous Execution with Callbacks
+ ///
+ public int Attempts => restRequest.Attempts;
+
+ ///
+ /// Serializer to use. Can be JSON or XML, defaults to XML.
+ ///
+ public DataFormat RequestFormat
+ {
+ get => restRequest.RequestFormat;
+ set => restRequest.RequestFormat = value;
+ }
+
+ #endregion
+
+ #region constructor methods
+
+ ///
+ /// Private constructor : Build a simple GET web request to the specified URL
+ ///
+ /// The URL to send the request to.
+ /// The endpoint, or resource, used in conjunction with a WebClient base URL.
+ /// The request object, ready for execution.
+ private WebRequest(string url, string resource)
+ {
+ // handle the case where only endpoint is needed,
+ // but a valid URL is still required for the RestSharp request constructor
+ if (string.IsNullOrEmpty(url) && !string.IsNullOrEmpty(resource))
+ URL = defaultUrl;
+ else URL = url;
+
+ restRequest = new RestRequest(this.URL, Method.GET);
+ restRequest.Resource = resource;
+ }
+
+ ///
+ /// Build a simple GET web request to the specified URL
+ ///
+ /// The URL to send the request to.
+ /// The request object, ready for execution.
+ public static WebRequest ByUrl(string url)
+ {
+ if (string.IsNullOrEmpty(url)) throw new ArgumentNullException(DynaWeb.Properties.Resources.WebUrlNullMessage);
+ return new WebRequest(url, null);
+ }
+
+ ///
+ /// Build a simple GET web request to the specified URL
+ ///
+ /// The resource (or endpoint) to use for the request.
+ /// This will be used in conjunction with a WebClient base URL to form the full request URL.
+ /// ex : "users".
+ /// The request object, ready for execution.
+ public static WebRequest ByEndpoint(string endpoint)
+ {
+ if (string.IsNullOrEmpty(endpoint)) throw new ArgumentNullException(DynaWeb.Properties.Resources.WebRequestEndpointNullMessage);
+ return new WebRequest(null, endpoint);
+ }
+
+ #endregion
+
+ #region Execution
+
+ ///
+ /// Executes a WebRequest and returns the response from the server.
+ ///
+ /// The web request to execute.
+ /// The response from the server as a WebResponse object.
+ [CanUpdatePeriodically(true)]
+ public static WebResponse Execute(WebRequest request)
+ {
+ request.response = DynaWeb.Execute.ByClientRequestMethod(null, request, request.Method.ToString());
+ return request.response;
+ }
+
+ #endregion
+
+ #region extension methods
+
+ ///
+ /// Sets the HTTP method to use for the request.
+ /// Valid input : GET, DELETE, HEAD, OPTIONS, POST, PUT, MERGE
+ /// Note : input is not case-sensitive.
+ ///
+ /// The request to update.
+ /// The string that represents the http method.
+ /// The WebRequest updated with set method if input was valid, the unchanged WebRequest otherwise.
+ public WebRequest SetMethod(string method)
+ {
+ if (Enum.TryParse(method, true, out Method reqMethod))
+ this.restRequest.Method = reqMethod;
+ else throw new InvalidDataException("Could not parse the method!");
+
+ return this;
+ }
+
+ ///
+ /// Sets the default serialiser to use with this request.
+ ///
+ /// The request to update
+ /// The serialiser to use as case-insensitive string.
+ /// Valid inputs : JSON, XML
+ /// The updated request if supplied format was valid, the unchanged request if not.
+ public WebRequest SetRequestFormat(string format)
+ {
+ if (Enum.TryParse(format, true, out DataFormat dataFormat))
+ this.restRequest.RequestFormat = dataFormat;
+ return this;
+ }
+
+ ///
+ /// Sets the URL of the request.
+ ///
+ /// The request to update
+ /// The URL to set for the request.
+ /// The request with an updated URL.
+ public WebRequest SetUrl(string url)
+ {
+ this.URL = url;
+ return this;
+ }
+
+ ///
+ /// Sets the resource of the request. Ignored when not executed through a WebClient.
+ /// This is combined with a WebClient base URL to form a complete request URL.
+ ///
+ /// The request to update
+ /// The resource to set for the request.
+ /// The request with an updated URL.
+ public WebRequest SetResource(string resource)
+ {
+ this.Resource = resource;
+ return this;
+ }
+
+ ///
+ /// Sets the value of the ForceSecurityProtocol property.
+ /// Use this property to foce use of TLS1.2, required when interacting over HTTPS.
+ ///
+ /// The request to update
+ /// True or False
+ /// The request
+ public WebRequest SetSecurityProtocol(bool forceSecurity)
+ {
+ this.ForceSecurityProtocol = forceSecurity;
+ return this;
+ }
+
+ ///
+ /// Adds a file to the Files collection to be included with a POST or PUT request (other methods do not support file uploads).
+ ///
+ /// The request to update
+ /// The parameter name to use in the request
+ /// Full path to file to upload
+ /// The MIME type of the file to upload
+ /// This request
+ public WebRequest AddFile(string name, string path, string contentType = null)
+ {
+ if (this.restRequest.Method != Method.POST && this.restRequest.Method != Method.PUT)
+ throw new InvalidOperationException("Can only add a file to a POST or PUT request.");
+
+ this.restRequest.AddFile(name, path, contentType);
+ return this;
+ }
+
+ ///
+ /// Adds the raw bytes of a file to the body of the request. Useful for situations when multipart data is not supported by the server.
+ ///
+ /// The name of the parameter, usually the name of the file.
+ /// The file name.
+ /// The full path to the file to be uploaded.
+ /// The request updated.
+ public WebRequest AddFileAsBytes(string name, string filename, string filepath)
+ {
+ try
+ {
+ var bytes = File.ReadAllBytes(filepath);
+ this.restRequest.AddParameter("application/octet-stream", bytes, ParameterType.RequestBody);
+ }
+ catch (Exception)
+ {
+ throw new InvalidOperationException(DynaWeb.Properties.Resources.WebIOFileNotRead);
+ }
+
+ return this;
+ }
+
+
+ ///
+ /// Serializes obj to data format specified by RequestFormat and adds it to the request body.
+ /// The default format is XML. Change RequestFormat if you wish to use a different serialization format.
+ ///
+ /// The request to update
+ /// The object to serialize
+ /// This request
+ public WebRequest AddBody(object obj)
+ {
+ if (this.restRequest.Method == Method.GET) throw new InvalidOperationException("Cannot add a body parameter to a GET request");
+
+ this.restRequest.AddBody(obj);
+ return this;
+ }
+
+ ///
+ /// Serializes obj to JSON format and adds it to the request body.
+ ///
+ /// The request to update
+ /// The object to serialize
+ /// This request
+ public WebRequest AddJsonBody(object obj)
+ {
+ if (this.restRequest.Method == Method.GET) throw new InvalidOperationException("Cannot add a body parameter to a GET request");
+
+ this.restRequest.AddJsonBody(obj);
+ return this;
+ }
+
+ ///
+ /// Serializes obj to XML format and adds it to the request body.
+ ///
+ /// The request to update
+ /// The object to serialize
+ /// This request
+ public WebRequest AddXmlBody(object obj)
+ {
+ if (this.restRequest.Method == Method.GET) throw new InvalidOperationException("Cannot add a body parameter to a GET request");
+
+ this.restRequest.AddXmlBody(obj);
+ return this;
+ }
+
+ ///
+ /// Calls AddParameter() for all public, readable properties of obj
+ ///
+ /// The request to update
+ /// The object with properties to add as parameters
+ /// This request
+ public WebRequest AddObject(object obj)
+ {
+ var hash = obj.GetHashCode().ToString();
+ if (this.parameters.ContainsKey(hash)) return this;
+
+ this.parameters.Add(hash, obj);
+ this.restRequest.AddObject(obj);
+ return this;
+ }
+
+ ///
+ /// Adds a HTTP parameter to the request.
+ /// Uses QueryString for GET, DELETE, OPTIONS and HEAD, Encoded form for POST and PUT
+ ///
+ /// The request to update
+ /// The name of the parameter to add.
+ /// The value of the parameter to add.
+ /// The type of the parameter to add.
+ /// Valid inputs: Cookie, GetOrPost, HttpHeader, QueryString, RequestBody, UrlSegment
+ /// The request with the added parameter.
+ public WebRequest AddParameter(string name, object value, string parameterType)
+ {
+ if (string.IsNullOrEmpty(name))
+ throw new ArgumentNullException("Name parameter cannot be null.");
+ if (value.Equals(null))
+ throw new ArgumentNullException("Value parameter cannot be null.");
+ if (Enum.TryParse(parameterType, true, out ParameterType pType) == false)
+ throw new ArgumentException("Could not parse the supplied value into a valid Parameter Type.");
+
+ try
+ {
+ this.parameters.Add(name, value);
+ // if the item was added, we should also add it to the wrapped RestRequest
+ this.restRequest.AddParameter(name, value, pType);
+ }
+ catch (Exception e)
+ {
+ // the addition silently fails
+ // TODO : add warning bubble on node without throwing Exception
+ // as that would stop downstream nodes from executing
+ }
+ return this;
+ }
+
+ ///
+ /// Shortcut to AddParameter(name, value, HttpHeader)
+ ///
+ /// The request to update
+ /// Name of the header to add
+ /// Value of the header to add
+ ///
+ public WebRequest AddHeader(string name, string value)
+ {
+ try
+ {
+ this.headers.Add(name, value);
+ // if the header was added, we should also add it to the wrapped RestRequest
+ this.restRequest.AddHeader(name, value);
+ }
+ catch (Exception e)
+ {
+ // the addition silently fails
+ // TODO : add warning bubble on node without throwing Exception
+ // as that would stop downstream nodes from executing
+ }
+ return this;
+ }
+
+ ///
+ /// Shortcut to AddParameter(name, value, Cookie)
+ ///
+ /// The request to update
+ /// Name of the cookie to add
+ /// Value of the cookie to add
+ ///
+ public WebRequest AddCookie(string name, string value)
+ {
+ this.restRequest.AddCookie(name, value);
+ return this;
+ }
+
+ ///
+ /// Shortcut to AddParameter(name, value, UrlSegment)
+ ///
+ /// The request to update
+ /// Name of the segment to add
+ /// Value of the segment to add
+ ///
+ public WebRequest AddUrlSegment(string name, string value)
+ {
+ return AddParameter(name, value, ParameterType.UrlSegment.ToString());
+ }
+
+ ///
+ /// Shortcut to AddParameter(name, value, QueryString)
+ ///
+ /// The request to update
+ /// Name of the parameter to add
+ /// Value of the parameter to add
+ ///
+ public WebRequest AddQueryParameter(string name, string value)
+ {
+ return AddParameter(name, value, ParameterType.QueryString.ToString());
+ }
+
+ #endregion
+ }
+}
diff --git a/src/DynaWeb/Classes/WebResponse.cs b/src/DynaWeb/Classes/WebResponse.cs
new file mode 100644
index 0000000..10cdb86
--- /dev/null
+++ b/src/DynaWeb/Classes/WebResponse.cs
@@ -0,0 +1,92 @@
+using RestSharp;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Net;
+using Autodesk.DesignScript.Runtime;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System.Linq;
+
+namespace DynaWeb
+{
+ ///
+ /// The response returned from a server after a WebRequest was executed
+ ///
+ public class WebResponse
+ {
+ #region private properties
+ private IRestResponse response;
+ #endregion
+
+ #region public properties
+
+ // properties relating to the content of the response
+ public string Content => this.response.Content;
+ public string ContentType => this.response.ContentType;
+ public long ContentLength => this.response.ContentLength;
+ public string ContentEncoding => this.response.ContentEncoding;
+ public byte[] RawBytes => this.response.RawBytes;
+
+ // properties relating to the status of the response
+ public string StatusCode => this.response.StatusCode.ToString();
+ public string StatusDescription => this.response.StatusDescription;
+ public string ResponseStatus => this.response.ResponseStatus.ToString();
+ public string ErrorException => this.response.ErrorException.ToString();
+ public string ErrorMessage => this.response.ErrorMessage;
+ public System.TimeSpan Time { get; internal set; }
+
+ // meta properties that have information about the response itself
+ public Uri ResponseUri => this.response.ResponseUri;
+ public string Server => this.response.Server;
+ public List> Headers
+ {
+ get
+ {
+ var headersDict = this.response.Headers.ToDictionary(x => x.Name);
+ var headers = new List>();
+ headers.Add(headersDict.Keys.ToList());
+ headers.Add(headersDict.Values.Select(x => x.Value.ToString()).ToList());
+
+ return headers;
+ }
+ }
+
+ public List> Cookies
+ {
+ get
+ {
+ var result = new List>();
+
+ foreach (var cookie in this.response.Cookies)
+ {
+ var values = new List();
+ values.Add(cookie.Name);
+ values.Add(cookie.Value);
+ values.Add(cookie.TimeStamp.ToString());
+
+ result.Add(new List() { "Name", "Value", "TimeStamp" });
+ result.Add(values);
+ }
+
+ return result;
+ }
+ }
+
+ #endregion
+
+ #region constructor
+ ///
+ /// Represents data returned by the server, contains both meta-data about the response/server as well the content of the response itself.
+ ///
+ /// Extract the response after the execution of a WebRequest.
+ /// Connect the output of "Execute" nodes to this as input.
+ public WebResponse(IRestResponse res)
+ {
+ this.response = res;
+ }
+ #endregion
+ }
+}
diff --git a/src/DynaWeb/Config/keys.sample.xml b/src/DynaWeb/Config/keys.sample.xml
new file mode 100644
index 0000000..fbd3555
--- /dev/null
+++ b/src/DynaWeb/Config/keys.sample.xml
@@ -0,0 +1,6 @@
+
+
+ INSERT YOU API KEY HERE
+ rename this file to keys.xml
+ Bearer 0/xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+
\ No newline at end of file
diff --git a/src/DynaWeb/Config/pkg.json b/src/DynaWeb/Config/pkg.json
new file mode 100644
index 0000000..65b0712
--- /dev/null
+++ b/src/DynaWeb/Config/pkg.json
@@ -0,0 +1,26 @@
+{
+ "license": "AGPL-3.0",
+ "file_hash": null,
+ "name": "www",
+ "version": "2017.0.1.0",
+ "description": "Dynamo support for interaction with the Web & REST APIs.",
+ "group": "radugidei",
+ "keywords": [
+ "web",
+ "integration",
+ "rest api",
+ "api",
+ "request"
+ ],
+ "dependencies": [],
+ "contents": "",
+ "engine_version": "1.2.1.3083",
+ "engine": "dynamo",
+ "engine_metadata": "",
+ "site_url": "www.radugidei.com",
+ "repository_url": "www.github.com/radumg/DynWWW",
+ "contains_binaries": true,
+ "node_libraries": [
+ "DynWWW, Version=2017.0.1.0, Culture=neutral, PublicKeyToken=null"
+ ]
+}
\ No newline at end of file
diff --git a/src/DynaWeb/DynaWeb.csproj b/src/DynaWeb/DynaWeb.csproj
new file mode 100644
index 0000000..7183d69
--- /dev/null
+++ b/src/DynaWeb/DynaWeb.csproj
@@ -0,0 +1,174 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {CE19C882-1AAC-434C-99AF-4A285DA053BA}
+ Library
+ Properties
+ DynaWeb
+ DynaWeb
+ v4.5.2
+ 512
+
+
+ true
+ full
+ false
+ ..\..\build\debug\
+ DEBUG;TRACE
+ prompt
+ 4
+ ..\..\build\debug\DynaWeb.xml
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ packages\DynamoVisualProgramming.DynamoCoreNodes.1.3.0\lib\net45\Analysis.dll
+ False
+
+
+ packages\DynamoVisualProgramming.DynamoCoreNodes.1.3.0\lib\net45\Display.dll
+ False
+
+
+ packages\DynamoVisualProgramming.DynamoCoreNodes.1.3.0\lib\net45\DSCoreNodes.dll
+ False
+
+
+ packages\DynamoVisualProgramming.Core.1.3.0\lib\net45\DSIronPython.dll
+ False
+
+
+ packages\DynamoVisualProgramming.Core.1.3.0\lib\net45\DynamoApplications.dll
+ False
+
+
+ packages\DynamoVisualProgramming.Core.1.3.0\lib\net45\DynamoCore.dll
+ False
+
+
+ packages\DynamoVisualProgramming.Core.1.3.0\lib\net45\DynamoInstallDetective.dll
+ False
+
+
+ packages\DynamoVisualProgramming.DynamoServices.1.3.0\lib\net45\DynamoServices.dll
+ False
+
+
+ packages\DynamoVisualProgramming.Core.1.3.0\lib\net45\DynamoShapeManager.dll
+ False
+
+
+ packages\DynamoVisualProgramming.ZeroTouchLibrary.1.3.0\lib\net45\DynamoUnits.dll
+ False
+
+
+ packages\DynamoVisualProgramming.Core.1.3.0\lib\net45\DynamoUtilities.dll
+ False
+
+
+ ..\packages\Prism.Composition.5.0.0\lib\NET45\Microsoft.Practices.Prism.Composition.dll
+ False
+
+
+ ..\packages\Prism.Interactivity.5.0.0\lib\NET45\Microsoft.Practices.Prism.Interactivity.dll
+ False
+
+
+ ..\packages\Prism.Mvvm.1.0.0\lib\net45\Microsoft.Practices.Prism.Mvvm.dll
+ False
+
+
+ ..\packages\Prism.Mvvm.1.0.0\lib\net45\Microsoft.Practices.Prism.Mvvm.Desktop.dll
+ False
+
+
+ ..\packages\Prism.PubSubEvents.1.0.0\lib\portable-sl4+wp7+windows8+net40\Microsoft.Practices.Prism.PubSubEvents.dll
+ False
+
+
+ ..\packages\Prism.Mvvm.1.0.0\lib\net45\Microsoft.Practices.Prism.SharedInterfaces.dll
+ False
+
+
+ ..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll
+ False
+
+
+ ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll
+ False
+
+
+ packages\DynamoVisualProgramming.DynamoServices.1.3.0\lib\net45\NodeServices2.dll
+ False
+
+
+ ..\packages\NUnit.3.7.1\lib\net45\nunit.framework.dll
+ False
+
+
+ packages\DynamoVisualProgramming.Core.1.3.0\lib\net45\ProtoCore.dll
+ False
+
+
+ packages\DynamoVisualProgramming.ZeroTouchLibrary.1.3.0\lib\net45\ProtoGeometry.dll
+ False
+
+
+ ..\packages\RestSharp.105.2.3\lib\net452\RestSharp.dll
+ False
+
+
+
+
+
+
+
+
+
+
+ packages\DynamoVisualProgramming.Core.1.3.0\lib\net45\VMDataBridge.dll
+ False
+
+
+
+
+
+
+
+
+
+
+
+ True
+ True
+ Resources.resx
+
+
+
+
+
+
+
+
+
+
+
+ ResXFileCodeGenerator
+ Resources.Designer.cs
+
+
+
+
+ (robocopy $(OutDir) C:\users\radug\desktop\testing /W:3 /R:3 /IT /IS /XF *.tmp) ^& IF %25ERRORLEVEL%25 LEQ 4 exit /B 0
+
+
\ No newline at end of file
diff --git a/src/DynaWeb/Helpers/WebHelpers.cs b/src/DynaWeb/Helpers/WebHelpers.cs
new file mode 100644
index 0000000..bff7d57
--- /dev/null
+++ b/src/DynaWeb/Helpers/WebHelpers.cs
@@ -0,0 +1,213 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using DynaWeb.Properties;
+using Autodesk.DesignScript.Runtime;
+using DynaWeb;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System.Reflection;
+using Newtonsoft.Json.Converters;
+using System.Dynamic;
+
+namespace DynaWeb
+{
+ public static class Helpers
+ {
+ #region URL & Uri handling
+ ///
+ /// Constructs a valid URI from a supplied string URL. Use this to both check and ensure URLs are valid
+ ///
+ /// The URL to check.
+ /// A valid URI if the string URL is valid, throws Exception if not.
+ public static Uri ParseUriFromString(string url)
+ {
+ if (string.IsNullOrEmpty(url))
+ {
+ throw new ArgumentException(DynaWeb.Properties.Resources.WebUrlNullMessage);
+ }
+
+ Uri uriResult;
+ var result = Uri.TryCreate(url, UriKind.Absolute, out uriResult)
+ && (uriResult.Scheme == Uri.UriSchemeHttp
+ || uriResult.Scheme == Uri.UriSchemeHttps);
+
+ if (!result)
+ {
+ throw new UriFormatException(DynaWeb.Properties.Resources.WebUrlInvalidMessage);
+ }
+
+ return uriResult;
+ }
+
+ /// Check the URI is valid
+ /// The URI to check
+ /// True if is valid, False otherwise
+ public static Boolean CheckURI(Uri uriToCheck)
+ {
+ if (uriToCheck.IsFile || uriToCheck.IsUnc) throw new Exception("URI is file or is UNC pointing to internal network");
+
+ if (!Uri.CheckSchemeName(uriToCheck.Scheme))
+ return false;
+ return true;
+ }
+
+ #endregion
+
+ #region deserialisation
+
+ ///
+ /// Recursively parse a JSON token into native data types.
+ /// This includes all children of the JSON object, regardless of how many levels of nesting there are.
+ ///
+ /// The JSON token (object) to parse.
+ /// The parsed object
+ public static object Deserialise(string json)
+ {
+ return ParseObject(JToken.Parse(json));
+ }
+
+ ///
+ /// Deserialises a JSON string to a .NET object.
+ ///
+ /// The JSON string that needs to be deserialised.
+ /// The response deserialised as an object.
+ public static dynamic DeserializeAsObject(string json)
+ {
+ /// We don't want the deserialisation to break if some properties are empty.
+ /// So we need to specify the behaviour when such values are encountered.
+ JsonSerializerSettings settings = new JsonSerializerSettings();
+ settings.NullValueHandling = NullValueHandling.Ignore;
+ settings.MissingMemberHandling = MissingMemberHandling.Ignore;
+ settings.CheckAdditionalContent = true;
+
+ return JsonConvert.DeserializeObject(json, settings);
+ }
+
+ ///
+ /// Deserialises a JSON string to the type of a supplied object.
+ ///
+ /// The object type to deserialize to.
+ /// The JSON string that needs to be deserialised.
+ /// The object that will be used to determine what type to deserialise to.
+ /// The response deserialised as same type as supplied object.
+ public static dynamic DeserializeByObjectType(string json, object obj)
+ {
+ /// We don't want the deserialisation to break if some properties are empty.
+ /// So we need to specify the behaviour when such values are encountered.
+ JsonSerializerSettings settings = new JsonSerializerSettings();
+ settings.NullValueHandling = NullValueHandling.Ignore;
+ settings.MissingMemberHandling = MissingMemberHandling.Ignore;
+ settings.CheckAdditionalContent = true;
+ var type = obj.GetType();
+
+ return JsonConvert.DeserializeObject(json, type, settings);
+ }
+ ///
+ /// Deserialises a JSON string into a dictionary of string keys and object values.
+ /// Note : Does not handle deserialisation of nested objects.
+ ///
+ /// The JSON string to deserialise
+ /// A dictionary of the responses's JSON content.
+ [MultiReturn(new[] { "properties", "values" })]
+ public static Dictionary DeserialiseAsDictionary(string json)
+ {
+ JObject jsonObj = JObject.Parse(json);
+
+ var props = jsonObj.Properties().Select(x => x.Name).ToList();
+ var values = jsonObj.Values().Select(x => x.ToString()).ToList();
+
+ return new Dictionary
+ {
+ { "properties", props },
+ { "values", values }
+ };
+ }
+
+ ///
+ /// Serialises an object string to a JSON string.
+ ///
+ /// The object that will be serialised.
+ /// Object serialised as JSON string.
+ public static string SerializeToJSON(object obj)
+ {
+ /// We don't want the serialisation to break if some properties are empty.
+ /// So we need to specify the behaviour when such values are encountered.
+ JsonSerializerSettings settings = new JsonSerializerSettings();
+ settings.NullValueHandling = NullValueHandling.Ignore;
+ settings.MissingMemberHandling = MissingMemberHandling.Ignore;
+ settings.CheckAdditionalContent = true;
+ settings.Formatting = Formatting.Indented;
+
+ return JsonConvert.SerializeObject(obj, settings);
+ }
+
+ ///
+ /// Builds a new JSON string from the given root of an existing JSON object.
+ ///
+ /// The existing JSON
+ /// The name of the root object to return as JSON.
+ /// The new JSON string
+ public static string SelectJsonRoot(string json, string root)
+ {
+ if (string.IsNullOrEmpty(json) || string.IsNullOrEmpty(root)) throw new ArgumentNullException();
+ return JObject.Parse(json).SelectToken(root).ToString();
+ }
+
+ ///
+ /// This method will recursively parse a JSON token into native .NET types.
+ ///
+ /// The JSON token (object) to parse.
+ /// The parsed object.
+ private static object ParseObject(JToken token)
+ {
+ switch (token.Type)
+ {
+ case JTokenType.Object:
+ return token.Children()
+ .ToDictionary(prop => prop.Name,
+ prop => ParseObject(prop.Value));
+
+ case JTokenType.Array:
+ return token.Select(ParseObject).ToList();
+
+ default:
+ return ((JValue)token).Value;
+ }
+ }
+
+ #endregion
+
+ #region Type support
+
+ ///
+ /// Gets only non-null properties and their values from a Type using Reflection.
+ ///
+ /// The object to extract type properties from.
+ /// A dictionary of properties and their values.
+ internal static Dictionary GetValidProperties(object obj)
+ {
+ var parameters = new Dictionary();
+ Type type = obj.GetType();
+ foreach (PropertyInfo prop in type.GetProperties())
+ {
+ var value = prop.GetValue(obj).ToString();
+ if (!string.IsNullOrEmpty(value)) parameters.Add(prop.Name, value);
+ }
+ return parameters;
+ }
+
+ internal static dynamic WrapObject(object obj)
+ {
+ var wrapper = new
+ {
+ data = obj
+ };
+ var json = JsonConvert.SerializeObject(wrapper);
+ return ParseObject(JToken.Parse(json));
+ }
+ #endregion
+ }
+}
diff --git a/src/DynaWeb/NodeModels/WebRequestModel.cs b/src/DynaWeb/NodeModels/WebRequestModel.cs
new file mode 100644
index 0000000..3463638
--- /dev/null
+++ b/src/DynaWeb/NodeModels/WebRequestModel.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Dynamo.Graph.Nodes;
+using DynaWeb.Properties;
+using ProtoCore.AST.AssociativeAST;
+using DynaWeb;
+
+namespace CoreNodeModels.Web
+{
+ /*
+ [NodeName("Web Request")]
+ [NodeDescription("WebRequestDescription", typeof(Resources))]
+ [NodeCategory(BuiltinNodeCategories.CORE_WEB)]
+ [IsDesignScriptCompatible]
+ [AlsoKnownAs("DynaWebNodesUI.WebRequest")]
+ public class SimpleWebRequest : NodeModel
+ {
+ public SimpleWebRequest()
+ {
+ InPortData.Add(new PortData("url", Resources.WebRequestPortDataUrlToolTip));
+ OutPortData.Add(new PortData("result", Resources.WebRequestPortDataResultToolTip));
+ RegisterAllPorts();
+
+ CanUpdatePeriodically = true;
+ }
+
+ public override IEnumerable BuildOutputAst(List inputAstNodes)
+ {
+ var functionCall = AstFactory.BuildFunctionCall(
+ new Func(WebRequest.Execute),
+ inputAstNodes
+ );
+
+ return new[] { AstFactory.BuildAssignment(GetAstIdentifierForOutputIndex(0), functionCall) };
+ }
+ }
+ */
+}
diff --git a/src/DynaWeb/Properties/AssemblyInfo.cs b/src/DynaWeb/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..a9dada4
--- /dev/null
+++ b/src/DynaWeb/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+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: AssemblyTitle("DynaWeb")]
+[assembly: AssemblyDescription("DynaWeb is a Dynamo package providing support for interaction with the interwebz in general and with REST APIs in particular.")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Radu Gidei")]
+[assembly: AssemblyProduct("DynaWeb")]
+[assembly: AssemblyCopyright("Copyright Radu Gidei © 2017")]
+[assembly: AssemblyTrademark("Radu Gidei © 2017")]
+[assembly: AssemblyCulture("")]
+
+// 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("ce19c882-1aac-434c-99af-4a285da053ba")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.3.0")]
+[assembly: AssemblyFileVersion("1.0.3.0")]
diff --git a/src/DynaWeb/Properties/Resources.Designer.cs b/src/DynaWeb/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..a81aed2
--- /dev/null
+++ b/src/DynaWeb/Properties/Resources.Designer.cs
@@ -0,0 +1,252 @@
+//------------------------------------------------------------------------------
+//
+// This code was generated by a tool.
+// Runtime Version:4.0.30319.42000
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+//------------------------------------------------------------------------------
+
+namespace DynaWeb.Properties {
+ using System;
+
+
+ ///
+ /// A strongly-typed resource class, for looking up localized strings, etc.
+ ///
+ // This class was auto-generated by the StronglyTypedResourceBuilder
+ // class via a tool like ResGen or Visual Studio.
+ // To add or remove a member, edit your .ResX file then rerun ResGen
+ // with the /str option, or rebuild your VS project.
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+ internal class Resources {
+
+ private static global::System.Resources.ResourceManager resourceMan;
+
+ private static global::System.Globalization.CultureInfo resourceCulture;
+
+ [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+ internal Resources() {
+ }
+
+ ///
+ /// Returns the cached ResourceManager instance used by this class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Resources.ResourceManager ResourceManager {
+ get {
+ if (object.ReferenceEquals(resourceMan, null)) {
+ global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("DynaWeb.Properties.Resources", typeof(Resources).Assembly);
+ resourceMan = temp;
+ }
+ return resourceMan;
+ }
+ }
+
+ ///
+ /// Overrides the current thread's CurrentUICulture property for all
+ /// resource lookups using this strongly typed resource class.
+ ///
+ [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+ internal static global::System.Globalization.CultureInfo Culture {
+ get {
+ return resourceCulture;
+ }
+ set {
+ resourceCulture = value;
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Could not build a valid Uri for the request. Please double-check the WebClient baseUrl and the WebRequest resource..
+ ///
+ internal static string WebClientBuildUrlFailed {
+ get {
+ return ResourceManager.GetString("WebClientBuildUrlFailed", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The value for MaxRedirects cannot be negative or equal to zero..
+ ///
+ internal static string WebClientMaxRedirectsInvalidMessage {
+ get {
+ return ResourceManager.GetString("WebClientMaxRedirectsInvalidMessage", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The provided WebClient cannot be null..
+ ///
+ internal static string WebClientNullMessage {
+ get {
+ return ResourceManager.GetString("WebClientNullMessage", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The provided request cannot be null..
+ ///
+ internal static string WebClientRequestNullMessage {
+ get {
+ return ResourceManager.GetString("WebClientRequestNullMessage", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The value for Timeout cannot be negative or equal to zero..
+ ///
+ internal static string WebClientTimeoutInvalidMessage {
+ get {
+ return ResourceManager.GetString("WebClientTimeoutInvalidMessage", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The token cannot be null..
+ ///
+ internal static string WebClientTokenNullMessage {
+ get {
+ return ResourceManager.GetString("WebClientTokenNullMessage", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The base URL for the client cannot be null..
+ ///
+ internal static string WebClientUrlNullMessage {
+ get {
+ return ResourceManager.GetString("WebClientUrlNullMessage", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The UserAgent provided cannot be null..
+ ///
+ internal static string WebClientUserAgentNullMessage {
+ get {
+ return ResourceManager.GetString("WebClientUserAgentNullMessage", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The file provided could not be read..
+ ///
+ internal static string WebIOFileNotRead {
+ get {
+ return ResourceManager.GetString("WebIOFileNotRead", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The supplied JSON token is not valid..
+ ///
+ internal static string WebJsonTokenInvalidMessage {
+ get {
+ return ResourceManager.GetString("WebJsonTokenInvalidMessage", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The resource/endpoint provided cannot be null..
+ ///
+ internal static string WebRequestEndpointNullMessage {
+ get {
+ return ResourceManager.GetString("WebRequestEndpointNullMessage", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The provided WebRequest cannot be null..
+ ///
+ internal static string WebRequestNullMessage {
+ get {
+ return ResourceManager.GetString("WebRequestNullMessage", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The parameter provided cannot be null..
+ ///
+ internal static string WebRequestParameterNullMessage {
+ get {
+ return ResourceManager.GetString("WebRequestParameterNullMessage", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to .
+ ///
+ internal static string WebRequestPortDataResultToolTip {
+ get {
+ return ResourceManager.GetString("WebRequestPortDataResultToolTip", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to .
+ ///
+ internal static string WebRequestPortDataUrlToolTip {
+ get {
+ return ResourceManager.GetString("WebRequestPortDataUrlToolTip", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The web request timed out and did not complete. Data may or may not have reached the remote server..
+ ///
+ internal static string WebRequestTimedOutMessage {
+ get {
+ return ResourceManager.GetString("WebRequestTimedOutMessage", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The web request was aborted before it could be completed. Data may or may not have reached the remote server..
+ ///
+ internal static string WebResponseAbortedMessage {
+ get {
+ return ResourceManager.GetString("WebResponseAbortedMessage", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to A network transport error occured. Possible causes include network is down, failed DNS lookup, etc. This also means the request did not reach the intended recipient..
+ ///
+ internal static string WebResponseNetworkErrorMessage {
+ get {
+ return ResourceManager.GetString("WebResponseNetworkErrorMessage", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The web request did not return a valid response status..
+ ///
+ internal static string WebResponseNoneMessage {
+ get {
+ return ResourceManager.GetString("WebResponseNoneMessage", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The URL provided is not a valid URL..
+ ///
+ internal static string WebUrlInvalidMessage {
+ get {
+ return ResourceManager.GetString("WebUrlInvalidMessage", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The URL cannot be null..
+ ///
+ internal static string WebUrlNullMessage {
+ get {
+ return ResourceManager.GetString("WebUrlNullMessage", resourceCulture);
+ }
+ }
+ }
+}
diff --git a/src/DynaWeb/Properties/Resources.resx b/src/DynaWeb/Properties/Resources.resx
new file mode 100644
index 0000000..ebb5d76
--- /dev/null
+++ b/src/DynaWeb/Properties/Resources.resx
@@ -0,0 +1,183 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ Could not build a valid Uri for the request. Please double-check the WebClient baseUrl and the WebRequest resource.
+
+
+ The value for MaxRedirects cannot be negative or equal to zero.
+
+
+ The provided WebClient cannot be null.
+
+
+ The provided request cannot be null.
+
+
+ The value for Timeout cannot be negative or equal to zero.
+
+
+ The token cannot be null.
+
+
+ The base URL for the client cannot be null.
+
+
+ The UserAgent provided cannot be null.
+
+
+ The file provided could not be read.
+
+
+ The supplied JSON token is not valid.
+
+
+ The resource/endpoint provided cannot be null.
+
+
+ The provided WebRequest cannot be null.
+
+
+ The parameter provided cannot be null.
+
+
+
+
+
+
+
+
+ The web request timed out and did not complete. Data may or may not have reached the remote server.
+
+
+ The web request was aborted before it could be completed. Data may or may not have reached the remote server.
+
+
+ A network transport error occured. Possible causes include network is down, failed DNS lookup, etc. This also means the request did not reach the intended recipient.
+
+
+ The web request did not return a valid response status.
+
+
+ The URL provided is not a valid URL.
+
+
+ The URL cannot be null.
+
+
\ No newline at end of file
diff --git a/src/DynaWeb/app.config b/src/DynaWeb/app.config
new file mode 100644
index 0000000..4fc378d
--- /dev/null
+++ b/src/DynaWeb/app.config
@@ -0,0 +1,11 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/DynaWeb/packages.config b/src/DynaWeb/packages.config
new file mode 100644
index 0000000..eaebdf9
--- /dev/null
+++ b/src/DynaWeb/packages.config
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/DynaWeb.Core.Tests/Class1.cs b/test/DynaWeb.Core.Tests/Class1.cs
new file mode 100644
index 0000000..4dd88a6
--- /dev/null
+++ b/test/DynaWeb.Core.Tests/Class1.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace DynaWeb.Core.Tests
+{
+ public class Class1
+ {
+ }
+}
diff --git a/test/DynaWeb.Core.Tests/DynaWeb.Core.Tests.csproj b/test/DynaWeb.Core.Tests/DynaWeb.Core.Tests.csproj
new file mode 100644
index 0000000..0bf7a22
--- /dev/null
+++ b/test/DynaWeb.Core.Tests/DynaWeb.Core.Tests.csproj
@@ -0,0 +1,56 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {50A649C6-FB32-4C6D-A7B6-6EB99DE8547D}
+ Library
+ Properties
+ DynWWW.Core.Tests
+ DynWWW.Core.Tests
+ v4.5.2
+ 512
+
+
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+ ..\..\src\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll
+
+
+ ..\..\src\packages\RestSharp.105.2.3\lib\net452\RestSharp.dll
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/test/DynaWeb.Core.Tests/Properties/AssemblyInfo.cs b/test/DynaWeb.Core.Tests/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..1591b51
--- /dev/null
+++ b/test/DynaWeb.Core.Tests/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+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: AssemblyTitle("DynaWeb.Core.Tests")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("DynaWeb.Core.Tests")]
+[assembly: AssemblyCopyright("Copyright © 2017")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// 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("50a649c6-fb32-4c6d-a7b6-6eb99de8547d")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/test/DynaWeb.Core.Tests/packages.config b/test/DynaWeb.Core.Tests/packages.config
new file mode 100644
index 0000000..d186dc1
--- /dev/null
+++ b/test/DynaWeb.Core.Tests/packages.config
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/test/README.md b/test/README.md
new file mode 100644
index 0000000..3a1303d
--- /dev/null
+++ b/test/README.md
@@ -0,0 +1 @@
+This folder houses all the testing (unit, integration, etc) code for the DynWWW package.