in src/WebJobs.Extensions.Http/HttpTriggerAttributeBindingProvider.cs [273:320]
internal Dictionary<string, Type> GetBindingDataContract(HttpTriggerAttribute attribute, ParameterInfo parameter)
{
// add contract members for POCO binding properties if binding to a POCO
var aggregateDataContract = new Dictionary<string, Type>(StringComparer.OrdinalIgnoreCase);
if (_isUserTypeBinding && _bindingDataProvider?.Contract != null)
{
aggregateDataContract.AddRange(_bindingDataProvider.Contract);
}
// Mark that HttpTrigger accepts a return value.
aggregateDataContract["$return"] = typeof(object).MakeByRefType();
// add contract members for any route parameters
if (!string.IsNullOrEmpty(attribute.Route))
{
var routeParameters = TemplateParser.Parse(attribute.Route).Parameters;
var parameters = ((MethodInfo)parameter.Member).GetParameters().ToDictionary(p => p.Name, p => p.ParameterType, StringComparer.OrdinalIgnoreCase);
foreach (TemplatePart routeParameter in routeParameters)
{
// don't override if the contract already includes a name
if (!aggregateDataContract.ContainsKey(routeParameter.Name))
{
// if there is a method parameter mapped to this parameter
// derive the Type from that
Type type;
if (!parameters.TryGetValue(routeParameter.Name, out type))
{
type = typeof(string);
}
aggregateDataContract[routeParameter.Name] = type;
}
}
}
// add headers collection to the contract
if (!aggregateDataContract.ContainsKey(HttpHeadersKey))
{
aggregateDataContract.Add(HttpHeadersKey, typeof(IDictionary<string, string>));
}
// add query parameter collection to binding contract
if (!aggregateDataContract.ContainsKey(HttpQueryKey))
{
aggregateDataContract.Add(HttpQueryKey, typeof(IDictionary<string, string>));
}
return aggregateDataContract;
}