/// <summary> /// Helper method to do additional transformation on the output value. /// </summary> internal static object TransformOutBindingValueAsNeeded(string bindingName, ReadOnlyBindingInfo bindingInfo, object value) { switch (bindingInfo.Type) { case "http": // Try converting the value to HttpResponseContext if it's not already an object of such type. if (value is HttpResponseContext) { break; } try { value = LanguagePrimitives.ConvertTo <HttpResponseContext>(value); } catch (PSInvalidCastException ex) { string errorMsg = string.Format(PowerShellWorkerStrings.FailToConvertToHttpResponseContext, bindingName, ex.Message); throw new InvalidOperationException(errorMsg); } break; default: break; } return(value); }
/// <summary> /// Helper private function that maps an output binding to a data collecting behavior. /// </summary> private DataCollectingBehavior GetDataCollectingBehavior(ReadOnlyBindingInfo bindingInfo) { switch (bindingInfo.Type) { case "http": return(DataCollectingBehavior.Singleton); case "blob": return(DataCollectingBehavior.Singleton); case "sendGrid": return(DataCollectingBehavior.Singleton); case "onedrive": return(DataCollectingBehavior.Singleton); case "outlook": return(DataCollectingBehavior.Singleton); case "notificationHub": return(DataCollectingBehavior.Singleton); case "excel": return(DataCollectingBehavior.Collection); case "table": return(DataCollectingBehavior.Collection); case "queue": return(DataCollectingBehavior.Collection); case "eventHub": return(DataCollectingBehavior.Collection); case "documentDB": return(DataCollectingBehavior.Collection); case "mobileTable": return(DataCollectingBehavior.Collection); case "serviceBus": return(DataCollectingBehavior.Collection); case "signalR": return(DataCollectingBehavior.Collection); case "twilioSms": return(DataCollectingBehavior.Collection); case "graphWebhookSubscription": return(DataCollectingBehavior.Collection); // Be conservative on new output bindings default: return(DataCollectingBehavior.Singleton); } }
/// <summary> /// Helper method to do additional transformation on the input value based on the type constraints specified in the script. /// </summary> internal static object TransformInBindingValueAsNeeded(PSScriptParamInfo paramInfo, ReadOnlyBindingInfo bindingInfo, object value) { switch (bindingInfo.Type) { case "blob": case "blobTrigger": // For blob input, the input data could be an array of bytes or a string. Documentation says // that a user can specify the 'dataType' to make the input data of the expected type. (see // https://docs.microsoft.com/en-us/azure/azure-functions/functions-triggers-bindings#binding-datatype-property) // // However, I found this setting is somewhat broken: // 1. For the 'blobTrigger' type in-binding, the input data is always byte array and the host doesn't // respect the "dataType" setting in 'function.json'. // 2. For the 'blob' type in-binding, the input data type is 'String' by default. When specified, the // 'binary' and 'string' dataType are respected, but 'stream' dataType is not respected. // // Due to (1), we should be reasonably smart and transform the data appropriately when type constraint is // specified on the input parameter to indicate the expected data type. Type paramType = paramInfo.ParamType; if (value is byte[] blobBytes) { if (paramType == typeof(string)) { // String is expected, so convert the byte array to string using UTF8 encoding. // This is a best effort attempt, as we don't know the true encoding. value = Encoding.UTF8.GetString(blobBytes); } else if (paramType == typeof(Stream)) { // Stream is expected, so convert the byte array to a MemoryStream. value = new MemoryStream(blobBytes); } } // When the input is 'String', we don't attempt to convert it to bytes because if the blob // is in fact a binary file, it's impossible to get the right bytes back even if we use the // same encoding used by the host when converting those bytes to string. break; default: break; } return(value); }
/// <summary> /// BeginProcessing override. /// </summary> protected override void BeginProcessing() { _bindingInfo = GetBindingInfo(Name); _behavior = GetDataCollectingBehavior(_bindingInfo); _outputBindings = FunctionMetadata.GetOutputBindingHashtable(Runspace.DefaultRunspace.InstanceId); }