├── .gitignore ├── Adoxio.Dynamics.Connect.nuspec ├── Adoxio.Dynamics.Connect.sln ├── LICENSE ├── README.md ├── samples ├── Adoxio.Connect.ConsoleApp │ ├── Adoxio.Connect.ConsoleApp.csproj │ ├── App.config │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── packages.config ├── Adoxio.Connect.Samples.sln ├── Adoxio.Connect.WebApp │ ├── Adoxio.Connect.WebApp.csproj │ ├── App_Start │ │ ├── BundleConfig.cs │ │ ├── FilterConfig.cs │ │ ├── RouteConfig.cs │ │ └── WebApiConfig.cs │ ├── ApplicationInsights.config │ ├── Content │ │ ├── Site.css │ │ ├── bootstrap.css │ │ └── bootstrap.min.css │ ├── Controllers │ │ ├── CrmSdkApiController.cs │ │ ├── CrmSdkController.cs │ │ └── HomeController.cs │ ├── Global.asax │ ├── Global.asax.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Scripts │ │ ├── bootstrap.js │ │ ├── bootstrap.min.js │ │ ├── jquery-1.10.2.intellisense.js │ │ ├── jquery-1.10.2.js │ │ ├── jquery-1.10.2.min.js │ │ ├── jquery-1.10.2.min.map │ │ ├── jquery.validate-vsdoc.js │ │ ├── jquery.validate.js │ │ ├── jquery.validate.min.js │ │ ├── jquery.validate.unobtrusive.js │ │ ├── jquery.validate.unobtrusive.min.js │ │ ├── modernizr-2.6.2.js │ │ ├── respond.js │ │ └── respond.min.js │ ├── Startup.cs │ ├── Views │ │ ├── CrmSdk │ │ │ └── Index.cshtml │ │ ├── Home │ │ │ ├── About.cshtml │ │ │ ├── Contact.cshtml │ │ │ └── Index.cshtml │ │ ├── Shared │ │ │ ├── Error.cshtml │ │ │ └── _Layout.cshtml │ │ ├── Web.config │ │ └── _ViewStart.cshtml │ ├── Web.Debug.config │ ├── Web.Release.config │ ├── Web.config │ ├── favicon.ico │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ └── glyphicons-halflings-regular.woff │ └── packages.config └── Adoxio.Connect.WebCore │ ├── .bowerrc │ ├── Adoxio.Connect.WebCore.csproj │ ├── Controllers │ ├── CrmSdkController.cs │ └── HomeController.cs │ ├── Extensions │ └── CrmContextCore.cs │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── Startup.cs │ ├── Views │ ├── CrmSdk │ │ ├── Index.cshtml │ │ ├── MultipleCalls.cshtml │ │ └── WhoAmI.cshtml │ ├── Home │ │ ├── About.cshtml │ │ ├── Contact.cshtml │ │ └── Index.cshtml │ ├── Shared │ │ ├── Error.cshtml │ │ ├── _Layout.cshtml │ │ └── _ValidationScriptsPartial.cshtml │ ├── _ViewImports.cshtml │ └── _ViewStart.cshtml │ ├── app.config │ ├── appsettings.Development.json │ ├── appsettings.json │ ├── bower.json │ ├── bundleconfig.json │ └── wwwroot │ ├── css │ ├── site.css │ └── site.min.css │ ├── favicon.ico │ ├── images │ ├── banner1.svg │ ├── banner2.svg │ ├── banner3.svg │ └── banner4.svg │ ├── js │ ├── site.js │ └── site.min.js │ └── lib │ ├── bootstrap │ ├── .bower.json │ ├── LICENSE │ └── dist │ │ ├── css │ │ ├── bootstrap-theme.css │ │ ├── bootstrap-theme.css.map │ │ ├── bootstrap-theme.min.css │ │ ├── bootstrap-theme.min.css.map │ │ ├── bootstrap.css │ │ ├── bootstrap.css.map │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ │ └── js │ │ ├── bootstrap.js │ │ ├── bootstrap.min.js │ │ └── npm.js │ ├── jquery-validation-unobtrusive │ ├── .bower.json │ ├── jquery.validate.unobtrusive.js │ └── jquery.validate.unobtrusive.min.js │ ├── jquery-validation │ ├── .bower.json │ ├── LICENSE.md │ └── dist │ │ ├── additional-methods.js │ │ ├── additional-methods.min.js │ │ ├── jquery.validate.js │ │ └── jquery.validate.min.js │ └── jquery │ ├── .bower.json │ ├── LICENSE.txt │ └── dist │ ├── jquery.js │ ├── jquery.min.js │ └── jquery.min.map └── src ├── Adoxio.Dynamics.Connect ├── Adoxio.Dynamics.Connect.csproj ├── CrmContext.cs ├── CrmContextExtensions.cs ├── Properties │ └── AssemblyInfo.cs ├── S2SAppSettings.cs ├── SettingManager.cs └── packages.config └── Adoxio.Dynamics.ConnectTests ├── Adoxio.Dynamics.ConnectTests.csproj ├── CrmContextTests.cs ├── Properties └── AssemblyInfo.cs ├── S2SAppSettingsTests.cs ├── S2SProp.cs └── packages.config /.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 | [Xx]64/ 19 | [Xx]86/ 20 | [Bb]uild/ 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 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | *.vspx 89 | *.sap 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | nCrunchTemp_* 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | 143 | # TODO: Un-comment the next line if you do not want to checkin 144 | # your web deploy settings because they may include unencrypted 145 | # passwords 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | # NuGet v3's project.json files produces more ignoreable files 158 | *.nuget.props 159 | *.nuget.targets 160 | 161 | # Microsoft Azure Build Output 162 | csx/ 163 | *.build.csdef 164 | 165 | # Microsoft Azure Emulator 166 | ecf/ 167 | rcf/ 168 | 169 | # Windows Store app package directory 170 | AppPackages/ 171 | BundleArtifacts/ 172 | 173 | # Visual Studio cache files 174 | # files ending in .cache can be ignored 175 | *.[Cc]ache 176 | # but keep track of directories ending in .cache 177 | !*.[Cc]ache/ 178 | 179 | # Others 180 | ClientBin/ 181 | [Ss]tyle[Cc]op.* 182 | ~$* 183 | *~ 184 | *.dbmdl 185 | *.dbproj.schemaview 186 | *.pfx 187 | *.publishsettings 188 | node_modules/ 189 | orleans.codegen.cs 190 | 191 | # RIA/Silverlight projects 192 | Generated_Code/ 193 | 194 | # Backup & report files from converting an old project file 195 | # to a newer Visual Studio version. Backup files are not needed, 196 | # because we have git ;-) 197 | _UpgradeReport_Files/ 198 | Backup*/ 199 | UpgradeLog*.XML 200 | UpgradeLog*.htm 201 | 202 | # SQL Server files 203 | *.mdf 204 | *.ldf 205 | 206 | # Business Intelligence projects 207 | *.rdl.data 208 | *.bim.layout 209 | *.bim_*.settings 210 | 211 | # Microsoft Fakes 212 | FakesAssemblies/ 213 | 214 | # GhostDoc plugin setting file 215 | *.GhostDoc.xml 216 | 217 | # Node.js Tools for Visual Studio 218 | .ntvs_analysis.dat 219 | 220 | # Visual Studio 6 build log 221 | *.plg 222 | 223 | # Visual Studio 6 workspace options file 224 | *.opt 225 | 226 | # Visual Studio LightSwitch build output 227 | **/*.HTMLClient/GeneratedArtifacts 228 | **/*.DesktopClient/GeneratedArtifacts 229 | **/*.DesktopClient/ModelManifest.xml 230 | **/*.Server/GeneratedArtifacts 231 | **/*.Server/ModelManifest.xml 232 | _Pvt_Extensions 233 | 234 | # LightSwitch generated files 235 | GeneratedArtifacts/ 236 | ModelManifest.xml 237 | 238 | # Paket dependency manager 239 | .paket/paket.exe 240 | 241 | # FAKE - F# Make 242 | .fake/ 243 | 244 | # Custom 245 | /temp -------------------------------------------------------------------------------- /Adoxio.Dynamics.Connect.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Adoxio.Dynamics.Connect 5 | 0.4.1 6 | Adoxio.Dynamics.Connect 7 | Adoxio Business Solutions 8 | Adoxio Business Solutions 9 | https://github.com/Adoxio/Adoxio.Dynamics.Connect/blob/master/LICENSE 10 | https://github.com/Adoxio/Adoxio.Dynamics.Connect 11 | https://www.adoxio.com/adoxio-icon.png 12 | true 13 | 14 | Implements OrganizationWebProxyClient with Dynamics 365 Server-to-Server authentication. 15 | 16 | 17 | 0.3.3 - Initial public release of Adoxio Connect Framework for Dynamics 365. 18 | 0.4.0 - Add Unit Test project with constructor and S2SAppSetting tests, add and update CrmContext constructors to standard pattern, add assert of S2SAppSettings, add reset token cache method to allow manual clearing of ADAL token cache 19 | 0.4.1 - Fix parameter order on string create method of CrmContext, resolve public key signing issue 20 | 21 | Copyright 2017 22 | dynamics365 crm 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Adoxio.Dynamics.Connect.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26228.9 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Adoxio.Dynamics.Connect", "src\Adoxio.Dynamics.Connect\Adoxio.Dynamics.Connect.csproj", "{EDB4BCD1-BFD0-434F-AD88-D8D5268ECFDF}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Adoxio.Dynamics.ConnectTests", "src\Adoxio.Dynamics.ConnectTests\Adoxio.Dynamics.ConnectTests.csproj", "{E86DCCD3-98C2-441F-AF78-20BE7767CCF3}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {EDB4BCD1-BFD0-434F-AD88-D8D5268ECFDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {EDB4BCD1-BFD0-434F-AD88-D8D5268ECFDF}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {EDB4BCD1-BFD0-434F-AD88-D8D5268ECFDF}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {EDB4BCD1-BFD0-434F-AD88-D8D5268ECFDF}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {E86DCCD3-98C2-441F-AF78-20BE7767CCF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {E86DCCD3-98C2-441F-AF78-20BE7767CCF3}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {E86DCCD3-98C2-441F-AF78-20BE7767CCF3}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {E86DCCD3-98C2-441F-AF78-20BE7767CCF3}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | EndGlobal 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Adoxio Connect Framework for Dynamics 365 2 | 3 | Implements OrganizationWebProxyClient with Dynamics 365 Server-to-Server authentication. 4 | 5 | * includes a setting manager for saving and loading application settings from a settings.json 6 | * utlizes Active Directory Authentication Library (ADAL) to retrieve and store tokens 7 | * implements OrganizationService and OrganizationServiceContext for easy Dynamics SDK functions 8 | 9 | Application Settings: 10 | 11 | ``` 12 | dyn:SdkClientVersion - define your SDK version, if not provided defaults to 8.2 13 | dyn:ClientId - Azure AD application ID or client ID 14 | dyn:ClientSecret - Azure AD application secret or client secret 15 | dyn:Resource - Dynamics 365 instance URI 16 | dyn:TenantId - Azure AD tenant ID 17 | ``` 18 | 19 | Supports .NET Framework 4.6.1, additional framework support in later releases 20 | 21 | Licensed under GNU LGPLv3 22 | 23 | ### Installation 24 | 25 | To install use NuGet Package Manager and search for Adoxio.Dynamics.Connect or package manager console and run the following command: 26 | 27 | ``` 28 | Install-Package Adoxio.Dynamics.Connect 29 | ``` 30 | 31 | NuGet: https://www.nuget.org/packages/Adoxio.Dynamics.Connect 32 | 33 | ### Samples included: 34 | 35 | * Console Application 36 | * ASP.NET Web App with MVC and WebAPI 37 | 38 | #### Release Notes: 39 | 40 | 0.3.3 - March 14, 2017 41 | * Initial public release of Adoxio Connect Framework for Dynamics 365. 42 | 43 | 0.4.0 - March 26, 2017 44 | * Add Unit Test project with constructor and S2SAppSetting tests 45 | * Add and update CrmContext constructors to standard pattern 46 | * Add assert of S2SAppSettings 47 | * Add reset token cache method to allow manual clearing of ADAL token cache 48 | 49 | 0.4.1 - March 26, 2017 50 | * Fix parameter order on string create method of CrmContext 51 | * Resolve public key issue on signing -------------------------------------------------------------------------------- /samples/Adoxio.Connect.ConsoleApp/Adoxio.Connect.ConsoleApp.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {785526D0-AC10-40BB-A001-57718363A145} 8 | Exe 9 | Adoxio.Connect.ConsoleApp 10 | Adoxio.Connect.ConsoleApp 11 | v4.6.1 12 | 512 13 | true 14 | 15 | 16 | AnyCPU 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | AnyCPU 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | ..\packages\Adoxio.Dynamics.Connect.0.4.1\lib\net461\Adoxio.Dynamics.Connect.dll 37 | 38 | 39 | packages\Microsoft.CrmSdk.CoreAssemblies.8.2.0.2\lib\net452\Microsoft.Crm.Sdk.Proxy.dll 40 | 41 | 42 | packages\Microsoft.IdentityModel.6.1.7600.16394\lib\net35\Microsoft.IdentityModel.dll 43 | True 44 | 45 | 46 | packages\Microsoft.IdentityModel.Clients.ActiveDirectory.2.22.302111727\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll 47 | 48 | 49 | packages\Microsoft.IdentityModel.Clients.ActiveDirectory.2.22.302111727\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll 50 | 51 | 52 | packages\Microsoft.CrmSdk.CoreAssemblies.8.2.0.2\lib\net452\Microsoft.Xrm.Sdk.dll 53 | 54 | 55 | packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.ConsoleApp/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.ConsoleApp/Program.cs: -------------------------------------------------------------------------------- 1 | using Adoxio.Dynamics.Connect; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Adoxio.Connect.ConsoleApp 9 | { 10 | class Program 11 | { 12 | static void Main(string[] args) 13 | { 14 | using (var context = new CrmContext()) 15 | { 16 | var contacts = context.ServiceContext.CreateQuery("contact").ToList(); 17 | 18 | foreach (var contact in contacts) 19 | { 20 | Console.WriteLine(contact.GetAttributeValue("fullname")); 21 | } 22 | } 23 | 24 | Console.ReadKey(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.ConsoleApp/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Adoxio.Connect.ConsoleApp")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Adoxio.Connect.ConsoleApp")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("785526d0-ac10-40bb-a001-57718363a145")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.ConsoleApp/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.Samples.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26430.13 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Adoxio.Connect.ConsoleApp", "Adoxio.Connect.ConsoleApp\Adoxio.Connect.ConsoleApp.csproj", "{785526D0-AC10-40BB-A001-57718363A145}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Adoxio.Connect.WebApp", "Adoxio.Connect.WebApp\Adoxio.Connect.WebApp.csproj", "{09C6B25D-373E-44C9-B87B-056C24C0A1CC}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Adoxio.Connect.WebCore", "Adoxio.Connect.WebCore\Adoxio.Connect.WebCore.csproj", "{F8C06CE3-C58A-4F8B-AEFB-24B48E332362}" 11 | EndProject 12 | Global 13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 14 | Debug|Any CPU = Debug|Any CPU 15 | Release|Any CPU = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 18 | {785526D0-AC10-40BB-A001-57718363A145}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 19 | {785526D0-AC10-40BB-A001-57718363A145}.Debug|Any CPU.Build.0 = Debug|Any CPU 20 | {785526D0-AC10-40BB-A001-57718363A145}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {785526D0-AC10-40BB-A001-57718363A145}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {09C6B25D-373E-44C9-B87B-056C24C0A1CC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 23 | {09C6B25D-373E-44C9-B87B-056C24C0A1CC}.Debug|Any CPU.Build.0 = Debug|Any CPU 24 | {09C6B25D-373E-44C9-B87B-056C24C0A1CC}.Release|Any CPU.ActiveCfg = Release|Any CPU 25 | {09C6B25D-373E-44C9-B87B-056C24C0A1CC}.Release|Any CPU.Build.0 = Release|Any CPU 26 | {F8C06CE3-C58A-4F8B-AEFB-24B48E332362}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 27 | {F8C06CE3-C58A-4F8B-AEFB-24B48E332362}.Debug|Any CPU.Build.0 = Debug|Any CPU 28 | {F8C06CE3-C58A-4F8B-AEFB-24B48E332362}.Release|Any CPU.ActiveCfg = Release|Any CPU 29 | {F8C06CE3-C58A-4F8B-AEFB-24B48E332362}.Release|Any CPU.Build.0 = Release|Any CPU 30 | EndGlobalSection 31 | GlobalSection(SolutionProperties) = preSolution 32 | HideSolutionNode = FALSE 33 | EndGlobalSection 34 | EndGlobal 35 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/App_Start/BundleConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Optimization; 3 | 4 | namespace Adoxio.Connect.WebApp 5 | { 6 | public class BundleConfig 7 | { 8 | // For more information on bundling, visit https://go.microsoft.com/fwlink/?LinkId=301862 9 | public static void RegisterBundles(BundleCollection bundles) 10 | { 11 | bundles.Add(new ScriptBundle("~/bundles/jquery").Include( 12 | "~/Scripts/jquery-{version}.js")); 13 | 14 | bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include( 15 | "~/Scripts/jquery.validate*")); 16 | 17 | // Use the development version of Modernizr to develop with and learn from. Then, when you're 18 | // ready for production, use the build tool at https://modernizr.com to pick only the tests you need. 19 | bundles.Add(new ScriptBundle("~/bundles/modernizr").Include( 20 | "~/Scripts/modernizr-*")); 21 | 22 | bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include( 23 | "~/Scripts/bootstrap.js", 24 | "~/Scripts/respond.js")); 25 | 26 | bundles.Add(new StyleBundle("~/Content/css").Include( 27 | "~/Content/bootstrap.css", 28 | "~/Content/site.css")); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/App_Start/FilterConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Mvc; 3 | 4 | namespace Adoxio.Connect.WebApp 5 | { 6 | public class FilterConfig 7 | { 8 | public static void RegisterGlobalFilters(GlobalFilterCollection filters) 9 | { 10 | filters.Add(new HandleErrorAttribute()); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/App_Start/RouteConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | using System.Web.Routing; 7 | 8 | namespace Adoxio.Connect.WebApp 9 | { 10 | public class RouteConfig 11 | { 12 | public static void RegisterRoutes(RouteCollection routes) 13 | { 14 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 15 | 16 | routes.MapRoute( 17 | name: "Default", 18 | url: "{controller}/{action}/{id}", 19 | defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 20 | ); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/App_Start/WebApiConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web.Http; 5 | 6 | namespace Adoxio.Connect.WebApp 7 | { 8 | public static class WebApiConfig 9 | { 10 | public static void Register(HttpConfiguration config) 11 | { 12 | // Web API configuration and services 13 | 14 | // Web API routes 15 | config.MapHttpAttributeRoutes(); 16 | 17 | config.Routes.MapHttpRoute( 18 | name: "DefaultApi", 19 | routeTemplate: "api/{controller}/{id}", 20 | defaults: new { id = RouteParameter.Optional } 21 | ); 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/ApplicationInsights.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 12 | search|spider|crawl|Bot|Monitor|AlwaysOn 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 54 | System.Web.Handlers.TransferRequestHandler 55 | Microsoft.VisualStudio.Web.PageInspector.Runtime.Tracing.RequestDataHttpHandler 56 | System.Web.StaticFileHandler 57 | System.Web.Handlers.AssemblyResourceLoader 58 | System.Web.Optimization.BundleHandler 59 | System.Web.Script.Services.ScriptHandlerFactory 60 | System.Web.Handlers.TraceHandler 61 | System.Web.Services.Discovery.DiscoveryRequestHandler 62 | System.Web.HttpDebugHandler 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 5 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/Content/Site.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | padding-bottom: 20px; 4 | } 5 | 6 | /* Set padding to keep content from hitting the edges */ 7 | .body-content { 8 | padding-left: 15px; 9 | padding-right: 15px; 10 | } 11 | 12 | /* Override the default bootstrap behavior where horizontal description lists 13 | will truncate terms that are too long to fit in the left column 14 | */ 15 | .dl-horizontal dt { 16 | white-space: normal; 17 | } 18 | 19 | /* Set width on the form input elements since they're 100% wide by default */ 20 | input, 21 | select, 22 | textarea { 23 | max-width: 280px; 24 | } 25 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/Controllers/CrmSdkApiController.cs: -------------------------------------------------------------------------------- 1 | using Adoxio.Dynamics.Connect; 2 | using Microsoft.AspNet.Identity.Owin; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Net; 7 | using System.Net.Http; 8 | using System.Web; 9 | using System.Web.Http; 10 | 11 | namespace Adoxio.Connect.WebApp.Controllers 12 | { 13 | public class CrmSdkApiController : ApiController 14 | { 15 | [HttpGet] 16 | public HttpResponseMessage Contacts() 17 | { 18 | var context = HttpContext.Current.GetOwinContext().Get(); 19 | 20 | var contacts = context.ServiceContext.CreateQuery("contact").Select(a => a.GetAttributeValue("fullname")).ToList(); 21 | 22 | return Request.CreateResponse(HttpStatusCode.OK, contacts); 23 | 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/Controllers/CrmSdkController.cs: -------------------------------------------------------------------------------- 1 | using Adoxio.Dynamics.Connect; 2 | using Microsoft.AspNet.Identity.Owin; 3 | using Microsoft.Crm.Sdk.Messages; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Web; 8 | using System.Web.Mvc; 9 | 10 | namespace Adoxio.Connect.WebApp.Controllers 11 | { 12 | public class CrmSdkController : Controller 13 | { 14 | // GET: CrmSdk 15 | public ActionResult Index() 16 | { 17 | var context = Request.GetOwinContext().Get(); 18 | 19 | WhoAmIResponse response = null; 20 | 21 | if (context != null) 22 | { 23 | response = (WhoAmIResponse) context.WebProxyClient.Execute(new WhoAmIRequest()); 24 | } 25 | 26 | return View((object)string.Join(",", response.Results.ToList())); 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | 7 | namespace Adoxio.Connect.WebApp.Controllers 8 | { 9 | public class HomeController : Controller 10 | { 11 | public ActionResult Index() 12 | { 13 | return View(); 14 | } 15 | 16 | public ActionResult About() 17 | { 18 | ViewBag.Message = "Your application description page."; 19 | 20 | return View(); 21 | } 22 | 23 | public ActionResult Contact() 24 | { 25 | ViewBag.Message = "Your contact page."; 26 | 27 | return View(); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="Adoxio.Connect.WebApp.MvcApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/Global.asax.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Http; 6 | using System.Web.Mvc; 7 | using System.Web.Optimization; 8 | using System.Web.Routing; 9 | 10 | namespace Adoxio.Connect.WebApp 11 | { 12 | public class MvcApplication : System.Web.HttpApplication 13 | { 14 | protected void Application_Start() 15 | { 16 | AreaRegistration.RegisterAllAreas(); 17 | GlobalConfiguration.Configure(WebApiConfig.Register); 18 | FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 19 | RouteConfig.RegisterRoutes(RouteTable.Routes); 20 | BundleConfig.RegisterBundles(BundleTable.Bundles); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Adoxio.Connect.WebApp")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Adoxio.Connect.WebApp")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("8a01c033-8338-4db9-88e0-86e7f070f350")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/Scripts/jquery.validate.unobtrusive.min.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | /* 16 | ** Unobtrusive validation support library for jQuery and jQuery Validate 17 | ** Copyright (C) Microsoft Corporation. All rights reserved. 18 | */ 19 | (function(a){var d=a.validator,b,e="unobtrusiveValidation";function c(a,b,c){a.rules[b]=c;if(a.message)a.messages[b]=a.message}function j(a){return a.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}function f(a){return a.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function h(a){return a.substr(0,a.lastIndexOf(".")+1)}function g(a,b){if(a.indexOf("*.")===0)a=a.replace("*.",b);return a}function m(c,e){var b=a(this).find("[data-valmsg-for='"+f(e[0].name)+"']"),d=b.attr("data-valmsg-replace"),g=d?a.parseJSON(d)!==false:null;b.removeClass("field-validation-valid").addClass("field-validation-error");c.data("unobtrusiveContainer",b);if(g){b.empty();c.removeClass("input-validation-error").appendTo(b)}else c.hide()}function l(e,d){var c=a(this).find("[data-valmsg-summary=true]"),b=c.find("ul");if(b&&b.length&&d.errorList.length){b.empty();c.addClass("validation-summary-errors").removeClass("validation-summary-valid");a.each(d.errorList,function(){a("
  • ").html(this.message).appendTo(b)})}}function k(d){var b=d.data("unobtrusiveContainer"),c=b.attr("data-valmsg-replace"),e=c?a.parseJSON(c):null;if(b){b.addClass("field-validation-valid").removeClass("field-validation-error");d.removeData("unobtrusiveContainer");e&&b.empty()}}function n(){var b=a(this),c="__jquery_unobtrusive_validation_form_reset";if(b.data(c))return;b.data(c,true);try{b.data("validator").resetForm()}finally{b.removeData(c)}b.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors");b.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}function i(b){var c=a(b),f=c.data(e),i=a.proxy(n,b),g=d.unobtrusive.options||{},h=function(e,d){var c=g[e];c&&a.isFunction(c)&&c.apply(b,d)};if(!f){f={options:{errorClass:g.errorClass||"input-validation-error",errorElement:g.errorElement||"span",errorPlacement:function(){m.apply(b,arguments);h("errorPlacement",arguments)},invalidHandler:function(){l.apply(b,arguments);h("invalidHandler",arguments)},messages:{},rules:{},success:function(){k.apply(b,arguments);h("success",arguments)}},attachValidation:function(){c.off("reset."+e,i).on("reset."+e,i).validate(this.options)},validate:function(){c.validate();return c.valid()}};c.data(e,f)}return f}d.unobtrusive={adapters:[],parseElement:function(b,h){var d=a(b),f=d.parents("form")[0],c,e,g;if(!f)return;c=i(f);c.options.rules[b.name]=e={};c.options.messages[b.name]=g={};a.each(this.adapters,function(){var c="data-val-"+this.name,i=d.attr(c),h={};if(i!==undefined){c+="-";a.each(this.params,function(){h[this]=d.attr(c+this)});this.adapt({element:b,form:f,message:i,params:h,rules:e,messages:g})}});a.extend(e,{__dummy__:true});!h&&c.attachValidation()},parse:function(c){var b=a(c),e=b.parents().addBack().filter("form").add(b.find("form")).has("[data-val=true]");b.find("[data-val=true]").each(function(){d.unobtrusive.parseElement(this,true)});e.each(function(){var a=i(this);a&&a.attachValidation()})}};b=d.unobtrusive.adapters;b.add=function(c,a,b){if(!b){b=a;a=[]}this.push({name:c,params:a,adapt:b});return this};b.addBool=function(a,b){return this.add(a,function(d){c(d,b||a,true)})};b.addMinMax=function(e,g,f,a,d,b){return this.add(e,[d||"min",b||"max"],function(b){var e=b.params.min,d=b.params.max;if(e&&d)c(b,a,[e,d]);else if(e)c(b,g,e);else d&&c(b,f,d)})};b.addSingleVal=function(a,b,d){return this.add(a,[b||"val"],function(e){c(e,d||a,e.params[b])})};d.addMethod("__dummy__",function(){return true});d.addMethod("regex",function(b,c,d){var a;if(this.optional(c))return true;a=(new RegExp(d)).exec(b);return a&&a.index===0&&a[0].length===b.length});d.addMethod("nonalphamin",function(c,d,b){var a;if(b){a=c.match(/\W/g);a=a&&a.length>=b}return a});if(d.methods.extension){b.addSingleVal("accept","mimtype");b.addSingleVal("extension","extension")}else b.addSingleVal("extension","extension","accept");b.addSingleVal("regex","pattern");b.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url");b.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range");b.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength");b.add("equalto",["other"],function(b){var i=h(b.element.name),j=b.params.other,d=g(j,i),e=a(b.form).find(":input").filter("[name='"+f(d)+"']")[0];c(b,"equalTo",e)});b.add("required",function(a){(a.element.tagName.toUpperCase()!=="INPUT"||a.element.type.toUpperCase()!=="CHECKBOX")&&c(a,"required",true)});b.add("remote",["url","type","additionalfields"],function(b){var d={url:b.params.url,type:b.params.type||"GET",data:{}},e=h(b.element.name);a.each(j(b.params.additionalfields||b.element.name),function(i,h){var c=g(h,e);d.data[c]=function(){var d=a(b.form).find(":input").filter("[name='"+f(c)+"']");return d.is(":checkbox")?d.filter(":checked").val()||d.filter(":hidden").val()||"":d.is(":radio")?d.filter(":checked").val()||"":d.val()}});c(b,"remote",d)});b.add("password",["min","nonalphamin","regex"],function(a){a.params.min&&c(a,"minlength",a.params.min);a.params.nonalphamin&&c(a,"nonalphamin",a.params.nonalphamin);a.params.regex&&c(a,"regex",a.params.regex)});a(function(){d.unobtrusive.parse(document)})})(jQuery); -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/Scripts/respond.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | /*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */ 16 | /*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */ 17 | window.matchMedia = window.matchMedia || (function(doc, undefined){ 18 | 19 | var bool, 20 | docElem = doc.documentElement, 21 | refNode = docElem.firstElementChild || docElem.firstChild, 22 | // fakeBody required for 23 | fakeBody = doc.createElement('body'), 24 | div = doc.createElement('div'); 25 | 26 | div.id = 'mq-test-1'; 27 | div.style.cssText = "position:absolute;top:-100em"; 28 | fakeBody.style.background = "none"; 29 | fakeBody.appendChild(div); 30 | 31 | return function(q){ 32 | 33 | div.innerHTML = '­'; 34 | 35 | docElem.insertBefore(fakeBody, refNode); 36 | bool = div.offsetWidth == 42; 37 | docElem.removeChild(fakeBody); 38 | 39 | return { matches: bool, media: q }; 40 | }; 41 | 42 | })(document); 43 | 44 | 45 | 46 | 47 | /*! Respond.js v1.2.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */ 48 | (function( win ){ 49 | //exposed namespace 50 | win.respond = {}; 51 | 52 | //define update even in native-mq-supporting browsers, to avoid errors 53 | respond.update = function(){}; 54 | 55 | //expose media query support flag for external use 56 | respond.mediaQueriesSupported = win.matchMedia && win.matchMedia( "only all" ).matches; 57 | 58 | //if media queries are supported, exit here 59 | if( respond.mediaQueriesSupported ){ return; } 60 | 61 | //define vars 62 | var doc = win.document, 63 | docElem = doc.documentElement, 64 | mediastyles = [], 65 | rules = [], 66 | appendedEls = [], 67 | parsedSheets = {}, 68 | resizeThrottle = 30, 69 | head = doc.getElementsByTagName( "head" )[0] || docElem, 70 | base = doc.getElementsByTagName( "base" )[0], 71 | links = head.getElementsByTagName( "link" ), 72 | requestQueue = [], 73 | 74 | //loop stylesheets, send text content to translate 75 | ripCSS = function(){ 76 | var sheets = links, 77 | sl = sheets.length, 78 | i = 0, 79 | //vars for loop: 80 | sheet, href, media, isCSS; 81 | 82 | for( ; i < sl; i++ ){ 83 | sheet = sheets[ i ], 84 | href = sheet.href, 85 | media = sheet.media, 86 | isCSS = sheet.rel && sheet.rel.toLowerCase() === "stylesheet"; 87 | 88 | //only links plz and prevent re-parsing 89 | if( !!href && isCSS && !parsedSheets[ href ] ){ 90 | // selectivizr exposes css through the rawCssText expando 91 | if (sheet.styleSheet && sheet.styleSheet.rawCssText) { 92 | translate( sheet.styleSheet.rawCssText, href, media ); 93 | parsedSheets[ href ] = true; 94 | } else { 95 | if( (!/^([a-zA-Z:]*\/\/)/.test( href ) && !base) 96 | || href.replace( RegExp.$1, "" ).split( "/" )[0] === win.location.host ){ 97 | requestQueue.push( { 98 | href: href, 99 | media: media 100 | } ); 101 | } 102 | } 103 | } 104 | } 105 | makeRequests(); 106 | }, 107 | 108 | //recurse through request queue, get css text 109 | makeRequests = function(){ 110 | if( requestQueue.length ){ 111 | var thisRequest = requestQueue.shift(); 112 | 113 | ajax( thisRequest.href, function( styles ){ 114 | translate( styles, thisRequest.href, thisRequest.media ); 115 | parsedSheets[ thisRequest.href ] = true; 116 | makeRequests(); 117 | } ); 118 | } 119 | }, 120 | 121 | //find media blocks in css text, convert to style blocks 122 | translate = function( styles, href, media ){ 123 | var qs = styles.match( /@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi ), 124 | ql = qs && qs.length || 0, 125 | //try to get CSS path 126 | href = href.substring( 0, href.lastIndexOf( "/" )), 127 | repUrls = function( css ){ 128 | return css.replace( /(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g, "$1" + href + "$2$3" ); 129 | }, 130 | useMedia = !ql && media, 131 | //vars used in loop 132 | i = 0, 133 | j, fullq, thisq, eachq, eql; 134 | 135 | //if path exists, tack on trailing slash 136 | if( href.length ){ href += "/"; } 137 | 138 | //if no internal queries exist, but media attr does, use that 139 | //note: this currently lacks support for situations where a media attr is specified on a link AND 140 | //its associated stylesheet has internal CSS media queries. 141 | //In those cases, the media attribute will currently be ignored. 142 | if( useMedia ){ 143 | ql = 1; 144 | } 145 | 146 | 147 | for( ; i < ql; i++ ){ 148 | j = 0; 149 | 150 | //media attr 151 | if( useMedia ){ 152 | fullq = media; 153 | rules.push( repUrls( styles ) ); 154 | } 155 | //parse for styles 156 | else{ 157 | fullq = qs[ i ].match( /@media *([^\{]+)\{([\S\s]+?)$/ ) && RegExp.$1; 158 | rules.push( RegExp.$2 && repUrls( RegExp.$2 ) ); 159 | } 160 | 161 | eachq = fullq.split( "," ); 162 | eql = eachq.length; 163 | 164 | for( ; j < eql; j++ ){ 165 | thisq = eachq[ j ]; 166 | mediastyles.push( { 167 | media : thisq.split( "(" )[ 0 ].match( /(only\s+)?([a-zA-Z]+)\s?/ ) && RegExp.$2 || "all", 168 | rules : rules.length - 1, 169 | hasquery: thisq.indexOf("(") > -1, 170 | minw : thisq.match( /\(min\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/ ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" ), 171 | maxw : thisq.match( /\(max\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/ ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" ) 172 | } ); 173 | } 174 | } 175 | 176 | applyMedia(); 177 | }, 178 | 179 | lastCall, 180 | 181 | resizeDefer, 182 | 183 | // returns the value of 1em in pixels 184 | getEmValue = function() { 185 | var ret, 186 | div = doc.createElement('div'), 187 | body = doc.body, 188 | fakeUsed = false; 189 | 190 | div.style.cssText = "position:absolute;font-size:1em;width:1em"; 191 | 192 | if( !body ){ 193 | body = fakeUsed = doc.createElement( "body" ); 194 | body.style.background = "none"; 195 | } 196 | 197 | body.appendChild( div ); 198 | 199 | docElem.insertBefore( body, docElem.firstChild ); 200 | 201 | ret = div.offsetWidth; 202 | 203 | if( fakeUsed ){ 204 | docElem.removeChild( body ); 205 | } 206 | else { 207 | body.removeChild( div ); 208 | } 209 | 210 | //also update eminpx before returning 211 | ret = eminpx = parseFloat(ret); 212 | 213 | return ret; 214 | }, 215 | 216 | //cached container for 1em value, populated the first time it's needed 217 | eminpx, 218 | 219 | //enable/disable styles 220 | applyMedia = function( fromResize ){ 221 | var name = "clientWidth", 222 | docElemProp = docElem[ name ], 223 | currWidth = doc.compatMode === "CSS1Compat" && docElemProp || doc.body[ name ] || docElemProp, 224 | styleBlocks = {}, 225 | lastLink = links[ links.length-1 ], 226 | now = (new Date()).getTime(); 227 | 228 | //throttle resize calls 229 | if( fromResize && lastCall && now - lastCall < resizeThrottle ){ 230 | clearTimeout( resizeDefer ); 231 | resizeDefer = setTimeout( applyMedia, resizeThrottle ); 232 | return; 233 | } 234 | else { 235 | lastCall = now; 236 | } 237 | 238 | for( var i in mediastyles ){ 239 | var thisstyle = mediastyles[ i ], 240 | min = thisstyle.minw, 241 | max = thisstyle.maxw, 242 | minnull = min === null, 243 | maxnull = max === null, 244 | em = "em"; 245 | 246 | if( !!min ){ 247 | min = parseFloat( min ) * ( min.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 ); 248 | } 249 | if( !!max ){ 250 | max = parseFloat( max ) * ( max.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 ); 251 | } 252 | 253 | // if there's no media query at all (the () part), or min or max is not null, and if either is present, they're true 254 | if( !thisstyle.hasquery || ( !minnull || !maxnull ) && ( minnull || currWidth >= min ) && ( maxnull || currWidth <= max ) ){ 255 | if( !styleBlocks[ thisstyle.media ] ){ 256 | styleBlocks[ thisstyle.media ] = []; 257 | } 258 | styleBlocks[ thisstyle.media ].push( rules[ thisstyle.rules ] ); 259 | } 260 | } 261 | 262 | //remove any existing respond style element(s) 263 | for( var i in appendedEls ){ 264 | if( appendedEls[ i ] && appendedEls[ i ].parentNode === head ){ 265 | head.removeChild( appendedEls[ i ] ); 266 | } 267 | } 268 | 269 | //inject active styles, grouped by media type 270 | for( var i in styleBlocks ){ 271 | var ss = doc.createElement( "style" ), 272 | css = styleBlocks[ i ].join( "\n" ); 273 | 274 | ss.type = "text/css"; 275 | ss.media = i; 276 | 277 | //originally, ss was appended to a documentFragment and sheets were appended in bulk. 278 | //this caused crashes in IE in a number of circumstances, such as when the HTML element had a bg image set, so appending beforehand seems best. Thanks to @dvelyk for the initial research on this one! 279 | head.insertBefore( ss, lastLink.nextSibling ); 280 | 281 | if ( ss.styleSheet ){ 282 | ss.styleSheet.cssText = css; 283 | } 284 | else { 285 | ss.appendChild( doc.createTextNode( css ) ); 286 | } 287 | 288 | //push to appendedEls to track for later removal 289 | appendedEls.push( ss ); 290 | } 291 | }, 292 | //tweaked Ajax functions from Quirksmode 293 | ajax = function( url, callback ) { 294 | var req = xmlHttp(); 295 | if (!req){ 296 | return; 297 | } 298 | req.open( "GET", url, true ); 299 | req.onreadystatechange = function () { 300 | if ( req.readyState != 4 || req.status != 200 && req.status != 304 ){ 301 | return; 302 | } 303 | callback( req.responseText ); 304 | } 305 | if ( req.readyState == 4 ){ 306 | return; 307 | } 308 | req.send( null ); 309 | }, 310 | //define ajax obj 311 | xmlHttp = (function() { 312 | var xmlhttpmethod = false; 313 | try { 314 | xmlhttpmethod = new XMLHttpRequest(); 315 | } 316 | catch( e ){ 317 | xmlhttpmethod = new ActiveXObject( "Microsoft.XMLHTTP" ); 318 | } 319 | return function(){ 320 | return xmlhttpmethod; 321 | }; 322 | })(); 323 | 324 | //translate CSS 325 | ripCSS(); 326 | 327 | //expose update for re-running respond later on 328 | respond.update = ripCSS; 329 | 330 | //adjust on resize 331 | function callMedia(){ 332 | applyMedia( true ); 333 | } 334 | if( win.addEventListener ){ 335 | win.addEventListener( "resize", callMedia, false ); 336 | } 337 | else if( win.attachEvent ){ 338 | win.attachEvent( "onresize", callMedia ); 339 | } 340 | })(this); 341 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/Scripts/respond.min.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | /*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */ 16 | /*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */ 17 | window.matchMedia=window.matchMedia||(function(e,f){var c,a=e.documentElement,b=a.firstElementChild||a.firstChild,d=e.createElement("body"),g=e.createElement("div");g.id="mq-test-1";g.style.cssText="position:absolute;top:-100em";d.style.background="none";d.appendChild(g);return function(h){g.innerHTML='­';a.insertBefore(d,b);c=g.offsetWidth==42;a.removeChild(d);return{matches:c,media:h}}})(document); 18 | 19 | /*! Respond.js v1.2.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */ 20 | (function(e){e.respond={};respond.update=function(){};respond.mediaQueriesSupported=e.matchMedia&&e.matchMedia("only all").matches;if(respond.mediaQueriesSupported){return}var w=e.document,s=w.documentElement,i=[],k=[],q=[],o={},h=30,f=w.getElementsByTagName("head")[0]||s,g=w.getElementsByTagName("base")[0],b=f.getElementsByTagName("link"),d=[],a=function(){var D=b,y=D.length,B=0,A,z,C,x;for(;B-1,minw:F.match(/\(min\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:F.match(/\(max\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}}j()},l,r,v=function(){var z,A=w.createElement("div"),x=w.body,y=false;A.style.cssText="position:absolute;font-size:1em;width:1em";if(!x){x=y=w.createElement("body");x.style.background="none"}x.appendChild(A);s.insertBefore(x,s.firstChild);z=A.offsetWidth;if(y){s.removeChild(x)}else{x.removeChild(A)}z=p=parseFloat(z);return z},p,j=function(I){var x="clientWidth",B=s[x],H=w.compatMode==="CSS1Compat"&&B||w.body[x]||B,D={},G=b[b.length-1],z=(new Date()).getTime();if(I&&l&&z-l-1?(p||v()):1)}if(!!J){J=parseFloat(J)*(J.indexOf(y)>-1?(p||v()):1)}if(!K.hasquery||(!A||!L)&&(A||H>=C)&&(L||H<=J)){if(!D[K.media]){D[K.media]=[]}D[K.media].push(k[K.rules])}}for(var E in q){if(q[E]&&q[E].parentNode===f){f.removeChild(q[E])}}for(var E in D){var M=w.createElement("style"),F=D[E].join("\n");M.type="text/css";M.media=E;f.insertBefore(M,G.nextSibling);if(M.styleSheet){M.styleSheet.cssText=F}else{M.appendChild(w.createTextNode(F))}q.push(M)}},n=function(x,z){var y=c();if(!y){return}y.open("GET",x,true);y.onreadystatechange=function(){if(y.readyState!=4||y.status!=200&&y.status!=304){return}z(y.responseText)};if(y.readyState==4){return}y.send(null)},c=(function(){var x=false;try{x=new XMLHttpRequest()}catch(y){x=new ActiveXObject("Microsoft.XMLHTTP")}return function(){return x}})();a();respond.update=a;function t(){j(true)}if(e.addEventListener){e.addEventListener("resize",t,false)}else{if(e.attachEvent){e.attachEvent("onresize",t)}}})(this); -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | using Microsoft.Owin; 4 | using Owin; 5 | using Adoxio.Dynamics.Connect; 6 | 7 | [assembly: OwinStartup(typeof(Adoxio.Connect.WebApp.Startup))] 8 | 9 | namespace Adoxio.Connect.WebApp 10 | { 11 | public class Startup 12 | { 13 | public void Configuration(IAppBuilder app) 14 | { 15 | if (!SettingManager.InitAppSettings()) 16 | { 17 | throw new Exception("no Adoxio Connect settings found"); 18 | } 19 | else 20 | { 21 | app.CreatePerOwinContext(CrmContext.Create); 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/Views/CrmSdk/Index.cshtml: -------------------------------------------------------------------------------- 1 |  2 | @{ 3 | ViewBag.Title = "CRMSDK - Index"; 4 | Layout = "~/Views/Shared/_Layout.cshtml"; 5 | } 6 | 7 |

    CRMSDK - Index

    8 | 9 |

    Result: @Model

    10 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/Views/Home/About.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "About"; 3 | } 4 |

    @ViewBag.Title.

    5 |

    @ViewBag.Message

    6 | 7 |

    Use this area to provide additional information.

    8 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/Views/Home/Contact.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Contact"; 3 | } 4 |

    @ViewBag.Title.

    5 |

    @ViewBag.Message

    6 | 7 |
    8 | One Microsoft Way
    9 | Redmond, WA 98052-6399
    10 | P: 11 | 425.555.0100 12 |
    13 | 14 |
    15 | Support: Support@example.com
    16 | Marketing: Marketing@example.com 17 |
    -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Home Page"; 3 | } 4 | 5 |
    6 |

    ASP.NET

    7 |

    ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS and JavaScript.

    8 |

    Learn more »

    9 |
    10 | 11 |
    12 |
    13 |

    Getting started

    14 |

    15 | ASP.NET MVC gives you a powerful, patterns-based way to build dynamic websites that 16 | enables a clean separation of concerns and gives you full control over markup 17 | for enjoyable, agile development. 18 |

    19 |

    Learn more »

    20 |
    21 |
    22 |

    Get more libraries

    23 |

    NuGet is a free Visual Studio extension that makes it easy to add, remove, and update libraries and tools in Visual Studio projects.

    24 |

    Learn more »

    25 |
    26 |
    27 |

    Web Hosting

    28 |

    You can easily find a web hosting company that offers the right mix of features and price for your applications.

    29 |

    Learn more »

    30 |
    31 |
    -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Error 6 | 7 | 8 |
    9 |

    Error.

    10 |

    An error occurred while processing your request.

    11 |
    12 | 13 | 14 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | @ViewBag.Title - My ASP.NET Application 7 | @Styles.Render("~/Content/css") 8 | @Scripts.Render("~/bundles/modernizr") 9 | 10 | 11 | 31 |
    32 | @RenderBody() 33 |
    34 |
    35 |

    © @DateTime.Now.Year - My ASP.NET Application

    36 |
    37 |
    38 | 39 | @Scripts.Render("~/bundles/jquery") 40 | @Scripts.Render("~/bundles/bootstrap") 41 | @RenderSection("scripts", required: false) 42 | 43 | 44 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/Views/Web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 |
    7 |
    8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "~/Views/Shared/_Layout.cshtml"; 3 | } 4 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/Web.Debug.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/Web.Release.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/Web.config: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adoxio/Adoxio.Dynamics.Connect/82c09bcdc385be618bb1c1a870dec686fc725a92/samples/Adoxio.Connect.WebApp/favicon.ico -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adoxio/Adoxio.Dynamics.Connect/82c09bcdc385be618bb1c1a870dec686fc725a92/samples/Adoxio.Connect.WebApp/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adoxio/Adoxio.Dynamics.Connect/82c09bcdc385be618bb1c1a870dec686fc725a92/samples/Adoxio.Connect.WebApp/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adoxio/Adoxio.Dynamics.Connect/82c09bcdc385be618bb1c1a870dec686fc725a92/samples/Adoxio.Connect.WebApp/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebApp/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "wwwroot/lib" 3 | } 4 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/Adoxio.Connect.WebCore.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net461 5 | win7-x86 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/Controllers/CrmSdkController.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using Microsoft.AspNetCore.Mvc; 4 | using Adoxio.Connect.WebCore.Extensions; 5 | using Microsoft.Xrm.Sdk; 6 | using Microsoft.Crm.Sdk.Messages; 7 | using System.Diagnostics; 8 | 9 | namespace Adoxio.Connect.WebCore.Controllers 10 | { 11 | public class CrmSdkController : Controller 12 | { 13 | private readonly CrmContextCore _crmContext; 14 | 15 | public CrmSdkController(CrmContextCore crmContext) 16 | { 17 | _crmContext = crmContext; 18 | } 19 | 20 | public IActionResult Index() 21 | { 22 | var contacts = _crmContext.ServiceContext.CreateQuery("contact").ToList(); 23 | return View(model: string.Join(",", contacts.Select(a => a.GetAttributeValue("fullname")))); 24 | } 25 | 26 | public IActionResult WhoAmI() 27 | { 28 | WhoAmIResponse response = null; 29 | 30 | if (_crmContext?.WebProxyClient != null) 31 | response = (WhoAmIResponse)_crmContext.WebProxyClient.Execute(new WhoAmIRequest()); 32 | 33 | string responseText = string.Empty; 34 | if (response != null) 35 | responseText = $"{response.UserId}"; 36 | else 37 | responseText = $"WebProxyClient null"; 38 | 39 | return View((object)responseText); 40 | } 41 | 42 | public IActionResult MultipleCalls() 43 | { 44 | Trace.TraceInformation("Start MultipleCalls"); 45 | 46 | WhoAmIResponse response = null; 47 | 48 | if (_crmContext?.WebProxyClient != null) 49 | { 50 | response = (WhoAmIResponse)_crmContext.WebProxyClient.Execute(new WhoAmIRequest()); 51 | Trace.TraceInformation("WhoAmI Executed"); 52 | } 53 | 54 | string responseText = string.Empty; 55 | if (response != null) 56 | responseText = $"{response.UserId} : "; 57 | else 58 | responseText = $"WebProxyClient null : "; 59 | 60 | List contacts = null; 61 | 62 | if (_crmContext?.ServiceContext != null) 63 | { 64 | contacts = _crmContext.ServiceContext.CreateQuery("contact").Select(a => a.GetAttributeValue("fullname")).ToList(); 65 | Trace.TraceInformation("Contact Query Executed"); 66 | } 67 | 68 | responseText += contacts != null ? string.Join(",", contacts) : "null"; 69 | 70 | return View((object)responseText); 71 | } 72 | 73 | [Produces("application/json")] 74 | [Route("api/CrmSdk")] 75 | public IEnumerable GetContacts() 76 | { 77 | var contacts = _crmContext.ServiceContext.CreateQuery("contact").ToList(); 78 | return contacts; 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | 7 | namespace Adoxio.Connect.WebCore.Controllers 8 | { 9 | public class HomeController : Controller 10 | { 11 | public IActionResult Index() 12 | { 13 | return View(); 14 | } 15 | 16 | public IActionResult About() 17 | { 18 | ViewData["Message"] = "Your application description page."; 19 | 20 | return View(); 21 | } 22 | 23 | public IActionResult Contact() 24 | { 25 | ViewData["Message"] = "Your contact page."; 26 | 27 | return View(); 28 | } 29 | 30 | public IActionResult Error() 31 | { 32 | return View(); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/Extensions/CrmContextCore.cs: -------------------------------------------------------------------------------- 1 | using Adoxio.Dynamics.Connect; 2 | using Microsoft.Extensions.Options; 3 | 4 | namespace Adoxio.Connect.WebCore.Extensions 5 | { 6 | public class CrmContextCore : CrmContext 7 | { 8 | public CrmContextCore(IOptions s2sAppSettingsOptions) : base(s2sAppSettingsOptions.Value) 9 | { 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Hosting; 7 | 8 | namespace Adoxio.Connect.WebCore 9 | { 10 | public class Program 11 | { 12 | public static void Main(string[] args) 13 | { 14 | var host = new WebHostBuilder() 15 | .UseKestrel() 16 | .UseContentRoot(Directory.GetCurrentDirectory()) 17 | .UseIISIntegration() 18 | .UseStartup() 19 | .UseApplicationInsights() 20 | .Build(); 21 | 22 | host.Run(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:58636/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "Adoxio.Connect.WebCore": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:58637" 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Builder; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.Extensions.Configuration; 8 | using Microsoft.Extensions.DependencyInjection; 9 | using Microsoft.Extensions.Logging; 10 | using Adoxio.Dynamics.Connect; 11 | using Adoxio.Connect.WebCore.Extensions; 12 | 13 | namespace Adoxio.Connect.WebCore 14 | { 15 | public class Startup 16 | { 17 | public Startup(IHostingEnvironment env) 18 | { 19 | var builder = new ConfigurationBuilder() 20 | .SetBasePath(env.ContentRootPath) 21 | .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) 22 | .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) 23 | .AddEnvironmentVariables(); 24 | Configuration = builder.Build(); 25 | } 26 | 27 | public IConfigurationRoot Configuration { get; } 28 | 29 | // This method gets called by the runtime. Use this method to add services to the container. 30 | public void ConfigureServices(IServiceCollection services) 31 | { 32 | // Add framework services. 33 | services.AddMvc(); 34 | 35 | // Add Dynamics 365 S2S auth settings and Crm Context 36 | services.Configure(Configuration.GetSection("AdoxioConnect:dynS2S")); 37 | services.AddSingleton(); 38 | } 39 | 40 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 41 | public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 42 | { 43 | loggerFactory.AddConsole(Configuration.GetSection("Logging")); 44 | loggerFactory.AddDebug(); 45 | 46 | if (env.IsDevelopment()) 47 | { 48 | app.UseDeveloperExceptionPage(); 49 | app.UseBrowserLink(); 50 | } 51 | else 52 | { 53 | app.UseExceptionHandler("/Home/Error"); 54 | } 55 | 56 | app.UseStaticFiles(); 57 | 58 | app.UseMvc(routes => 59 | { 60 | routes.MapRoute( 61 | name: "default", 62 | template: "{controller=Home}/{action=Index}/{id?}"); 63 | }); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/Views/CrmSdk/Index.cshtml: -------------------------------------------------------------------------------- 1 | 2 | @{ 3 | ViewData["Title"] = "Index"; 4 | Layout = "~/Views/Shared/_Layout.cshtml"; 5 | } 6 | 7 |

    Index

    8 | 9 |

    Result: @Model

    -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/Views/CrmSdk/MultipleCalls.cshtml: -------------------------------------------------------------------------------- 1 | 2 | @{ 3 | ViewData["Title"] = "MultipleCalls"; 4 | Layout = "~/Views/Shared/_Layout.cshtml"; 5 | } 6 | 7 |

    MultipleCalls

    8 | 9 |

    Result: @Model

    -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/Views/CrmSdk/WhoAmI.cshtml: -------------------------------------------------------------------------------- 1 | 2 | @{ 3 | ViewData["Title"] = "WhoAmI"; 4 | Layout = "~/Views/Shared/_Layout.cshtml"; 5 | } 6 | 7 |

    WhoAmI

    8 | 9 |

    Result: @Model

    -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/Views/Home/About.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "About"; 3 | } 4 |

    @ViewData["Title"].

    5 |

    @ViewData["Message"]

    6 | 7 |

    Use this area to provide additional information.

    8 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/Views/Home/Contact.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Contact"; 3 | } 4 |

    @ViewData["Title"].

    5 |

    @ViewData["Message"]

    6 | 7 |
    8 | One Microsoft Way
    9 | Redmond, WA 98052-6399
    10 | P: 11 | 425.555.0100 12 |
    13 | 14 |
    15 | Support: Support@example.com
    16 | Marketing: Marketing@example.com 17 |
    18 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Home Page"; 3 | } 4 | 5 | 67 | 68 |
    69 |
    70 |

    Application uses

    71 |
      72 |
    • Sample pages using ASP.NET Core MVC
    • 73 |
    • Bower for managing client-side libraries
    • 74 |
    • Theming using Bootstrap
    • 75 |
    76 |
    77 | 88 | 100 |
    101 |

    Run & Deploy

    102 | 107 |
    108 |
    109 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Error"; 3 | } 4 | 5 |

    Error.

    6 |

    An error occurred while processing your request.

    7 | 8 |

    Development Mode

    9 |

    10 | Swapping to Development environment will display more detailed information about the error that occurred. 11 |

    12 |

    13 | Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. 14 |

    15 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 | @inject Microsoft.ApplicationInsights.AspNetCore.JavaScriptSnippet JavaScriptSnippet 2 | 3 | 4 | 5 | 6 | 7 | @ViewData["Title"] - Adoxio.Connect.WebCore 8 | 9 | 10 | 11 | 12 | 13 | 14 | 17 | 18 | 19 | @Html.Raw(JavaScriptSnippet.FullScript) 20 | 21 | 22 | 50 |
    51 | @RenderBody() 52 |
    53 |
    54 |

    © 2017 - Adoxio.Connect.WebCore

    55 |
    56 |
    57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 70 | 76 | 77 | 78 | 79 | @RenderSection("Scripts", required: false) 80 | 81 | 82 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/Views/Shared/_ValidationScriptsPartial.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 12 | 18 | 19 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using Adoxio.Connect.WebCore 2 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 3 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Debug", 6 | "System": "Information", 7 | "Microsoft": "Information" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "IncludeScopes": false, 4 | "LogLevel": { 5 | "Default": "Warning" 6 | } 7 | }, 8 | "AdoxioConnect": { 9 | "dynS2S": { 10 | "ClientId": "--ClientId--", 11 | "ClientSecret": "--ClientSecret--", 12 | "Resource": "https://--Instance--.crm.dynamics.com", 13 | "TenantId": "--TenantId--" 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "asp.net", 3 | "private": true, 4 | "dependencies": { 5 | "bootstrap": "3.3.7", 6 | "jquery": "2.2.0", 7 | "jquery-validation": "1.14.0", 8 | "jquery-validation-unobtrusive": "3.2.6" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/bundleconfig.json: -------------------------------------------------------------------------------- 1 | // Configure bundling and minification for the project. 2 | // More info at https://go.microsoft.com/fwlink/?LinkId=808241 3 | [ 4 | { 5 | "outputFileName": "wwwroot/css/site.min.css", 6 | // An array of relative input file paths. Globbing patterns supported 7 | "inputFiles": [ 8 | "wwwroot/css/site.css" 9 | ] 10 | }, 11 | { 12 | "outputFileName": "wwwroot/js/site.min.js", 13 | "inputFiles": [ 14 | "wwwroot/js/site.js" 15 | ], 16 | // Optionally specify minification options 17 | "minify": { 18 | "enabled": true, 19 | "renameLocals": true 20 | }, 21 | // Optionally generate .map file 22 | "sourceMap": false 23 | } 24 | ] 25 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | padding-bottom: 20px; 4 | } 5 | 6 | /* Wrapping element */ 7 | /* Set some basic padding to keep content from hitting the edges */ 8 | .body-content { 9 | padding-left: 15px; 10 | padding-right: 15px; 11 | } 12 | 13 | /* Set widths on the form inputs since otherwise they're 100% wide */ 14 | input, 15 | select, 16 | textarea { 17 | max-width: 280px; 18 | } 19 | 20 | /* Carousel */ 21 | .carousel-caption p { 22 | font-size: 20px; 23 | line-height: 1.4; 24 | } 25 | 26 | /* Make .svg files in the carousel display properly in older browsers */ 27 | .carousel-inner .item img[src$=".svg"] { 28 | width: 100%; 29 | } 30 | 31 | /* Hide/rearrange for smaller screens */ 32 | @media screen and (max-width: 767px) { 33 | /* Hide captions */ 34 | .carousel-caption { 35 | display: none; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/wwwroot/css/site.min.css: -------------------------------------------------------------------------------- 1 | body{padding-top:50px;padding-bottom:20px}.body-content{padding-left:15px;padding-right:15px}input,select,textarea{max-width:280px}.carousel-caption p{font-size:20px;line-height:1.4}.carousel-inner .item img[src$=".svg"]{width:100%}@media screen and (max-width:767px){.carousel-caption{display:none}} -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adoxio/Adoxio.Dynamics.Connect/82c09bcdc385be618bb1c1a870dec686fc725a92/samples/Adoxio.Connect.WebCore/wwwroot/favicon.ico -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/wwwroot/images/banner1.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/wwwroot/images/banner2.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/wwwroot/images/banner3.svg: -------------------------------------------------------------------------------- 1 | banner3b -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/wwwroot/images/banner4.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/wwwroot/js/site.js: -------------------------------------------------------------------------------- 1 | // Write your Javascript code. 2 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/wwwroot/js/site.min.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adoxio/Adoxio.Dynamics.Connect/82c09bcdc385be618bb1c1a870dec686fc725a92/samples/Adoxio.Connect.WebCore/wwwroot/js/site.min.js -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/wwwroot/lib/bootstrap/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bootstrap", 3 | "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.", 4 | "keywords": [ 5 | "css", 6 | "js", 7 | "less", 8 | "mobile-first", 9 | "responsive", 10 | "front-end", 11 | "framework", 12 | "web" 13 | ], 14 | "homepage": "http://getbootstrap.com", 15 | "license": "MIT", 16 | "moduleType": "globals", 17 | "main": [ 18 | "less/bootstrap.less", 19 | "dist/js/bootstrap.js" 20 | ], 21 | "ignore": [ 22 | "/.*", 23 | "_config.yml", 24 | "CNAME", 25 | "composer.json", 26 | "CONTRIBUTING.md", 27 | "docs", 28 | "js/tests", 29 | "test-infra" 30 | ], 31 | "dependencies": { 32 | "jquery": "1.9.1 - 3" 33 | }, 34 | "version": "3.3.7", 35 | "_release": "3.3.7", 36 | "_resolution": { 37 | "type": "version", 38 | "tag": "v3.3.7", 39 | "commit": "0b9c4a4007c44201dce9a6cc1a38407005c26c86" 40 | }, 41 | "_source": "https://github.com/twbs/bootstrap.git", 42 | "_target": "v3.3.7", 43 | "_originalSource": "bootstrap", 44 | "_direct": true 45 | } -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/wwwroot/lib/bootstrap/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2016 Twitter, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adoxio/Adoxio.Dynamics.Connect/82c09bcdc385be618bb1c1a870dec686fc725a92/samples/Adoxio.Connect.WebCore/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adoxio/Adoxio.Dynamics.Connect/82c09bcdc385be618bb1c1a870dec686fc725a92/samples/Adoxio.Connect.WebCore/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adoxio/Adoxio.Dynamics.Connect/82c09bcdc385be618bb1c1a870dec686fc725a92/samples/Adoxio.Connect.WebCore/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Adoxio/Adoxio.Dynamics.Connect/82c09bcdc385be618bb1c1a870dec686fc725a92/samples/Adoxio.Connect.WebCore/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/wwwroot/lib/bootstrap/dist/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/wwwroot/lib/jquery-validation-unobtrusive/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-validation-unobtrusive", 3 | "version": "3.2.6", 4 | "homepage": "https://github.com/aspnet/jquery-validation-unobtrusive", 5 | "description": "Add-on to jQuery Validation to enable unobtrusive validation options in data-* attributes.", 6 | "main": [ 7 | "jquery.validate.unobtrusive.js" 8 | ], 9 | "ignore": [ 10 | "**/.*", 11 | "*.json", 12 | "*.md", 13 | "*.txt", 14 | "gulpfile.js" 15 | ], 16 | "keywords": [ 17 | "jquery", 18 | "asp.net", 19 | "mvc", 20 | "validation", 21 | "unobtrusive" 22 | ], 23 | "authors": [ 24 | "Microsoft" 25 | ], 26 | "license": "http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm", 27 | "repository": { 28 | "type": "git", 29 | "url": "git://github.com/aspnet/jquery-validation-unobtrusive.git" 30 | }, 31 | "dependencies": { 32 | "jquery-validation": ">=1.8", 33 | "jquery": ">=1.8" 34 | }, 35 | "_release": "3.2.6", 36 | "_resolution": { 37 | "type": "version", 38 | "tag": "v3.2.6", 39 | "commit": "13386cd1b5947d8a5d23a12b531ce3960be1eba7" 40 | }, 41 | "_source": "git://github.com/aspnet/jquery-validation-unobtrusive.git", 42 | "_target": "3.2.6", 43 | "_originalSource": "jquery-validation-unobtrusive" 44 | } -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | ** Unobtrusive validation support library for jQuery and jQuery Validate 3 | ** Copyright (C) Microsoft Corporation. All rights reserved. 4 | */ 5 | !function(a){function e(a,e,n){a.rules[e]=n,a.message&&(a.messages[e]=a.message)}function n(a){return a.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}function t(a){return a.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function r(a){return a.substr(0,a.lastIndexOf(".")+1)}function i(a,e){return 0===a.indexOf("*.")&&(a=a.replace("*.",e)),a}function o(e,n){var r=a(this).find("[data-valmsg-for='"+t(n[0].name)+"']"),i=r.attr("data-valmsg-replace"),o=i?a.parseJSON(i)!==!1:null;r.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",r),o?(r.empty(),e.removeClass("input-validation-error").appendTo(r)):e.hide()}function d(e,n){var t=a(this).find("[data-valmsg-summary=true]"),r=t.find("ul");r&&r.length&&n.errorList.length&&(r.empty(),t.addClass("validation-summary-errors").removeClass("validation-summary-valid"),a.each(n.errorList,function(){a("
  • ").html(this.message).appendTo(r)}))}function s(e){var n=e.data("unobtrusiveContainer");if(n){var t=n.attr("data-valmsg-replace"),r=t?a.parseJSON(t):null;n.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),r&&n.empty()}}function l(e){var n=a(this),t="__jquery_unobtrusive_validation_form_reset";if(!n.data(t)){n.data(t,!0);try{n.data("validator").resetForm()}finally{n.removeData(t)}n.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),n.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function m(e){var n=a(e),t=n.data(v),r=a.proxy(l,e),i=p.unobtrusive.options||{},m=function(n,t){var r=i[n];r&&a.isFunction(r)&&r.apply(e,t)};return t||(t={options:{errorClass:i.errorClass||"input-validation-error",errorElement:i.errorElement||"span",errorPlacement:function(){o.apply(e,arguments),m("errorPlacement",arguments)},invalidHandler:function(){d.apply(e,arguments),m("invalidHandler",arguments)},messages:{},rules:{},success:function(){s.apply(e,arguments),m("success",arguments)}},attachValidation:function(){n.off("reset."+v,r).on("reset."+v,r).validate(this.options)},validate:function(){return n.validate(),n.valid()}},n.data(v,t)),t}var u,p=a.validator,v="unobtrusiveValidation";p.unobtrusive={adapters:[],parseElement:function(e,n){var t,r,i,o=a(e),d=o.parents("form")[0];d&&(t=m(d),t.options.rules[e.name]=r={},t.options.messages[e.name]=i={},a.each(this.adapters,function(){var n="data-val-"+this.name,t=o.attr(n),s={};void 0!==t&&(n+="-",a.each(this.params,function(){s[this]=o.attr(n+this)}),this.adapt({element:e,form:d,message:t,params:s,rules:r,messages:i}))}),a.extend(r,{__dummy__:!0}),n||t.attachValidation())},parse:function(e){var n=a(e),t=n.parents().addBack().filter("form").add(n.find("form")).has("[data-val=true]");n.find("[data-val=true]").each(function(){p.unobtrusive.parseElement(this,!0)}),t.each(function(){var a=m(this);a&&a.attachValidation()})}},u=p.unobtrusive.adapters,u.add=function(a,e,n){return n||(n=e,e=[]),this.push({name:a,params:e,adapt:n}),this},u.addBool=function(a,n){return this.add(a,function(t){e(t,n||a,!0)})},u.addMinMax=function(a,n,t,r,i,o){return this.add(a,[i||"min",o||"max"],function(a){var i=a.params.min,o=a.params.max;i&&o?e(a,r,[i,o]):i?e(a,n,i):o&&e(a,t,o)})},u.addSingleVal=function(a,n,t){return this.add(a,[n||"val"],function(r){e(r,t||a,r.params[n])})},p.addMethod("__dummy__",function(a,e,n){return!0}),p.addMethod("regex",function(a,e,n){var t;return this.optional(e)?!0:(t=new RegExp(n).exec(a),t&&0===t.index&&t[0].length===a.length)}),p.addMethod("nonalphamin",function(a,e,n){var t;return n&&(t=a.match(/\W/g),t=t&&t.length>=n),t}),p.methods.extension?(u.addSingleVal("accept","mimtype"),u.addSingleVal("extension","extension")):u.addSingleVal("extension","extension","accept"),u.addSingleVal("regex","pattern"),u.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),u.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),u.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),u.add("equalto",["other"],function(n){var o=r(n.element.name),d=n.params.other,s=i(d,o),l=a(n.form).find(":input").filter("[name='"+t(s)+"']")[0];e(n,"equalTo",l)}),u.add("required",function(a){("INPUT"!==a.element.tagName.toUpperCase()||"CHECKBOX"!==a.element.type.toUpperCase())&&e(a,"required",!0)}),u.add("remote",["url","type","additionalfields"],function(o){var d={url:o.params.url,type:o.params.type||"GET",data:{}},s=r(o.element.name);a.each(n(o.params.additionalfields||o.element.name),function(e,n){var r=i(n,s);d.data[r]=function(){var e=a(o.form).find(":input").filter("[name='"+t(r)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),e(o,"remote",d)}),u.add("password",["min","nonalphamin","regex"],function(a){a.params.min&&e(a,"minlength",a.params.min),a.params.nonalphamin&&e(a,"nonalphamin",a.params.nonalphamin),a.params.regex&&e(a,"regex",a.params.regex)}),a(function(){p.unobtrusive.parse(document)})}(jQuery); -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/wwwroot/lib/jquery-validation/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-validation", 3 | "homepage": "http://jqueryvalidation.org/", 4 | "repository": { 5 | "type": "git", 6 | "url": "git://github.com/jzaefferer/jquery-validation.git" 7 | }, 8 | "authors": [ 9 | "Jörn Zaefferer " 10 | ], 11 | "description": "Form validation made easy", 12 | "main": "dist/jquery.validate.js", 13 | "keywords": [ 14 | "forms", 15 | "validation", 16 | "validate" 17 | ], 18 | "license": "MIT", 19 | "ignore": [ 20 | "**/.*", 21 | "node_modules", 22 | "bower_components", 23 | "test", 24 | "demo", 25 | "lib" 26 | ], 27 | "dependencies": { 28 | "jquery": ">= 1.7.2" 29 | }, 30 | "version": "1.14.0", 31 | "_release": "1.14.0", 32 | "_resolution": { 33 | "type": "version", 34 | "tag": "1.14.0", 35 | "commit": "c1343fb9823392aa9acbe1c3ffd337b8c92fed48" 36 | }, 37 | "_source": "git://github.com/jzaefferer/jquery-validation.git", 38 | "_target": ">=1.8", 39 | "_originalSource": "jquery-validation" 40 | } -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/wwwroot/lib/jquery-validation/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright Jörn Zaefferer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/wwwroot/lib/jquery/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery", 3 | "main": "dist/jquery.js", 4 | "license": "MIT", 5 | "ignore": [ 6 | "package.json" 7 | ], 8 | "keywords": [ 9 | "jquery", 10 | "javascript", 11 | "browser", 12 | "library" 13 | ], 14 | "homepage": "https://github.com/jquery/jquery-dist", 15 | "version": "2.2.0", 16 | "_release": "2.2.0", 17 | "_resolution": { 18 | "type": "version", 19 | "tag": "2.2.0", 20 | "commit": "6fc01e29bdad0964f62ef56d01297039cdcadbe5" 21 | }, 22 | "_source": "git://github.com/jquery/jquery-dist.git", 23 | "_target": "2.2.0", 24 | "_originalSource": "jquery" 25 | } -------------------------------------------------------------------------------- /samples/Adoxio.Connect.WebCore/wwwroot/lib/jquery/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright jQuery Foundation and other contributors, https://jquery.org/ 2 | 3 | This software consists of voluntary contributions made by many 4 | individuals. For exact contribution history, see the revision history 5 | available at https://github.com/jquery/jquery 6 | 7 | The following license applies to all parts of this software except as 8 | documented below: 9 | 10 | ==== 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining 13 | a copy of this software and associated documentation files (the 14 | "Software"), to deal in the Software without restriction, including 15 | without limitation the rights to use, copy, modify, merge, publish, 16 | distribute, sublicense, and/or sell copies of the Software, and to 17 | permit persons to whom the Software is furnished to do so, subject to 18 | the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be 21 | included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | ==== 32 | 33 | All files located in the node_modules and external directories are 34 | externally maintained libraries used by this software which have their 35 | own licenses; we recommend you read them, as their terms may differ from 36 | the terms above. 37 | -------------------------------------------------------------------------------- /src/Adoxio.Dynamics.Connect/Adoxio.Dynamics.Connect.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {EDB4BCD1-BFD0-434F-AD88-D8D5268ECFDF} 8 | Library 9 | Properties 10 | Adoxio.Dynamics.Connect 11 | Adoxio.Dynamics.Connect 12 | v4.6.1 13 | 512 14 | SAK 15 | SAK 16 | SAK 17 | SAK 18 | 19 | 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | 28 | 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | false 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | ..\..\packages\Microsoft.CrmSdk.CoreAssemblies.8.2.0.2\lib\net452\Microsoft.Crm.Sdk.Proxy.dll 46 | True 47 | 48 | 49 | ..\..\packages\Microsoft.IdentityModel.6.1.7600.16394\lib\net35\Microsoft.IdentityModel.dll 50 | True 51 | 52 | 53 | ..\..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.2.22.302111727\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll 54 | True 55 | 56 | 57 | ..\..\packages\Microsoft.CrmSdk.CoreAssemblies.8.2.0.2\lib\net452\Microsoft.Xrm.Sdk.dll 58 | True 59 | 60 | 61 | ..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll 62 | True 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 100 | -------------------------------------------------------------------------------- /src/Adoxio.Dynamics.Connect/CrmContext.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Configuration; 3 | using System.Diagnostics; 4 | using Microsoft.IdentityModel.Clients.ActiveDirectory; 5 | using Microsoft.Xrm.Sdk.Client; 6 | using Microsoft.Xrm.Sdk.WebServiceClient; 7 | 8 | namespace Adoxio.Dynamics.Connect 9 | { 10 | public class CrmContext : IDisposable 11 | { 12 | private const string ServiceEndpoint = @"/xrmservices/2011/organization.svc/web?SdkClientVersion="; 13 | private const string AadInstance = "https://login.microsoftonline.com/"; 14 | 15 | private readonly string _sdkClientVersion = ConfigurationManager.AppSettings["dyn:SdkClientVersion"] ?? "8.2"; 16 | private OrganizationWebProxyClient _organizationWebProxyClient; 17 | private OrganizationServiceContext _organizationServiceContext; 18 | private readonly string _resource; 19 | private string _token; 20 | private readonly Func _getToken; 21 | private static S2SAppSettings _appSettings; 22 | private static AuthenticationContext _authContext; 23 | 24 | public CrmContext() : this(SettingManager.GetAppSettings()) { } 25 | 26 | public CrmContext(string clientId, string clientSecret, string resource, string tenantId, Func getToken = null) 27 | : this(new S2SAppSettings() 28 | { 29 | ClientId = clientId, 30 | ClientSecret = clientSecret, 31 | Resource = resource, 32 | TenantId = tenantId 33 | }, getToken) 34 | { } 35 | 36 | public CrmContext(S2SAppSettings settings, Func getToken = null) 37 | { 38 | if (_appSettings == null || !_appSettings.Equals(settings)) 39 | { 40 | settings.AssertAppSettings(); 41 | } 42 | _appSettings = settings; 43 | 44 | _resource = settings.Resource; 45 | Trace.TraceInformation($"CrmContext set instance: {_resource}"); 46 | 47 | _getToken = getToken == null ? GetDefaultToken : getToken; 48 | } 49 | 50 | public CrmContext(string resource, string token) 51 | { 52 | _resource = resource; 53 | _token = token; 54 | } 55 | 56 | public OrganizationWebProxyClient WebProxyClient 57 | { 58 | get 59 | { 60 | Trace.TraceInformation("Get WebProxyClient"); 61 | // create client for instance if null 62 | if (_organizationWebProxyClient == null) 63 | { 64 | Trace.TraceInformation("WebProxyClient is null"); 65 | var serviceUri = new Uri($"{_resource}{ServiceEndpoint}{_sdkClientVersion}"); 66 | _organizationWebProxyClient = new OrganizationWebProxyClient(serviceUri, false); 67 | Trace.TraceInformation($"Init OrganizationWebProxyClient: {serviceUri}"); 68 | } 69 | 70 | var token = _token; 71 | // get token if token string is empty 72 | if (string.IsNullOrEmpty(token)) 73 | { 74 | Trace.TraceInformation("Execute GetToken"); 75 | token = _getToken(_appSettings); 76 | } 77 | 78 | // add latest token token to client header 79 | _organizationWebProxyClient.HeaderToken = token; 80 | Trace.TraceInformation("token added to WebProxyClient headertoken"); 81 | return _organizationWebProxyClient; 82 | } 83 | } 84 | 85 | public OrganizationServiceContext ServiceContext 86 | { 87 | get 88 | { 89 | Trace.TraceInformation("Get ServiceContext"); 90 | if (_organizationServiceContext == null) 91 | { 92 | Trace.TraceInformation("ServiceContext is null"); 93 | _organizationServiceContext = new OrganizationServiceContext(WebProxyClient); 94 | } 95 | 96 | return _organizationServiceContext; 97 | } 98 | } 99 | 100 | public static CrmContext Create() 101 | { 102 | return new CrmContext(); 103 | } 104 | 105 | public static CrmContext Create(string clientId, string clientSecret, string resource, string tenantId) 106 | { 107 | return new CrmContext(clientId, clientSecret, resource, tenantId); 108 | } 109 | 110 | public static CrmContext Create(S2SAppSettings settings) 111 | { 112 | return new CrmContext(settings); 113 | } 114 | 115 | public void Dispose() 116 | { 117 | Dispose(true); 118 | GC.SuppressFinalize(this); 119 | Trace.TraceInformation("CrmContext dispose complete"); 120 | } 121 | 122 | protected virtual void Dispose(bool disposing) 123 | { 124 | if (disposing) 125 | { 126 | _organizationWebProxyClient?.Dispose(); 127 | _organizationServiceContext?.Dispose(); 128 | Trace.TraceInformation("WebProxyClient and ServiceContext disposed"); 129 | } 130 | } 131 | 132 | public void ResetTokenCache() 133 | { 134 | if (_authContext != null) 135 | { 136 | _authContext.TokenCache.Clear(); 137 | Trace.TraceInformation("ADAL TokenCache cleared"); 138 | } 139 | } 140 | 141 | internal void ResetAll() 142 | { 143 | ResetTokenCache(); 144 | _appSettings = null; 145 | _authContext = null; 146 | Trace.TraceInformation("Reset complete"); 147 | } 148 | 149 | #region private helpers 150 | 151 | private string GetDefaultToken(S2SAppSettings settings) 152 | { 153 | var authority = $"{AadInstance}{settings.TenantId}"; 154 | 155 | if (_authContext == null || !_authContext.Authority.Contains(authority)) 156 | { 157 | _authContext = new AuthenticationContext(authority); 158 | Trace.TraceInformation($"CrmContext set auth context: {authority}"); 159 | } 160 | var result = _authContext.AcquireToken(settings.Resource, 161 | new ClientCredential(settings.ClientId, settings.ClientSecret)); 162 | Trace.TraceInformation($"ADAL AcquireToken complete"); 163 | 164 | return result.AccessToken; 165 | } 166 | 167 | #endregion 168 | } 169 | } -------------------------------------------------------------------------------- /src/Adoxio.Dynamics.Connect/CrmContextExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Microsoft.Xrm.Sdk; 3 | using Microsoft.Xrm.Sdk.Query; 4 | 5 | namespace Adoxio.Dynamics.Connect 6 | { 7 | public static class CrmContextExtensions 8 | { 9 | public static Entity GetContactByExternalIdentityUsername(this CrmContext context, string username) 10 | { 11 | var fetchxml = 12 | $@" 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | "; 22 | 23 | var contactResponse = context.WebProxyClient.RetrieveMultiple(new FetchExpression(fetchxml)); 24 | 25 | return contactResponse.Entities.SingleOrDefault(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Adoxio.Dynamics.Connect/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Adoxio.Dynamics.Connect")] 9 | [assembly: AssemblyDescription("Implements OrganizationWebProxyClient with Dynamics 365 Server-to-Server authentication to retrieve bearer token.")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Adoxio Business Solutions")] 12 | [assembly: AssemblyProduct("Adoxio.Dynamics.Connect")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | [assembly: InternalsVisibleTo("Adoxio.Dynamics.ConnectTests")] 17 | 18 | // Setting ComVisible to false makes the types in this assembly not visible 19 | // to COM components. If you need to access a type in this assembly from 20 | // COM, set the ComVisible attribute to true on that type. 21 | [assembly: ComVisible(false)] 22 | 23 | // The following GUID is for the ID of the typelib if this project is exposed to COM 24 | [assembly: Guid("edb4bcd1-bfd0-434f-ad88-d8d5268ecfdf")] 25 | 26 | // Version information for an assembly consists of the following four values: 27 | // 28 | // Major Version 29 | // Minor Version 30 | // Build Number 31 | // Revision 32 | // 33 | // You can specify all the values or you can default the Build and Revision Numbers 34 | // by using the '*' as shown below: 35 | // [assembly: AssemblyVersion("1.0.*")] 36 | [assembly: AssemblyVersion("0.4.0.*")] 37 | -------------------------------------------------------------------------------- /src/Adoxio.Dynamics.Connect/S2SAppSettings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Diagnostics; 3 | 4 | namespace Adoxio.Dynamics.Connect 5 | { 6 | public class S2SAppSettings 7 | { 8 | public string ClientId { get; set; } 9 | public string ClientSecret { get; set; } 10 | public string TenantId { get; set; } 11 | public string Resource { get; set; } 12 | 13 | public S2SAppSettings() 14 | { } 15 | 16 | public S2SAppSettings(string clientId, string clientSecret, string resource, string tenantId) 17 | { 18 | ClientId = clientId; 19 | ClientSecret = clientSecret; 20 | Resource = resource; 21 | TenantId = tenantId; 22 | 23 | AssertAppSettings(); 24 | } 25 | 26 | public void AssertAppSettings() 27 | { 28 | if (string.IsNullOrEmpty(ClientId) || !Guid.TryParse(ClientId, out Guid tempGuid)) 29 | { 30 | throw new ArgumentException($"{nameof(ClientId)} is null or not valid format"); 31 | } 32 | if (string.IsNullOrEmpty(ClientSecret)) 33 | { 34 | throw new ArgumentNullException($"{nameof(ClientSecret)} is null"); 35 | } 36 | if (!Uri.IsWellFormedUriString(Resource, UriKind.Absolute)) 37 | { 38 | throw new UriFormatException($"{nameof(Resource)} is not well formed URI"); 39 | } 40 | if (string.IsNullOrEmpty(TenantId) || !Guid.TryParse(TenantId, out tempGuid)) 41 | { 42 | throw new ArgumentException($"{nameof(TenantId)} is null or not valid format"); 43 | } 44 | Trace.TraceInformation("Successfully asserted S2S App Settings"); 45 | } 46 | 47 | public bool ValidateAppSettings() 48 | { 49 | try 50 | { 51 | AssertAppSettings(); 52 | } 53 | catch (Exception) 54 | { 55 | return false; 56 | } 57 | return true; 58 | } 59 | 60 | public virtual bool Equals(S2SAppSettings settings) 61 | { 62 | if (!ClientId.Equals(settings.ClientId)) 63 | return false; 64 | if (!ClientSecret.Equals(settings.ClientSecret)) 65 | return false; 66 | if (!Resource.Equals(settings.Resource)) 67 | return false; 68 | if (!TenantId.Equals(settings.TenantId)) 69 | return false; 70 | return true; 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/Adoxio.Dynamics.Connect/SettingManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Configuration; 3 | using System.Diagnostics; 4 | using System.IO; 5 | using System.Text; 6 | using System.Web.Hosting; 7 | using System.Web.Security; 8 | using Newtonsoft.Json; 9 | 10 | namespace Adoxio.Dynamics.Connect 11 | { 12 | public static partial class SettingManager 13 | { 14 | private static readonly string _settingClientId = "dyn:ClientId"; 15 | private static readonly string _settingClientSecret = "dyn:ClientSecret"; 16 | private static readonly string _settingResource = "dyn:Resource"; 17 | private static readonly string _settingTenantId = "dyn:TenantId"; 18 | 19 | private static readonly Lazy SettingsPath = new Lazy(GetSettingsPath); 20 | private static readonly string[] MachineKeyPurposes = { "adoxio", "setup" }; 21 | 22 | public static void Save(string clientId, string clientSecret, string tenantId, string resource) 23 | { 24 | var protectedSecret = Convert.ToBase64String(MachineKey.Protect(Encoding.UTF8.GetBytes(clientSecret), MachineKeyPurposes)); 25 | 26 | var jsonObject = new 27 | { 28 | ClientId = clientId, 29 | ClientSecret = protectedSecret, 30 | TenantId = tenantId, 31 | Resource = resource 32 | }; 33 | 34 | using (var fs = File.Open(SettingsPath.Value, FileMode.OpenOrCreate, FileAccess.ReadWrite)) 35 | { 36 | fs.SetLength(0); 37 | using (var sw = new StreamWriter(fs)) 38 | using (var jw = new JsonTextWriter(sw)) 39 | { 40 | jw.Formatting = Formatting.Indented; 41 | 42 | JsonSerializer serializer = new JsonSerializer(); 43 | serializer.Serialize(jw, jsonObject); 44 | } 45 | } 46 | } 47 | 48 | public static bool Exists() 49 | { 50 | return File.Exists(SettingsPath.Value); 51 | } 52 | 53 | public static S2SAppSettings Read() 54 | { 55 | using (StreamReader r = new StreamReader(SettingsPath.Value)) 56 | { 57 | string json = r.ReadToEnd(); 58 | var settings = JsonConvert.DeserializeObject(json); 59 | 60 | if (!string.IsNullOrEmpty(settings.ClientSecret)) 61 | { 62 | var protectedSecret = settings.ClientSecret; 63 | settings.ClientSecret = Encoding.UTF8.GetString(MachineKey.Unprotect(Convert.FromBase64String(protectedSecret), MachineKeyPurposes)); 64 | } 65 | 66 | return settings; 67 | } 68 | } 69 | 70 | public static bool InitAppSettings() 71 | { 72 | if (GetAppSettings().ValidateAppSettings()) 73 | { 74 | return true; 75 | } 76 | 77 | if (Exists() && LoadConfigAppSettings(Read())) 78 | { 79 | return true; 80 | } 81 | 82 | return false; 83 | } 84 | 85 | public static bool LoadConfigAppSettings(S2SAppSettings appSettings) 86 | { 87 | Trace.TraceInformation("Start load/set with ConfigurationManager of app settings"); 88 | try 89 | { 90 | ConfigurationManager.AppSettings[_settingClientId] = appSettings.ClientId; 91 | ConfigurationManager.AppSettings[_settingClientSecret] = appSettings.ClientSecret; 92 | ConfigurationManager.AppSettings[_settingResource] = appSettings.Resource; 93 | ConfigurationManager.AppSettings[_settingTenantId] = appSettings.TenantId; 94 | return true; 95 | } 96 | catch (Exception) 97 | { 98 | return false; 99 | } 100 | } 101 | 102 | public static S2SAppSettings GetAppSettings() 103 | { 104 | Trace.TraceInformation("GetAppSettings with ConfigurationManager"); 105 | var settings = new S2SAppSettings() 106 | { 107 | ClientId = ConfigurationManager.AppSettings[_settingClientId], 108 | ClientSecret = ConfigurationManager.AppSettings[_settingClientSecret], 109 | Resource = ConfigurationManager.AppSettings[_settingResource], 110 | TenantId = ConfigurationManager.AppSettings[_settingTenantId] 111 | }; 112 | 113 | return settings; 114 | } 115 | 116 | private static string GetSettingsPath() 117 | { 118 | var virtualPath = ConfigurationManager.AppSettings["SettingsPath"] ?? "~/App_Data/settings.json"; 119 | var settingsPath = HostingEnvironment.MapPath(virtualPath); 120 | var dataDirectory = Path.GetDirectoryName(settingsPath); 121 | 122 | if (!Directory.Exists(dataDirectory)) 123 | { 124 | Directory.CreateDirectory(dataDirectory); 125 | } 126 | 127 | return settingsPath; 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /src/Adoxio.Dynamics.Connect/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/Adoxio.Dynamics.ConnectTests/Adoxio.Dynamics.ConnectTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {E86DCCD3-98C2-441F-AF78-20BE7767CCF3} 8 | Library 9 | Properties 10 | Adoxio.Dynamics.ConnectTests 11 | Adoxio.Dynamics.ConnectTests 12 | v4.6.1 13 | 512 14 | {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 15 | 10.0 16 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 17 | $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages 18 | False 19 | UnitTest 20 | 21 | 22 | 23 | 24 | 25 | true 26 | full 27 | false 28 | bin\Debug\ 29 | DEBUG;TRACE 30 | prompt 31 | 4 32 | 33 | 34 | pdbonly 35 | true 36 | bin\Release\ 37 | TRACE 38 | prompt 39 | 4 40 | 41 | 42 | false 43 | 44 | 45 | 46 | 47 | 48 | 49 | false 50 | 51 | 52 | 53 | ..\..\packages\Microsoft.CrmSdk.CoreAssemblies.8.2.0.2\lib\net452\Microsoft.Crm.Sdk.Proxy.dll 54 | 55 | 56 | ..\..\packages\Microsoft.IdentityModel.6.1.7600.16394\lib\net35\Microsoft.IdentityModel.dll 57 | True 58 | 59 | 60 | ..\..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.2.22.302111727\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll 61 | 62 | 63 | ..\..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.2.22.302111727\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.WindowsForms.dll 64 | 65 | 66 | ..\..\packages\MSTest.TestFramework.1.1.11\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll 67 | 68 | 69 | ..\..\packages\MSTest.TestFramework.1.1.11\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll 70 | 71 | 72 | ..\..\packages\Microsoft.CrmSdk.CoreAssemblies.8.2.0.2\lib\net452\Microsoft.Xrm.Sdk.dll 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | {EDB4BCD1-BFD0-434F-AD88-D8D5268ECFDF} 107 | Adoxio.Dynamics.Connect 108 | 109 | 110 | 111 | 112 | 113 | 114 | False 115 | 116 | 117 | False 118 | 119 | 120 | False 121 | 122 | 123 | False 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. 133 | 134 | 135 | 136 | 137 | 138 | 145 | -------------------------------------------------------------------------------- /src/Adoxio.Dynamics.ConnectTests/CrmContextTests.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.VisualStudio.TestTools.UnitTesting; 2 | using Adoxio.Dynamics.Connect; 3 | using System; 4 | using System.Configuration; 5 | using Microsoft.Crm.Sdk.Messages; 6 | using Microsoft.IdentityModel.Clients.ActiveDirectory; 7 | using System.ServiceModel; 8 | using System.Diagnostics; 9 | 10 | namespace Adoxio.Dynamics.ConnectTests 11 | { 12 | [TestClass()] 13 | public class CrmContextTests 14 | { 15 | 16 | [TestMethod()] 17 | public void CrmContext_DefaultTest() 18 | { 19 | ConfigurationManager.AppSettings["dyn:ClientId"] = S2SProp.testClientId; 20 | ConfigurationManager.AppSettings["dyn:ClientSecret"] = S2SProp.testClientSecret; 21 | ConfigurationManager.AppSettings["dyn:Resource"] = S2SProp.testResource; 22 | ConfigurationManager.AppSettings["dyn:tenantId"] = S2SProp.testTenantId; 23 | 24 | var context = new CrmContext(); 25 | WhoAmITest(context); 26 | } 27 | 28 | [TestMethod()] 29 | public void CrmContext_StringTest() 30 | { 31 | var context = new CrmContext(S2SProp.testClientId, S2SProp.testClientSecret, S2SProp.testResource, S2SProp.testTenantId); 32 | WhoAmITest(context); 33 | } 34 | 35 | [TestMethod()] 36 | public void CrmContext_ObjectTest() 37 | { 38 | var settings = new S2SAppSettings(S2SProp.testClientId, S2SProp.testClientSecret, S2SProp.testResource, S2SProp.testTenantId); 39 | var context = new CrmContext(settings); 40 | WhoAmITest(context); 41 | } 42 | 43 | [TestMethod()] 44 | public void CrmContext_DefaultCreateTest() 45 | { 46 | ConfigurationManager.AppSettings["dyn:ClientId"] = S2SProp.testClientId; 47 | ConfigurationManager.AppSettings["dyn:ClientSecret"] = S2SProp.testClientSecret; 48 | ConfigurationManager.AppSettings["dyn:Resource"] = S2SProp.testResource; 49 | ConfigurationManager.AppSettings["dyn:tenantId"] = S2SProp.testTenantId; 50 | 51 | var context = CrmContext.Create(); 52 | WhoAmITest(context); 53 | } 54 | 55 | [TestMethod()] 56 | public void CrmContext_StringCreateTest() 57 | { 58 | var context = CrmContext.Create(S2SProp.testClientId, S2SProp.testClientSecret, S2SProp.testResource, S2SProp.testTenantId); 59 | WhoAmITest(context); 60 | } 61 | 62 | [TestMethod()] 63 | public void CrmContext_ObjectCreateTest() 64 | { 65 | var settings = new S2SAppSettings(S2SProp.testClientId, S2SProp.testClientSecret, S2SProp.testResource, S2SProp.testTenantId); 66 | 67 | var context = CrmContext.Create(settings); 68 | WhoAmITest(context); 69 | } 70 | 71 | [TestMethod()] 72 | public void CrmContext_DefaultMultipleContext_Test() 73 | { 74 | ConfigurationManager.AppSettings["dyn:ClientId"] = S2SProp.testClientId; 75 | ConfigurationManager.AppSettings["dyn:ClientSecret"] = S2SProp.testClientSecret; 76 | ConfigurationManager.AppSettings["dyn:Resource"] = S2SProp.testResource; 77 | ConfigurationManager.AppSettings["dyn:tenantId"] = S2SProp.testTenantId; 78 | 79 | var context = new CrmContext(); 80 | WhoAmITest(context); 81 | 82 | var context2 = new CrmContext(); 83 | WhoAmITest(context2); 84 | 85 | var context3 = new CrmContext(); 86 | WhoAmITest(context3); 87 | } 88 | 89 | [TestMethod()] 90 | public void CrmContext_DefaultMultipleContextNoClear_Test() 91 | { 92 | ConfigurationManager.AppSettings["dyn:ClientId"] = S2SProp.testClientId; 93 | ConfigurationManager.AppSettings["dyn:ClientSecret"] = S2SProp.testClientSecret; 94 | ConfigurationManager.AppSettings["dyn:Resource"] = S2SProp.testResource; 95 | ConfigurationManager.AppSettings["dyn:tenantId"] = S2SProp.testTenantId; 96 | 97 | var context = new CrmContext(); 98 | var context2 = new CrmContext(); 99 | var context3 = new CrmContext(); 100 | 101 | try 102 | { 103 | WhoAmITest(context, false); 104 | WhoAmITest(context2, false); 105 | WhoAmITest(context3, false); 106 | } 107 | finally 108 | { 109 | context.Dispose(); 110 | context.ResetAll(); 111 | context2.Dispose(); 112 | context2.ResetAll(); 113 | context3.Dispose(); 114 | context3.ResetAll(); 115 | } 116 | } 117 | 118 | [TestMethod()] 119 | public void CrmContext_DefaultMultipleRequestsNoClear_Test() 120 | { 121 | ConfigurationManager.AppSettings["dyn:ClientId"] = S2SProp.testClientId; 122 | ConfigurationManager.AppSettings["dyn:ClientSecret"] = S2SProp.testClientSecret; 123 | ConfigurationManager.AppSettings["dyn:Resource"] = S2SProp.testResource; 124 | ConfigurationManager.AppSettings["dyn:tenantId"] = S2SProp.testTenantId; 125 | 126 | var context = new CrmContext(); 127 | try 128 | { 129 | WhoAmITest(context, false); 130 | WhoAmITest(context, false); 131 | WhoAmITest(context, false); 132 | } 133 | finally 134 | { 135 | context.Dispose(); 136 | context.ResetAll(); 137 | } 138 | } 139 | 140 | [TestMethod] 141 | [ExpectedException(typeof(AdalServiceException))] 142 | public void CrmContext_Default_InvalidClientId_Throws() 143 | { 144 | ConfigurationManager.AppSettings["dyn:ClientId"] = Guid.NewGuid().ToString(); 145 | ConfigurationManager.AppSettings["dyn:ClientSecret"] = S2SProp.testClientSecret; 146 | ConfigurationManager.AppSettings["dyn:Resource"] = S2SProp.testResource; 147 | ConfigurationManager.AppSettings["dyn:tenantId"] = S2SProp.testTenantId; 148 | 149 | var context = new CrmContext(); 150 | WhoAmITest(context); 151 | } 152 | 153 | [TestMethod] 154 | [ExpectedException(typeof(AdalServiceException))] 155 | public void CrmContext_Default_InvalidClientSecret_Throws() 156 | { 157 | ConfigurationManager.AppSettings["dyn:ClientId"] = S2SProp.testClientId; 158 | ConfigurationManager.AppSettings["dyn:ClientSecret"] = "bullshit"; 159 | ConfigurationManager.AppSettings["dyn:Resource"] = S2SProp.testResource; 160 | ConfigurationManager.AppSettings["dyn:tenantId"] = S2SProp.testTenantId; 161 | 162 | var context = new CrmContext(); 163 | WhoAmITest(context); 164 | } 165 | 166 | [TestMethod] 167 | [ExpectedException(typeof(EndpointNotFoundException))] 168 | public void CrmContext_Default_InvalidResource_Throws() 169 | { 170 | ConfigurationManager.AppSettings["dyn:ClientId"] = S2SProp.testClientId; 171 | ConfigurationManager.AppSettings["dyn:ClientSecret"] = S2SProp.testClientSecret; 172 | ConfigurationManager.AppSettings["dyn:Resource"] = "https://thereisnowaythisexists.crm.dynamics.com"; 173 | ConfigurationManager.AppSettings["dyn:tenantId"] = S2SProp.testTenantId; 174 | 175 | var context = new CrmContext(); 176 | WhoAmITest(context); 177 | } 178 | 179 | [TestMethod] 180 | [ExpectedException(typeof(AdalServiceException))] 181 | public void CrmContext_Default_InvalidTenantId_Throws() 182 | { 183 | ConfigurationManager.AppSettings["dyn:ClientId"] = S2SProp.testClientId; 184 | ConfigurationManager.AppSettings["dyn:ClientSecret"] = S2SProp.testClientSecret; 185 | ConfigurationManager.AppSettings["dyn:Resource"] = S2SProp.testResource; 186 | ConfigurationManager.AppSettings["dyn:tenantId"] = Guid.NewGuid().ToString(); 187 | 188 | var context = new CrmContext(); 189 | WhoAmITest(context); 190 | } 191 | 192 | [TestMethod] 193 | [ExpectedException(typeof(ArgumentException))] 194 | public void CrmContext_Default_NullClientId_Throws() 195 | { 196 | ConfigurationManager.AppSettings["dyn:ClientId"] = null; 197 | ConfigurationManager.AppSettings["dyn:ClientSecret"] = S2SProp.testClientSecret; 198 | ConfigurationManager.AppSettings["dyn:Resource"] = S2SProp.testResource; 199 | ConfigurationManager.AppSettings["dyn:tenantId"] = S2SProp.testTenantId; 200 | 201 | var context = new CrmContext(); 202 | WhoAmITest(context); 203 | } 204 | 205 | [TestMethod] 206 | [ExpectedException(typeof(ArgumentNullException))] 207 | public void CrmContext_Default_NullClientSecret_Throws() 208 | { 209 | ConfigurationManager.AppSettings["dyn:ClientId"] = S2SProp.testClientId; 210 | ConfigurationManager.AppSettings["dyn:ClientSecret"] = null; 211 | ConfigurationManager.AppSettings["dyn:Resource"] = S2SProp.testResource; 212 | ConfigurationManager.AppSettings["dyn:tenantId"] = S2SProp.testTenantId; 213 | 214 | var context = new CrmContext(); 215 | WhoAmITest(context); 216 | } 217 | 218 | [TestMethod] 219 | [ExpectedException(typeof(UriFormatException))] 220 | public void CrmContext_Default_NullResource_Throws() 221 | { 222 | ConfigurationManager.AppSettings["dyn:ClientId"] = S2SProp.testClientId; 223 | ConfigurationManager.AppSettings["dyn:ClientSecret"] = S2SProp.testClientSecret; 224 | ConfigurationManager.AppSettings["dyn:Resource"] = null; 225 | ConfigurationManager.AppSettings["dyn:tenantId"] = S2SProp.testTenantId; 226 | 227 | var context = new CrmContext(); 228 | WhoAmITest(context); 229 | } 230 | 231 | [TestMethod] 232 | [ExpectedException(typeof(ArgumentException))] 233 | public void CrmContext_Default_NullTenantId_Throws() 234 | { 235 | ConfigurationManager.AppSettings["dyn:ClientId"] = S2SProp.testClientId; 236 | ConfigurationManager.AppSettings["dyn:ClientSecret"] = S2SProp.testClientSecret; 237 | ConfigurationManager.AppSettings["dyn:Resource"] = S2SProp.testResource; 238 | ConfigurationManager.AppSettings["dyn:tenantId"] = null; 239 | 240 | var context = new CrmContext(); 241 | WhoAmITest(context); 242 | } 243 | 244 | #region private test helpers 245 | 246 | private static void WhoAmITest(CrmContext context, bool clear = true) 247 | { 248 | try 249 | { 250 | var response = (WhoAmIResponse)context.WebProxyClient.Execute(new WhoAmIRequest()); 251 | 252 | Assert.IsNotNull(response); 253 | Assert.IsNotNull(response.UserId); 254 | Trace.TraceInformation($"WhoAmI UserId: {response.UserId}"); 255 | Assert.IsNotNull(response.BusinessUnitId); 256 | Trace.TraceInformation($"WhoAmI BusinessUnitId: {response.BusinessUnitId}"); 257 | Assert.IsNotNull(response.OrganizationId); 258 | Trace.TraceInformation($"WhoAmI OrganizationId: {response.OrganizationId}"); 259 | } 260 | finally 261 | { 262 | if (clear) 263 | { 264 | context.Dispose(); 265 | context.ResetAll(); 266 | } 267 | } 268 | } 269 | 270 | #endregion 271 | } 272 | } -------------------------------------------------------------------------------- /src/Adoxio.Dynamics.ConnectTests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Adoxio.Dynamics.ConnectTests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Adoxio.Dynamics.ConnectTests")] 13 | [assembly: AssemblyCopyright("Copyright © 2017")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("e86dccd3-98c2-441f-af78-20be7767ccf3")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/Adoxio.Dynamics.ConnectTests/S2SAppSettingsTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.VisualStudio.TestTools.UnitTesting; 3 | using Adoxio.Dynamics.Connect; 4 | 5 | namespace Adoxio.Dynamics.ConnectTests 6 | { 7 | [TestClass] 8 | public class S2SAppSettingsTests 9 | { 10 | [TestMethod] 11 | public void S2SAppSetting_Default_Test() 12 | { 13 | var setting = new S2SAppSettings() 14 | { 15 | ClientId = S2SProp.testClientId, 16 | ClientSecret = S2SProp.testClientSecret, 17 | Resource = S2SProp.testResource, 18 | TenantId = S2SProp.testTenantId 19 | }; 20 | 21 | Assert.IsNotNull(setting); 22 | } 23 | 24 | [TestMethod] 25 | public void S2SAppSetting_PropConstructor_Test() 26 | { 27 | var setting = new S2SAppSettings(S2SProp.testClientId, S2SProp.testClientSecret, S2SProp.testResource, S2SProp.testTenantId); 28 | 29 | Assert.IsNotNull(setting); 30 | } 31 | 32 | [TestMethod] 33 | [ExpectedException(typeof(ArgumentException))] 34 | public void S2SAppSetting_PropConstructor_NullClientId_Throws() 35 | { 36 | var setting = new S2SAppSettings(null, S2SProp.testClientSecret, S2SProp.testResource, S2SProp.testTenantId); 37 | } 38 | 39 | [TestMethod] 40 | [ExpectedException(typeof(ArgumentException))] 41 | public void S2SAppSetting_PropConstructor_NonGuidClientId_Throws() 42 | { 43 | var setting = new S2SAppSettings("asdf", S2SProp.testClientSecret, S2SProp.testResource, S2SProp.testTenantId); 44 | } 45 | 46 | [TestMethod] 47 | [ExpectedException(typeof(ArgumentNullException))] 48 | public void S2SAppSetting_PropConstructor_NullClientSecret_Throws() 49 | { 50 | var setting = new S2SAppSettings(S2SProp.testClientId, null, S2SProp.testResource, S2SProp.testTenantId); 51 | //setting.AssertAppSettings(); 52 | } 53 | 54 | [TestMethod] 55 | [ExpectedException(typeof(UriFormatException))] 56 | public void S2SAppSetting_PropConstructor_NullResource_Throws() 57 | { 58 | var setting = new S2SAppSettings(S2SProp.testClientId, S2SProp.testClientSecret, null, S2SProp.testTenantId); 59 | //setting.AssertAppSettings(); 60 | } 61 | 62 | [TestMethod] 63 | [ExpectedException(typeof(ArgumentException))] 64 | public void S2SAppSetting_PropConstructor_NullTenantId_Throws() 65 | { 66 | var setting = new S2SAppSettings(S2SProp.testClientId, S2SProp.testClientSecret, S2SProp.testResource, null); 67 | //setting.AssertAppSettings(); 68 | } 69 | 70 | [TestMethod] 71 | [ExpectedException(typeof(ArgumentException))] 72 | public void S2SAppSetting_PropConstructor_NonGuidTenantId_Throws() 73 | { 74 | var setting = new S2SAppSettings(S2SProp.testClientId, S2SProp.testClientSecret, S2SProp.testResource, "asdf"); 75 | //setting.AssertAppSettings(); 76 | } 77 | 78 | 79 | [TestMethod] 80 | public void S2SAppSetting_EqualsTrue_Test() 81 | { 82 | var setting = new S2SAppSettings(S2SProp.testClientId, S2SProp.testClientSecret, S2SProp.testResource, S2SProp.testTenantId); 83 | 84 | Assert.IsTrue(setting.Equals(setting)); 85 | } 86 | 87 | [TestMethod] 88 | public void S2SAppSetting_EqualsFalseClientId_Test() 89 | { 90 | var setting = new S2SAppSettings(S2SProp.testClientId, S2SProp.testClientSecret, S2SProp.testResource, S2SProp.testTenantId); 91 | var setting2 = new S2SAppSettings(Guid.NewGuid().ToString(), S2SProp.testClientSecret, S2SProp.testResource, S2SProp.testTenantId); 92 | 93 | Assert.IsFalse(setting.Equals(setting2)); 94 | } 95 | 96 | [TestMethod] 97 | public void S2SAppSetting_EqualsFalseClientSecret_Test() 98 | { 99 | var setting = new S2SAppSettings(S2SProp.testClientId, S2SProp.testClientSecret, S2SProp.testResource, S2SProp.testTenantId); 100 | var setting2 = new S2SAppSettings(Guid.NewGuid().ToString(), "bullshit", S2SProp.testResource, S2SProp.testTenantId); 101 | 102 | Assert.IsFalse(setting.Equals(setting2)); 103 | } 104 | 105 | [TestMethod] 106 | public void S2SAppSetting_EqualsFalseResource_Test() 107 | { 108 | var setting = new S2SAppSettings(S2SProp.testClientId, S2SProp.testClientSecret, S2SProp.testResource, S2SProp.testTenantId); 109 | var setting2 = new S2SAppSettings(Guid.NewGuid().ToString(), S2SProp.testClientSecret, "https://thereisnowaythisexists.crm.dynamics.com", S2SProp.testTenantId); 110 | 111 | Assert.IsFalse(setting.Equals(setting2)); 112 | } 113 | 114 | [TestMethod] 115 | public void S2SAppSetting_EqualsFalseTenantId_Test() 116 | { 117 | var setting = new S2SAppSettings(S2SProp.testClientId, S2SProp.testClientSecret, S2SProp.testResource, S2SProp.testTenantId); 118 | var setting2 = new S2SAppSettings(S2SProp.testClientId, S2SProp.testClientSecret, S2SProp.testResource, Guid.NewGuid().ToString()); 119 | 120 | Assert.IsFalse(setting.Equals(setting2)); 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/Adoxio.Dynamics.ConnectTests/S2SProp.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Adoxio.Dynamics.ConnectTests 8 | { 9 | public static class S2SProp 10 | { 11 | public static string testClientId = "--ClientId--"; 12 | public static string testClientSecret = "--ClientSecret--"; 13 | public static string testResource = "https://*.crm.dynamics.com"; 14 | public static string testTenantId = "--TenantId--"; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Adoxio.Dynamics.ConnectTests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | --------------------------------------------------------------------------------