How to pass parameters by POST to an Azure function?

前端 未结 9 1977
暗喜
暗喜 2020-12-24 05:27

I\'m trying to do a simple Azure Function to learn about it. There will be 3 functions:

  • 1 function to insert a row into a table of a database. This table will
9条回答
  •  攒了一身酷
    2020-12-24 06:21

    I like the WebApi approach of using [FromBody] attribute, so using IBinding I made my own. Now I can just pass in the object.

    [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.ReturnValue)]
    [Binding]
    public sealed class FromBodyAttribute : Attribute
    {
    }
    
    public class FromBodyBinding : IBinding
    {
        private readonly ILogger logger;
        public FromBodyBinding(ILogger logger)
        {
            this.logger = logger;
        }
        public Task BindAsync(BindingContext context)
        {
            // Get the HTTP request
            var request = context.BindingData["req"] as DefaultHttpRequest;
    
            return Task.FromResult(new FromBodyValueProvider(request, logger));
        }
    
        public bool FromAttribute => true;
    
    
        public Task BindAsync(object value, ValueBindingContext context)
        {
            return null;
        }
    
        public ParameterDescriptor ToParameterDescriptor() => new ParameterDescriptor();
    }
    
    public class FromBodyBindingProvider : IBindingProvider
    {
        private readonly ILogger logger;
        public FromBodyBindingProvider(ILogger logger)
        {
            this.logger = logger;
        }
    
        public Task TryCreateAsync(BindingProviderContext context)
        {
            IBinding binding = new FromBodyBinding(this.logger);
            return Task.FromResult(binding);
        }
    }
    
    public class FromBodyValueProvider : IValueProvider
    {
        private HttpRequest request;
        private ILogger logger;
    
        public FromBodyValueProvider(HttpRequest request, ILogger logger)
        {
            this.request = request;
            this.logger = logger;
        }
    
        public async Task GetValueAsync()
        {
            try
            {
                string requestBody = await new StreamReader(this.request.Body).ReadToEndAsync();
                object result = JsonConvert.DeserializeObject(requestBody);
                return result;
            }
            catch (System.Exception ex)
            {
                this.logger.LogCritical(ex, "Error deserializing object from body");
    
                throw ex;
            }
        }
    
        public Type Type => typeof(object);
    
        public string ToInvokeString() => string.Empty;
    }
    
    public class BindingExtensionProvider : IExtensionConfigProvider
    {
        private readonly ILogger logger;
        public BindingExtensionProvider(ILogger logger)
        {
            this.logger = logger;
        }
    
        public void Initialize(ExtensionConfigContext context)
        {
            // Creates a rule that links the attribute to the binding
            context.AddBindingRule().Bind(new FromBodyBindingProvider(this.logger));
        }
    }
    
    
    

    Then inside your Startup.cs file, add the binding.

    public class Startup : IWebJobsStartup
    {
        public void Configure(IWebJobsBuilder builder)
        {
            JsonConvert.DefaultSettings = () =>
            {
                return new JsonSerializerSettings()
                {
                    ContractResolver = new DefaultContractResolver
                    {
                        NamingStrategy = new CamelCaseNamingStrategy()
                    },
                    Formatting = Formatting.Indented
                };
            };
    
            builder.Services.AddLogging();
            builder.AddExtension();
    
        }
    }
    

    Now you can just have a regular old class, just like WebApi!

    [FunctionName("MyFunction")]
    public async Task Run(
        [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest req,
        [Binding.FromBody] dynamic data) // or you can change 'dynamic' to some class
    {
        string username = data?.username;
        ...
    }
    

    提交回复
    热议问题