├── CSScript
├── Global.asax
├── Metadata
│ └── deploymentTemplates
│ │ └── apiappconfig.azureresource.json
├── apiapp.json
├── Global.asax.cs
├── App_Start
│ ├── WebApiConfig.cs
│ └── SwaggerConfig.cs
├── packages.config
├── Web.Debug.config
├── Web.Release.config
├── Properties
│ └── AssemblyInfo.cs
├── Web.config
├── Controllers
│ └── CompileController.cs
└── CSScript.csproj
├── CSScript.sln
├── LICENSE
├── .gitattributes
├── README.md
├── .gitignore
└── azuredeploy.json
/CSScript/Global.asax:
--------------------------------------------------------------------------------
1 | <%@ Application Codebehind="Global.asax.cs" Inherits="CSScript.WebApiApplication" Language="C#" %>
2 |
--------------------------------------------------------------------------------
/CSScript/Metadata/deploymentTemplates/apiappconfig.azureresource.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://schemas.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#",
3 | "contentVersion": "1.0.0.0",
4 | "parameters": {
5 | "$system": {
6 | "type": "Object"
7 | }
8 | },
9 | "resources": []
10 | }
--------------------------------------------------------------------------------
/CSScript/apiapp.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://json-schema.org/schemas/2014-11-01/apiapp.json#",
3 | "id": "CSharpAPI",
4 | "namespace": "logicappsio.com",
5 | "gateway": "2015-01-14",
6 | "version": "1.0.0",
7 | "title": "CSharp API",
8 | "summary": "Compiles C# Scripts",
9 | "author": "Jeff Hollan",
10 | "endpoints": {
11 | "apiDefinition": "/swagger/docs/v1",
12 | "status": null
13 | }
14 | }
--------------------------------------------------------------------------------
/CSScript/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.Routing;
7 |
8 | namespace CSScript
9 | {
10 | public class WebApiApplication : System.Web.HttpApplication
11 | {
12 | protected void Application_Start()
13 | {
14 | GlobalConfiguration.Configure(WebApiConfig.Register);
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/CSScript/App_Start/WebApiConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Web.Http;
5 |
6 | namespace CSScript
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: "CSScriptAPI",
19 | routeTemplate: "api/{controller}/{action}",
20 | defaults: new { id = RouteParameter.Optional }
21 | );
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/CSScript.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.22823.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSScript", "CSScript\CSScript.csproj", "{8DAA99D2-C633-44F4-AFFF-A2C571FCF5FF}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {8DAA99D2-C633-44F4-AFFF-A2C571FCF5FF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {8DAA99D2-C633-44F4-AFFF-A2C571FCF5FF}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {8DAA99D2-C633-44F4-AFFF-A2C571FCF5FF}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {8DAA99D2-C633-44F4-AFFF-A2C571FCF5FF}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | EndGlobal
23 |
--------------------------------------------------------------------------------
/CSScript/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Azure Logic Apps
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 all
13 | 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 THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/CSScript/Web.Debug.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
17 |
18 |
29 |
30 |
--------------------------------------------------------------------------------
/CSScript/Web.Release.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
17 |
18 |
19 |
30 |
31 |
--------------------------------------------------------------------------------
/CSScript/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("CSScript")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("CSScript")]
13 | [assembly: AssemblyCopyright("Copyright © 2015")]
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("8daa99d2-c633-44f4-afff-a2c571fcf5ff")]
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 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | ###############################################################################
2 | # Set default behavior to automatically normalize line endings.
3 | ###############################################################################
4 | * text=auto
5 |
6 | ###############################################################################
7 | # Set default behavior for command prompt diff.
8 | #
9 | # This is need for earlier builds of msysgit that does not have it on by
10 | # default for csharp files.
11 | # Note: This is only used by command line
12 | ###############################################################################
13 | #*.cs diff=csharp
14 |
15 | ###############################################################################
16 | # Set the merge driver for project and solution files
17 | #
18 | # Merging from the command prompt will add diff markers to the files if there
19 | # are conflicts (Merging from VS is not affected by the settings below, in VS
20 | # the diff markers are never inserted). Diff markers may cause the following
21 | # file extensions to fail to load in VS. An alternative would be to treat
22 | # these files as binary and thus will always conflict and require user
23 | # intervention with every merge. To do so, just uncomment the entries below
24 | ###############################################################################
25 | #*.sln merge=binary
26 | #*.csproj merge=binary
27 | #*.vbproj merge=binary
28 | #*.vcxproj merge=binary
29 | #*.vcproj merge=binary
30 | #*.dbproj merge=binary
31 | #*.fsproj merge=binary
32 | #*.lsproj merge=binary
33 | #*.wixproj merge=binary
34 | #*.modelproj merge=binary
35 | #*.sqlproj merge=binary
36 | #*.wwaproj merge=binary
37 |
38 | ###############################################################################
39 | # behavior for image files
40 | #
41 | # image files are treated as binary by default.
42 | ###############################################################################
43 | #*.jpg binary
44 | #*.png binary
45 | #*.gif binary
46 |
47 | ###############################################################################
48 | # diff behavior for common document formats
49 | #
50 | # Convert binary document formats to text before diffing them. This feature
51 | # is only available from the command line. Turn it on by uncommenting the
52 | # entries below.
53 | ###############################################################################
54 | #*.doc diff=astextplain
55 | #*.DOC diff=astextplain
56 | #*.docx diff=astextplain
57 | #*.DOCX diff=astextplain
58 | #*.dot diff=astextplain
59 | #*.DOT diff=astextplain
60 | #*.pdf diff=astextplain
61 | #*.PDF diff=astextplain
62 | #*.rtf diff=astextplain
63 | #*.RTF diff=astextplain
64 |
--------------------------------------------------------------------------------
/CSScript/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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # C# Scripting API
2 | [](https://azuredeploy.net/)
3 |
4 | ## Deploying ##
5 | Click the "Deploy to Azure" button above. You can create new resources or reference existing ones (resource group, gateway, service plan, etc.) **Site Name and Gateway must be unique URL hostnames.** The deployment script will deploy the following:
6 | * Resource Group (optional)
7 | * Service Plan (if you don't reference exisiting one)
8 | * Gateway (if you don't reference existing one)
9 | * API App (CSharpAPI)
10 | * API App Host (this is the site behind the api app that this github code deploys to)
11 |
12 | ## API Documentation ##
13 | The API app has one action - Execute Script - which returns a JToken based on what the script returns.
14 |
15 | The action has three input parameters:
16 |
17 | | Input | Description |
18 | | ----- | ----- |
19 | | Script | C# script syntax |
20 | | Context Object *(optional)* | Objects to reference in the script. Can pass in multiple objects, but base must be a single JObject { .. }. Can be accessed in script by object key (as a JToken). |
21 | | Libraries *(optional)* | Array of libraries to pass in and compile with script. Works from Blob/FTP Connector output of .dll files. See structure [below](#libraries-array-structure). Default libraries can be found [here](#compiler-information) |
22 |
23 | #### Context Object Structure ####
24 | ```javascript
25 | { "object1": { ... }, "object2": "value" }
26 | ```
27 | In script could then reference object1 and object2 - both passed in as a JToken.
28 |
29 | #### Libraries Array Structure ####
30 | ```javascript
31 | [{"filename": "name.dll", "assembly": {Base64StringFromConnector}, "usingstatment": "using Library.Reference;"}, { ... } ]
32 | ```
33 |
34 | ####AppDomain ####
35 |
36 | The script executes inside of an AppDomain that includes some standard System assemblies as well as Newtonsoft.Json. The full list can be found [here](#compiler-information)
37 |
38 | ###Trigger###
39 | You can use the C# Script API as a trigger. It takes a single input of "script" and will trigger the logic app (and pass result) whenever the script returns anything but `false`. You set the frequency in which the script runs.
40 |
41 | ## Example ##
42 | | Step | Info |
43 | |----|----|
44 | | Action | Execute Script |
45 | | C# Script | `return message;` |
46 | | Context Object | `{"message": {"Hello": "World"}}` |
47 | | Output | `{"Hello": "World"}` |
48 |
49 | You can also perform more complex scripts like the following:
50 | ####Context Object####
51 | ```javascript
52 | { "tax": 0.06, "orders": [{"order": "order1", "subtotal": 100}] }
53 | ```
54 | #### C\# Script ####
55 | ```csharp
56 | foreach (var order in orders)
57 | {
58 | order["total"] = (double)order["subtotal"] * (1 + (double)tax);
59 | }
60 | return orders;
61 | ```
62 |
63 | #### Result ####
64 | ```javascript
65 | [ {"order": "order1", "subtotal": 100, "total": 106.0 } ]
66 | ```
67 |
68 | ## Compiler Information ##
69 |
70 | The following assemblies are included by default in the script:
71 |
72 | ```csharp
73 | using System;
74 | using Newtonsoft.Json;
75 | using Newtonsoft.Json.Linq;
76 | using System.Linq;
77 | using System.Collections.Generic;
78 | using System.Net;
79 | using System.Net.Http;
80 | using System.Xml;
81 | ```
82 |
83 |
--------------------------------------------------------------------------------
/.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 | PublishProfiles/
14 |
15 | # Build results
16 | [Dd]ebug/
17 | [Dd]ebugPublic/
18 | [Rr]elease/
19 | [Rr]eleases/
20 | x64/
21 | x86/
22 | build/
23 | bld/
24 | [Bb]in/
25 | [Oo]bj/
26 |
27 | # Visual Studio 2015 cache/options directory
28 | .vs/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | artifacts/
46 |
47 | *_i.c
48 | *_p.c
49 | *_i.h
50 | *.ilk
51 | *.meta
52 | *.obj
53 | *.pch
54 | *.pdb
55 | *.pgc
56 | *.pgd
57 | *.rsp
58 | *.sbr
59 | *.tlb
60 | *.tli
61 | *.tlh
62 | *.tmp
63 | *.tmp_proj
64 | *.log
65 | *.vspscc
66 | *.vssscc
67 | .builds
68 | *.pidb
69 | *.svclog
70 | *.scc
71 |
72 | # Chutzpah Test files
73 | _Chutzpah*
74 |
75 | # Visual C++ cache files
76 | ipch/
77 | *.aps
78 | *.ncb
79 | *.opensdf
80 | *.sdf
81 | *.cachefile
82 |
83 | # Visual Studio profiler
84 | *.psess
85 | *.vsp
86 | *.vspx
87 |
88 | # TFS 2012 Local Workspace
89 | $tf/
90 |
91 | # Guidance Automation Toolkit
92 | *.gpState
93 |
94 | # ReSharper is a .NET coding add-in
95 | _ReSharper*/
96 | *.[Rr]e[Ss]harper
97 | *.DotSettings.user
98 |
99 | # JustCode is a .NET coding add-in
100 | .JustCode
101 |
102 | # TeamCity is a build add-in
103 | _TeamCity*
104 |
105 | # DotCover is a Code Coverage Tool
106 | *.dotCover
107 |
108 | # NCrunch
109 | _NCrunch_*
110 | .*crunch*.local.xml
111 |
112 | # MightyMoose
113 | *.mm.*
114 | AutoTest.Net/
115 |
116 | # Web workbench (sass)
117 | .sass-cache/
118 |
119 | # Installshield output folder
120 | [Ee]xpress/
121 |
122 | # Publish Profiles
123 | Properties/PublishProfiles
124 | # DocProject is a documentation generator add-in
125 | DocProject/buildhelp/
126 | DocProject/Help/*.HxT
127 | DocProject/Help/*.HxC
128 | DocProject/Help/*.hhc
129 | DocProject/Help/*.hhk
130 | DocProject/Help/*.hhp
131 | DocProject/Help/Html2
132 | DocProject/Help/html
133 |
134 | # Click-Once directory
135 | publish/
136 |
137 | # Publish Web Output
138 | *.[Pp]ublish.xml
139 | *.azurePubxml
140 | ## TODO: Comment the next line if you want to checkin your
141 | ## web deploy settings but do note that will include unencrypted
142 | ## passwords
143 | #*.pubxml
144 |
145 | *.publishproj
146 |
147 | # NuGet Packages
148 | *.nupkg
149 | # The packages folder can be ignored because of Package Restore
150 | **/packages/*
151 | # except build/, which is used as an MSBuild target.
152 | !**/packages/build/
153 | # Uncomment if necessary however generally it will be regenerated when needed
154 | #!**/packages/repositories.config
155 |
156 | # Windows Azure Build Output
157 | csx/
158 | *.build.csdef
159 |
160 | # Windows Store app package directory
161 | AppPackages/
162 |
163 | # Visual Studio cache files
164 | # files ending in .cache can be ignored
165 | *.[Cc]ache
166 | # but keep track of directories ending in .cache
167 | !*.[Cc]ache/
168 |
169 | # Others
170 | ClientBin/
171 | [Ss]tyle[Cc]op.*
172 | ~$*
173 | *~
174 | *.dbmdl
175 | *.dbproj.schemaview
176 | *.pfx
177 | *.publishsettings
178 | node_modules/
179 | orleans.codegen.cs
180 |
181 | # RIA/Silverlight projects
182 | Generated_Code/
183 |
184 | # Backup & report files from converting an old project file
185 | # to a newer Visual Studio version. Backup files are not needed,
186 | # because we have git ;-)
187 | _UpgradeReport_Files/
188 | Backup*/
189 | UpgradeLog*.XML
190 | UpgradeLog*.htm
191 |
192 | # SQL Server files
193 | *.mdf
194 | *.ldf
195 |
196 | # Business Intelligence projects
197 | *.rdl.data
198 | *.bim.layout
199 | *.bim_*.settings
200 |
201 | # Microsoft Fakes
202 | FakesAssemblies/
203 |
204 | # Node.js Tools for Visual Studio
205 | .ntvs_analysis.dat
206 |
207 | # Visual Studio 6 build log
208 | *.plg
209 |
210 | # Visual Studio 6 workspace options file
211 | *.opt
212 |
213 | # LightSwitch generated files
214 | GeneratedArtifacts/
215 | _Pvt_Extensions/
216 | ModelManifest.xml
217 |
--------------------------------------------------------------------------------
/CSScript/Controllers/CompileController.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Reflection;
5 | using System.CodeDom.Compiler;
6 | using System.Web.Http;
7 | using Newtonsoft.Json.Linq;
8 | using TRex.Metadata;
9 | using System.Net.Http;
10 | using Microsoft.Azure.AppService.ApiApps.Service;
11 | using System.Diagnostics;
12 | using System.Collections.ObjectModel;
13 | using System.Web;
14 | using System.IO;
15 |
16 | namespace CSScript.Controllers
17 | {
18 | public class CompileController : ApiController
19 | {
20 | private bool compiled;
21 | //The imports that will be included when executing the script. Must be System or Newtonsoft (or you would need to change where the assemblies are referenced to include more)
22 | private const string scriptIncludes = @"
23 | using System;
24 | using Newtonsoft.Json;
25 | using Newtonsoft.Json.Linq;
26 | using System.Linq;
27 | using System.Collections.Generic;
28 | using System.Net;
29 | using System.Net.Http;
30 | using System.Xml;";
31 |
32 | List args;
33 |
34 | private string contextTokens = "";
35 |
36 | [HttpPost]
37 | [Metadata(friendlyName: "Execute Script")]
38 | public JToken Execute([FromBody] Body body)
39 | {
40 | if (body.context != null)
41 | GenerateArgs(body.context);
42 |
43 | if (body.libraries != null)
44 | readAttachments(body.libraries);
45 | var result = (JToken)RunScript(body.script, "JToken", body.libraries);
46 | if (compiled)
47 | return result;
48 | else
49 | {
50 | var resp = new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest)
51 | {
52 | Content = new StringContent(result.ToString()),
53 | ReasonPhrase = "Compiler Error"
54 | };
55 | throw new HttpResponseException(resp);
56 | }
57 |
58 | }
59 |
60 |
61 | [HttpGet]
62 | [Metadata(friendlyName: "Execute Script Trigger", description: "When the script returns anything but false, the Logic App will fire")]
63 | [Trigger(TriggerType.Poll)]
64 | public HttpResponseMessage ExecutePollTrigger([FromUri] string script)
65 | {
66 |
67 | JToken result = RunScript(script, "JToken", null);
68 | Debug.WriteLine(result.ToString());
69 | if (result.ToString() == "False")
70 | return Request.EventWaitPoll();
71 | else if (compiled)
72 | return Request.EventTriggered(result);
73 | else
74 | return Request.CreateErrorResponse(System.Net.HttpStatusCode.BadRequest, result.ToString());
75 | }
76 |
77 | ///
78 | /// Generates variables within the script matching to the Key/Values of the context object
79 | ///
80 | /// JSON Context passed through
81 | private void GenerateArgs(JObject json)
82 | {
83 | args = new List();
84 | foreach(var param in json)
85 | {
86 | contextTokens += "JToken " + param.Key +", ";
87 | args.Add(param.Value);
88 | }
89 | contextTokens = contextTokens.Remove(contextTokens.Length - 2, 2);
90 | }
91 | private JToken RunScript(string input, string type, Collection libraries)
92 | {
93 | compiled = false;
94 | var sourceCode = scriptIncludes + "namespace Script { public class ScriptClass { public " + type + " RunScript(" + contextTokens + ") { " + input + " } } }";
95 |
96 | // Get a reference to the CSharp code provider
97 | using (var codeDomProvider = CodeDomProvider.CreateProvider("csharp"))
98 | {
99 | // Set compile options (we want to compile in memory)
100 | var compileParameters = new CompilerParameters() { GenerateInMemory = true };
101 | compileParameters.GenerateExecutable = false;
102 |
103 | //Include library references, only when library contains System or Newtonsoft
104 | foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
105 | {
106 | if (!asm.IsDynamic && ( asm.FullName.Contains("System") || asm.FullName.Contains("Newtonsoft")))
107 | compileParameters.ReferencedAssemblies.Add(asm.Location);
108 | }
109 | if (libraries != null)
110 | {
111 | foreach (var attachment in libraries)
112 | {
113 | compileParameters.ReferencedAssemblies.Add(HttpRuntime.AppDomainAppPath + @"\" + attachment.filename);
114 | sourceCode = attachment.usingstatement + sourceCode;
115 | }
116 | }
117 |
118 | // Now compile the supplied source code and compile it.
119 | var compileResult = codeDomProvider.CompileAssemblyFromSource(compileParameters, sourceCode);
120 |
121 | if (libraries != null)
122 | {
123 | foreach (var attachment in libraries)
124 | {
125 | File.Delete(HttpRuntime.AppDomainAppPath + @"\" + attachment.filename);
126 | }
127 | }
128 |
129 | // Check for compile errors
130 | if (compileResult.Errors.Count > 0)
131 | {
132 | var errorArray = new JArray();
133 | foreach (var error in compileResult.Errors)
134 | {
135 | errorArray.Add(error.ToString());
136 | }
137 | return errorArray;
138 | }
139 | // If everything goes well we get a reference to the compiled assembly.
140 | var compiledAssembly = compileResult.CompiledAssembly;
141 |
142 | // Now, using reflection we can create an instance of our class
143 | var inst = compiledAssembly.CreateInstance("Script.ScriptClass");
144 | // ... and call a method on it!
145 | object callResult;
146 | if(args != null)
147 | callResult = inst.GetType().InvokeMember("RunScript", BindingFlags.InvokeMethod, null, inst, args.ToArray());
148 | else
149 | callResult = inst.GetType().InvokeMember("RunScript", BindingFlags.InvokeMethod, null, inst, null);
150 | compiled = true;
151 |
152 |
153 | return (JToken)callResult;
154 | }
155 | }
156 |
157 | ///
158 | /// Loop through the attachements write the .dll from the Base64String
159 | ///
160 | /// Array of libraries
161 | private void readAttachments(Collection libraries)
162 | {
163 | foreach (var library in libraries)
164 | {
165 | var file = System.Convert.FromBase64String(library.assembly);
166 | File.WriteAllBytes(HttpRuntime.AppDomainAppPath + @"\" + library.filename, file);
167 | }
168 | }
169 |
170 |
171 | public class Body
172 | {
173 | [Metadata(friendlyName:"C# Script", Visibility = VisibilityType.Default)]
174 | public string script { get; set; }
175 |
176 | [Metadata(friendlyName: "Context Object(s)", description: "JSON Object(s) to be passed into script argument. Can pass in multiple items, but base object must be single object { .. }. Can be referenced in scripted as object names")]
177 | public JObject context {get; set;}
178 |
179 | [Metadata(friendlyName: "Libraries", description: "Libraries to be included in execution of script. Array of this format [{\"filename\": , \"assembly\": , \"usingstatement\": }, ..]", Visibility = VisibilityType.Advanced)]
180 | public Collection libraries { get; set; }
181 |
182 |
183 | }
184 |
185 | public class Library
186 | {
187 | public string filename;
188 | public string assembly;
189 | public string usingstatement;
190 | }
191 |
192 | }
193 |
194 |
195 | }
196 |
--------------------------------------------------------------------------------
/azuredeploy.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
3 | "contentVersion": "1.0.0.0",
4 | "parameters": {
5 | "siteName": {
6 | "type": "string"
7 | },
8 | "apiAppName": {
9 | "type": "string",
10 | "defaultValue": "CSharpAPI"
11 | },
12 | "gatewayName": {
13 | "type": "string"
14 | },
15 | "repoURL": {
16 | "type": "string"
17 | },
18 | "branch": {
19 | "type": "string"
20 | },
21 | "svcPlanName": {
22 | "type": "string"
23 | },
24 | "sku": {
25 | "type": "string",
26 | "defaultValue": "Standard",
27 | "allowedValues": [
28 | "Free",
29 | "Basic",
30 | "Standard",
31 | "Premium"
32 | ]
33 | },
34 | "svcPlanSize": {
35 | "defaultValue": "0",
36 | "type": "string",
37 | "allowedValues": [
38 | "0",
39 | "1",
40 | "2"
41 | ]
42 | },
43 | "gatewayToApiAppSecret": {
44 | "defaultValue": "Y3NzY3JpcHRpbmdhcGk=",
45 | "type": "securestring"
46 | }
47 | },
48 | "variables": {
49 | "$packageId": "Microsoft.ApiApp",
50 | "$nugetFeed": "http://apiapps-preview.nuget.org/api/v2/"
51 | },
52 | "resources": [
53 | {
54 | "type": "Microsoft.Web/serverfarms",
55 | "apiVersion": "2015-04-01",
56 | "name": "[parameters('svcPlanName')]",
57 | "location": "[resourceGroup().location]",
58 | "tags": {
59 | "displayName": "AppServicePlan"
60 | },
61 | "properties": {
62 | "name": "[parameters('svcPlanName')]",
63 | "sku": "[parameters('sku')]",
64 | "workerSize": "[parameters('svcPlanSize')]",
65 | "numberOfWorkers": 1
66 | }
67 | },
68 | {
69 | "type": "Microsoft.Web/sites",
70 | "apiVersion": "2015-04-01",
71 | "name": "[parameters('gatewayName')]",
72 | "location": "[resourceGroup().location]",
73 | "kind": "gateway",
74 | "tags": {
75 | "displayName": "GatewayHost"
76 | },
77 | "resources": [
78 | {
79 | "type": "providers/links",
80 | "apiVersion": "2015-01-01",
81 | "name": "Microsoft.Resources/gateway",
82 | "dependsOn": [
83 | "[resourceId('Microsoft.Web/sites',parameters('gatewayName'))]"
84 | ],
85 | "properties": {
86 | "targetId": "[resourceId('Microsoft.AppService/gateways', parameters('gatewayName'))]"
87 | }
88 | }
89 | ],
90 | "dependsOn": [
91 | "[concat(resourceGroup().id, '/providers/Microsoft.Web/serverfarms/',parameters('svcPlanName'))]"
92 | ],
93 | "properties": {
94 | "name": "[parameters('gatewayName')]",
95 | "gatewaySiteName": "[parameters('gatewayName')]",
96 | "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('svcPlanName'))]",
97 | "siteConfig": {
98 | "appSettings": [
99 | {
100 | "name": "ApiAppsGateway_EXTENSION_VERSION",
101 | "value": "latest"
102 | },
103 | {
104 | "name": "EmaStorage",
105 | "value": "D:\\home\\data\\apiapps"
106 | },
107 | {
108 | "name": "WEBSITE_START_SCM_ON_SITE_CREATION",
109 | "value": "1"
110 | }
111 | ]
112 | }
113 | }
114 | },
115 | {
116 | "type": "Microsoft.AppService/gateways",
117 | "apiVersion": "2015-03-01-preview",
118 | "name": "[parameters('gatewayName')]",
119 | "location": "[resourceGroup().location]",
120 | "tags": {
121 | "displayName": "Gateway"
122 | },
123 | "resources": [
124 | {
125 | "type": "providers/links",
126 | "apiVersion": "2015-01-01",
127 | "name": "Microsoft.Resources/gatewaySite",
128 | "dependsOn": [
129 | "[resourceId('Microsoft.AppService/gateways',parameters('gatewayName'))]"
130 | ],
131 | "properties": {
132 | "targetId": "[resourceId('Microsoft.Web/sites',parameters('gatewayName'))]"
133 | }
134 | },
135 | {
136 | "type": "tokens",
137 | "apiVersion": "2015-03-01-preview",
138 | "location": "[resourceGroup().location]",
139 | "name": "[parameters('apiAppName')]",
140 | "tags": {
141 | "displayName": "AuthenticationToken"
142 | },
143 | "dependsOn": [
144 | "[resourceId('Microsoft.AppService/gateways', parameters('gatewayName'))]"
145 | ]
146 | }
147 |
148 | ],
149 | "dependsOn": [
150 | "[resourceId('Microsoft.Web/sites', parameters('gatewayName'))]"
151 | ],
152 | "properties": {
153 | "host": {
154 | "resourceName": "[parameters('gatewayName')]"
155 | }
156 | }
157 | },
158 | {
159 | "type": "Microsoft.Web/sites",
160 | "apiVersion": "2015-04-01",
161 |
162 | "name": "[parameters('siteName')]",
163 | "location": "[resourceGroup().location]",
164 | "kind": "apiApp",
165 | "tags": {
166 | "displayName": "APIAppHost"
167 | },
168 | "dependsOn": [
169 | "[resourceId('Microsoft.AppService/gateways', parameters('gatewayName'))]"
170 | ],
171 | "resources": [
172 | {
173 | "type": "siteextensions",
174 | "tags": {
175 | "displayName": "APIAppExtension"
176 | },
177 | "apiVersion": "2015-04-01",
178 | "name": "[variables('$packageId')]",
179 | "dependsOn": [
180 |
181 | "[resourceId('Microsoft.Web/sites', parameters('siteName'))]"
182 | ],
183 | "properties": {
184 | "type": "WebRoot",
185 | "feed_url": "[variables('$nugetFeed')]"
186 | }
187 | },
188 | {
189 | "type": "providers/links",
190 | "apiVersion": "2015-01-01",
191 | "name": "Microsoft.Resources/apiApp",
192 | "dependsOn": [
193 | "[resourceId('Microsoft.Web/sites', parameters('siteName'))]"
194 | ],
195 | "properties": {
196 | "targetId": "[resourceId('Microsoft.AppService/apiapps', parameters('apiAppName'))]"
197 | }
198 | },
199 |
200 | {
201 | "apiVersion": "2015-04-01",
202 | "name": "web",
203 | "type": "sourcecontrols",
204 | "dependsOn": [
205 | "[resourceId('Microsoft.Web/Sites', parameters('siteName'))]"
206 | ],
207 | "properties": {
208 | "RepoUrl": "[parameters('repoURL')]",
209 | "branch": "[parameters('branch')]",
210 | "IsManualIntegration": true
211 | }
212 | }
213 |
214 |
215 | ],
216 | "properties": {
217 | "name": "[parameters('siteName')]",
218 | "gatewaySiteName": "[parameters('gatewayName')]",
219 | "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('svcPlanName'))]",
220 | "siteConfig": {
221 | "appSettings": [
222 | {
223 | "name": "EMA_MicroserviceId",
224 | "value": "[parameters('apiAppName')]"
225 | },
226 | {
227 | "name": "EMA_Secret",
228 | "value": "[parameters('gatewayToAPIappSecret')]"
229 | },
230 | {
231 | "name": "EMA_RuntimeUrl",
232 | "value": "[concat('https://', reference(resourceId('Microsoft.Web/sites', parameters('gatewayName'))).hostNames[0])]"
233 | },
234 | {
235 | "name": "WEBSITE_START_SCM_ON_SITE_CREATION",
236 | "value": "1"
237 | }
238 | ]
239 | }
240 | }
241 | },
242 | {
243 | "type": "Microsoft.AppService/apiapps",
244 | "apiVersion": "2015-03-01-preview",
245 | "name": "[parameters('apiAppName')]",
246 | "location": "[resourceGroup().location]",
247 | "tags": {
248 | "displayName": "APIApp"
249 | },
250 | "resources": [
251 | {
252 | "type": "providers/links",
253 | "apiVersion": "2015-01-01",
254 | "name": "Microsoft.Resources/apiAppSite",
255 | "dependsOn": [
256 | "[resourceId('Microsoft.AppService/apiapps', parameters('apiAppName'))]"
257 | ],
258 | "properties": {
259 |
260 | "targetId": "[resourceId('Microsoft.Web/sites', parameters('siteName'))]"
261 | }
262 | }
263 | ],
264 | "dependsOn": [
265 |
266 | "[resourceId('Microsoft.Web/sites/siteextensions', parameters('siteName'), 'Microsoft.ApiApp')]"
267 | ],
268 | "properties": {
269 | "package": {
270 | "id": "Microsoft.ApiApp"
271 | },
272 | "accessLevel" : "PublicAnonymous",
273 | "host": {
274 |
275 | "resourceName": "[parameters('siteName')]"
276 | },
277 | "gateway": {
278 | "resourceName": "[parameters('gatewayName')]"
279 | },
280 | "dependencies": [ ]
281 | }
282 | }
283 |
284 | ]
285 | }
286 |
--------------------------------------------------------------------------------
/CSScript/CSScript.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 |
8 |
9 | 2.0
10 | {8DAA99D2-C633-44F4-AFFF-A2C571FCF5FF}
11 | {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
12 | Library
13 | Properties
14 | CSScript
15 | CSScript
16 | v4.5.2
17 | true
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | /subscriptions/80d4fe69-c95b-4dd2-a938-9250f1c8ab03/resourcegroups/Default-ApplicationInsights-CentralUS/providers/microsoft.insights/components/WebApplication2
26 |
27 |
28 | true
29 | full
30 | false
31 | bin\
32 | DEBUG;TRACE
33 | prompt
34 | 4
35 |
36 |
37 | pdbonly
38 | true
39 | bin\
40 | TRACE
41 | prompt
42 | 4
43 |
44 |
45 |
46 | ..\packages\Microsoft.Azure.AppService.ApiApps.Service.0.9.64\lib\net45\Microsoft.Azure.AppService.ApiApps.Service.dll
47 | True
48 |
49 |
50 |
51 | ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll
52 | True
53 |
54 |
55 | ..\packages\Newtonsoft.Json.7.0.1\lib\net45\Newtonsoft.Json.dll
56 | True
57 |
58 |
59 | ..\packages\Swashbuckle.Core.5.2.1\lib\net40\Swashbuckle.Core.dll
60 | True
61 |
62 |
63 | ..\packages\System.IdentityModel.Tokens.Jwt.4.0.2.206221351\lib\net45\System.IdentityModel.Tokens.Jwt.dll
64 | True
65 |
66 |
67 |
68 | ..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll
69 | True
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 | ..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll
82 | True
83 |
84 |
85 | ..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll
86 | True
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 | ..\packages\TRex.0.1.4.0\lib\net45\TRex.Metadata.dll
97 | True
98 |
99 |
100 | ..\packages\WebActivatorEx.2.0.6\lib\net40\WebActivatorEx.dll
101 | True
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 | Global.asax
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 | Web.config
123 |
124 |
125 | Web.config
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 | 10.0
138 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 | True
148 | True
149 | 54281
150 | /
151 | http://localhost:54281/
152 | False
153 | False
154 |
155 |
156 | False
157 |
158 |
159 |
160 |
161 |
162 |
163 | 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}.
164 |
165 |
166 |
173 |
--------------------------------------------------------------------------------
/CSScript/App_Start/SwaggerConfig.cs:
--------------------------------------------------------------------------------
1 | using System.Web.Http;
2 | using WebActivatorEx;
3 | using CSScript;
4 | using Swashbuckle.Application;
5 | using TRex.Metadata;
6 | using Swashbuckle.Swagger;
7 | using System;
8 | using System.Web.Http.Description;
9 |
10 | [assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")]
11 |
12 | namespace CSScript
13 | {
14 | public class SwaggerConfig
15 | {
16 | public static void Register()
17 | {
18 | var thisAssembly = typeof(SwaggerConfig).Assembly;
19 |
20 | GlobalConfiguration.Configuration
21 | .EnableSwagger(c =>
22 | {
23 | // By default, the service root url is inferred from the request used to access the docs.
24 | // However, there may be situations (e.g. proxy and load-balanced environments) where this does not
25 | // resolve correctly. You can workaround this by providing your own code to determine the root URL.
26 | //
27 | //c.RootUrl(req => GetRootUrlFromAppConfig());
28 |
29 | // If schemes are not explicitly provided in a Swagger 2.0 document, then the scheme used to access
30 | // the docs is taken as the default. If your API supports multiple schemes and you want to be explicit
31 | // about them, you can use the "Schemes" option as shown below.
32 | //
33 | //c.Schemes(new[] { "http", "https" });
34 |
35 | // Use "SingleApiVersion" to describe a single version API. Swagger 2.0 includes an "Info" object to
36 | // hold additional metadata for an API. Version and title are required but you can also provide
37 | // additional fields by chaining methods off SingleApiVersion.
38 | //
39 | c.SingleApiVersion("v1", "CSScript");
40 | c.ReleaseTheTRex();
41 | c.DocumentFilter();
42 |
43 | // If your API has multiple versions, use "MultipleApiVersions" instead of "SingleApiVersion".
44 | // In this case, you must provide a lambda that tells Swashbuckle which actions should be
45 | // included in the docs for a given API version. Like "SingleApiVersion", each call to "Version"
46 | // returns an "Info" builder so you can provide additional metadata per API version.
47 | //
48 | //c.MultipleApiVersions(
49 | // (apiDesc, targetApiVersion) => ResolveVersionSupportByRouteConstraint(apiDesc, targetApiVersion),
50 | // (vc) =>
51 | // {
52 | // vc.Version("v2", "Swashbuckle Dummy API V2");
53 | // vc.Version("v1", "Swashbuckle Dummy API V1");
54 | // });
55 |
56 | // You can use "BasicAuth", "ApiKey" or "OAuth2" options to describe security schemes for the API.
57 | // See https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md for more details.
58 | // NOTE: These only define the schemes and need to be coupled with a corresponding "security" property
59 | // at the document or operation level to indicate which schemes are required for an operation. To do this,
60 | // you'll need to implement a custom IDocumentFilter and/or IOperationFilter to set these properties
61 | // according to your specific authorization implementation
62 | //
63 | //c.BasicAuth("basic")
64 | // .Description("Basic HTTP Authentication");
65 | //
66 | //c.ApiKey("apiKey")
67 | // .Description("API Key Authentication")
68 | // .Name("apiKey")
69 | // .In("header");
70 | //
71 | //c.OAuth2("oauth2")
72 | // .Description("OAuth2 Implicit Grant")
73 | // .Flow("implicit")
74 | // .AuthorizationUrl("http://petstore.swagger.wordnik.com/api/oauth/dialog")
75 | // //.TokenUrl("https://tempuri.org/token")
76 | // .Scopes(scopes =>
77 | // {
78 | // scopes.Add("read", "Read access to protected resources");
79 | // scopes.Add("write", "Write access to protected resources");
80 | // });
81 |
82 | // Set this flag to omit descriptions for any actions decorated with the Obsolete attribute
83 | //c.IgnoreObsoleteActions();
84 |
85 | // Each operation be assigned one or more tags which are then used by consumers for various reasons.
86 | // For example, the swagger-ui groups operations according to the first tag of each operation.
87 | // By default, this will be controller name but you can use the "GroupActionsBy" option to
88 | // override with any value.
89 | //
90 | //c.GroupActionsBy(apiDesc => apiDesc.HttpMethod.ToString());
91 |
92 | // You can also specify a custom sort order for groups (as defined by "GroupActionsBy") to dictate
93 | // the order in which operations are listed. For example, if the default grouping is in place
94 | // (controller name) and you specify a descending alphabetic sort order, then actions from a
95 | // ProductsController will be listed before those from a CustomersController. This is typically
96 | // used to customize the order of groupings in the swagger-ui.
97 | //
98 | //c.OrderActionGroupsBy(new DescendingAlphabeticComparer());
99 |
100 | // Swashbuckle makes a best attempt at generating Swagger compliant context schemas for the various types
101 | // exposed in your API. However, there may be occasions when more control of the output is needed.
102 | // This is supported through the "MapType" and "SchemaFilter" options:
103 | //
104 | // Use the "MapType" option to override the Schema generation for a specific type.
105 | // It should be noted that the resulting Schema will be placed "inline" for any applicable Operations.
106 | // While Swagger 2.0 supports inline definitions for "all" Schema types, the swagger-ui tool does not.
107 | // It expects "complex" Schemas to be defined separately and referenced. For this reason, you should only
108 | // use the "MapType" option when the resulting Schema is a primitive or array type. If you need to alter a
109 | // complex Schema, use a Schema filter.
110 | //
111 | //c.MapType(() => new Schema { type = "integer", format = "int32" });
112 | //
113 | // If you want to post-modify "complex" Schemas once they've been generated, across the board or for a
114 | // specific type, you can wire up one or more Schema filters.
115 | //
116 | //c.SchemaFilter();
117 |
118 | // Set this flag to omit schema property descriptions for any type properties decorated with the
119 | // Obsolete attribute
120 | //c.IgnoreObsoleteProperties();
121 |
122 | // In a Swagger 2.0 document, complex types are typically declared globally and referenced by unique
123 | // Schema Id. By default, Swashbuckle does NOT use the full type name in Schema Ids. In most cases, this
124 | // works well because it prevents the "implementation detail" of type namespaces from leaking into your
125 | // Swagger docs and UI. However, if you have multiple types in your API with the same class name, you'll
126 | // need to opt out of this behavior to avoid Schema Id conflicts.
127 | //
128 | //c.UseFullTypeNameInSchemaIds();
129 |
130 | // In accordance with the built in JsonSerializer, Swashbuckle will, by default, describe enums as integers.
131 | // You can change the serializer behavior by configuring the StringToEnumConverter globally or for a given
132 | // enum type. Swashbuckle will honor this change out-of-the-box. However, if you use a different
133 | // approach to serialize enums as strings, you can also force Swashbuckle to describe them as strings.
134 | //
135 | //c.DescribeAllEnumsAsStrings();
136 |
137 | // Similar to Schema filters, Swashbuckle also supports Operation and Document filters:
138 | //
139 | // Post-modify Operation descriptions once they've been generated by wiring up one or more
140 | // Operation filters.
141 | //
142 | //c.OperationFilter();
143 | //
144 | // If you've defined an OAuth2 flow as described above, you could use a custom filter
145 | // to inspect some attribute on each action and infer which (if any) OAuth2 scopes are required
146 | // to execute the operation
147 | //
148 | //c.OperationFilter();
149 |
150 | // Post-modify the entire Swagger document by wiring up one or more Document filters.
151 | // This gives full control to modify the final SwaggerDocument. You should have a good understanding of
152 | // the Swagger 2.0 spec. - https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md
153 | // before using this option.
154 | //
155 | //c.DocumentFilter();
156 |
157 | // If you annonate Controllers and API Types with
158 | // Xml comments (http://msdn.microsoft.com/en-us/library/b2s063f7(v=vs.110).aspx), you can incorporate
159 | // those comments into the generated docs and UI. You can enable this by providing the path to one or
160 | // more Xml comment files.
161 | //
162 | //c.IncludeXmlComments(GetXmlCommentsPath());
163 |
164 | // In contrast to WebApi, Swagger 2.0 does not include the query string component when mapping a URL
165 | // to an action. As a result, Swashbuckle will raise an exception if it encounters multiple actions
166 | // with the same path (sans query string) and HTTP method. You can workaround this by providing a
167 | // custom strategy to pick a winner or merge the descriptions for the purposes of the Swagger docs
168 | //
169 | //c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());
170 | })
171 | .EnableSwaggerUi(c =>
172 | {
173 | // Use the "InjectStylesheet" option to enrich the UI with one or more additional CSS stylesheets.
174 | // The file must be included in your project as an "Embedded Resource", and then the resource's
175 | // "Logical Name" is passed to the method as shown below.
176 | //
177 | //c.InjectStylesheet(containingAssembly, "Swashbuckle.Dummy.SwaggerExtensions.testStyles1.css");
178 |
179 | // Use the "InjectJavaScript" option to invoke one or more custom JavaScripts after the swagger-ui
180 | // has loaded. The file must be included in your project as an "Embedded Resource", and then the resource's
181 | // "Logical Name" is passed to the method as shown above.
182 | //
183 | //c.InjectJavaScript(thisAssembly, "Swashbuckle.Dummy.SwaggerExtensions.testScript1.js");
184 |
185 | // The swagger-ui renders boolean data types as a dropdown. By default, it provides "true" and "false"
186 | // strings as the possible choices. You can use this option to change these to something else,
187 | // for example 0 and 1.
188 | //
189 | //c.BooleanValues(new[] { "0", "1" });
190 |
191 | // By default, swagger-ui will validate specs against swagger.io's online validator and display the result
192 | // in a badge at the bottom of the page. Use these options to set a different validator URL or to disable the
193 | // feature entirely.
194 | //c.SetValidatorUrl("http://localhost/validator");
195 | //c.DisableValidator();
196 |
197 | // Use this option to control how the Operation listing is displayed.
198 | // It can be set to "None" (default), "List" (shows operations for each resource),
199 | // or "Full" (fully expanded: shows operations and their details).
200 | //
201 | //c.DocExpansion(DocExpansion.List);
202 |
203 | // Use the CustomAsset option to provide your own version of assets used in the swagger-ui.
204 | // It's typically used to instruct Swashbuckle to return your version instead of the default
205 | // when a request is made for "index.html". As with all custom content, the file must be included
206 | // in your project as an "Embedded Resource", and then the resource's "Logical Name" is passed to
207 | // the method as shown below.
208 | //
209 | //c.CustomAsset("index", containingAssembly, "YourWebApiProject.SwaggerExtensions.index.html");
210 |
211 | // If your API has multiple versions and you've applied the MultipleApiVersions setting
212 | // as described above, you can also enable a select box in the swagger-ui, that displays
213 | // a discovery URL for each version. This provides a convenient way for users to browse documentation
214 | // for different API versions.
215 | //
216 | //c.EnableDiscoveryUrlSelector();
217 |
218 | // If your API supports the OAuth2 Implicit flow, and you've described it correctly, according to
219 | // the Swagger 2.0 specification, you can enable UI support as shown below.
220 | //
221 | //c.EnableOAuth2Support("test-client-id", "test-realm", "Swagger UI");
222 | });
223 | }
224 | internal class CustomDocumentFilter : IDocumentFilter
225 | {
226 | public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer)
227 | {
228 | swaggerDoc.definitions["Object"].vendorExtensions["additionalProperties"] = true;
229 |
230 | }
231 | }
232 | }
233 | }
--------------------------------------------------------------------------------