6
6
using System . Linq ;
7
7
using System . Net ;
8
8
using System . Net . Http ;
9
+ using System . Reflection ;
9
10
using System . Threading ;
10
11
using System . Threading . Tasks ;
12
+ using Microsoft . AspNet . WebHooks ;
11
13
using Microsoft . Azure . WebJobs ;
12
14
using Microsoft . Azure . WebJobs . Script ;
13
15
using Microsoft . Azure . WebJobs . Script . Description ;
@@ -18,6 +20,7 @@ namespace WebJobs.Script.WebHost
18
20
{
19
21
public class WebScriptHostManager : ScriptHostManager
20
22
{
23
+ private static Lazy < MethodInfo > _getWebHookDataMethod = new Lazy < MethodInfo > ( CreateGetWebHookDataMethodInfo ) ;
21
24
private IMetricsLogger _metricsLogger ;
22
25
23
26
public WebScriptHostManager ( ScriptHostConfiguration config ) : base ( config )
@@ -32,12 +35,7 @@ public async Task<HttpResponseMessage> HandleRequestAsync(FunctionDescriptor fun
32
35
// All authentication is assumed to have been done on the request
33
36
// BEFORE this method is called
34
37
35
- // Invoke the function
36
- ParameterDescriptor triggerParameter = function . Parameters . First ( p => p . IsTrigger ) ;
37
- Dictionary < string , object > arguments = new Dictionary < string , object >
38
- {
39
- { triggerParameter . Name , request }
40
- } ;
38
+ Dictionary < string , object > arguments = await GetFunctionArgumentsAsync ( function , request ) ;
41
39
42
40
// Suspend the current synchronization context so we don't pass the ASP.NET
43
41
// context down to the function.
@@ -57,6 +55,53 @@ public async Task<HttpResponseMessage> HandleRequestAsync(FunctionDescriptor fun
57
55
return response ;
58
56
}
59
57
58
+ private static MethodInfo CreateGetWebHookDataMethodInfo ( )
59
+ {
60
+ return typeof ( WebHookHandlerContextExtensions ) . GetMethod ( "GetDataOrDefault" , BindingFlags . Public | BindingFlags . Static ) ;
61
+ }
62
+
63
+ private static async Task < Dictionary < string , object > > GetFunctionArgumentsAsync ( FunctionDescriptor function , HttpRequestMessage request )
64
+ {
65
+ ParameterDescriptor triggerParameter = function . Parameters . First ( p => p . IsTrigger ) ;
66
+ Dictionary < string , object > arguments = new Dictionary < string , object > ( ) ;
67
+ object triggerArgument = null ;
68
+ if ( triggerParameter . Type == typeof ( HttpRequestMessage ) )
69
+ {
70
+ triggerArgument = request ;
71
+ }
72
+ else
73
+ {
74
+ // We'll replace the trigger argument but still want to flow the request
75
+ // so add it to the arguments, as a system argument
76
+ arguments . Add ( ScriptConstants . DefaultSystemTriggerParameterName , request ) ;
77
+
78
+ HttpTriggerBindingMetadata httpFunctionMetadata = ( HttpTriggerBindingMetadata ) function . Metadata . InputBindings . FirstOrDefault ( p => p . Type == BindingType . HttpTrigger ) ;
79
+ if ( ! string . IsNullOrEmpty ( httpFunctionMetadata . WebHookType ) )
80
+ {
81
+ WebHookHandlerContext webHookContext ;
82
+ if ( request . Properties . TryGetValue ( ScriptConstants . AzureFunctionsWebHookContextKey , out webHookContext ) )
83
+ {
84
+ triggerArgument = GetWebHookData ( triggerParameter . Type , webHookContext ) ;
85
+ }
86
+ }
87
+
88
+ if ( triggerArgument == null )
89
+ {
90
+ triggerArgument = await request . Content . ReadAsAsync ( triggerParameter . Type ) ;
91
+ }
92
+ }
93
+
94
+ arguments . Add ( triggerParameter . Name , triggerArgument ) ;
95
+
96
+ return arguments ;
97
+ }
98
+
99
+ private static object GetWebHookData ( Type dataType , WebHookHandlerContext context )
100
+ {
101
+ MethodInfo getDataMethod = _getWebHookDataMethod . Value . MakeGenericMethod ( dataType ) ;
102
+ return getDataMethod . Invoke ( null , new object [ ] { context } ) ;
103
+ }
104
+
60
105
public FunctionDescriptor GetHttpFunctionOrNull ( Uri uri )
61
106
{
62
107
if ( uri == null )
0 commit comments