Process a file using Azure Function

2019-02-18 04:47发布

问题:

I would like to process an input file and output it to some location for ex. FTP or Azure storage. I am trying to use Azure Function with SaasFile input/output. I am getting below error:

2016-07-14T00:44:53 Welcome, you are now connected to log-streaming service. 2016-07-14T00:45:00.580 Script for function 'HttpTriggerCSharp1' changed. Reloading. 2016-07-14T00:45:00.580 Compiling function script. 2016-07-14T00:45:00.721 run.csx(24,25): error CS0622: Can only use array initializer expressions to assign to array types. Try using a new expression instead. 2016-07-14T00:45:00.721 Compilation failed.

Here is my function signature:

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, string output, TraceWriter log)

Bindings:

{
  "bindings": [
    {
      "authLevel": "function",
      "name": "req",
      "type": "httpTrigger",
      "direction": "in"
    },
    {
      "name": "res",
      "type": "http",
      "direction": "out"
    },
    {
      "type": "apiHubFile",
      "name": "output",
      "path": "path/{file}",
      "connection": "ftp_FTP",
      "direction": "out"
    }
  ],
  "disabled": false
}

I think I am missing something in Run signature. I couldn't find it on Azure documentation.

I need help figure out how to process using FTP and Azure Storage. Thanks for your help.

回答1:

You don't really need a http trigger for this. Here is an example which watches a folder(input-cs) for new files in dropbox and copies the file to a folder (output-cs) in googledrive:

using System;

public static void Run(string input, out string output, TraceWriter log)
{
    output = input;
}

bindings:

{

 "bindings": [
    {
      "type": "apiHubFileTrigger",
      "name": "input",
      "direction": "in",
      "path": "input-cs/{name}",
      "connection": "dropbox_DROPBOX"
    },
    {
      "type": "apiHubFile",
      "name": "output",
      "direction": "out",
      "path": "output-cs/{name}",
      "connection": "googledrive_GOOGLEDRIVE"
    }
  ],
  "disabled": false
}


回答2:

If you have to use a Http trigger and need to create the file name in the function itself based on some header values or what not, you use use this sample:

Please make sure, you are using Functions version 0.4 or higher for this (it is being released today)

#r "Microsoft.Azure.WebJobs.Extensions.ApiHub"

using System.Net;
using Microsoft.Azure.WebJobs;

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log, IBinder binder)
{
    //Get request  body  
    string data = await req.Content.ReadAsStringAsync();

    string fileName = "path/" + Guid.NewGuid().ToString() + ".txt";

    var writer = binder.Bind<TextWriter>(new ApiHubFileAttribute("DROPBOX_dropbox", fileName, FileAccess.Write));

    writer.Write(data);
    return req.CreateResponse(HttpStatusCode.OK);  
}

bindings:

{
  "bindings": [
    {
      "authLevel": "function",
      "name": "req",
      "type": "httpTrigger",
      "direction": "in"
    },
    {
      "name": "res",
      "type": "http",
      "direction": "out"
    }
  ],
  "disabled": false
}


回答3:

Here is one way you can do it, assuming you output to a specific file name. I am binding to a dropbox file in this example.

using System.Net;

public static HttpResponseMessage Run(HttpRequestMessage req, TraceWriter log, out string output)
{
    output = req.Content.ReadAsStringAsync().GetAwaiter().GetResult();

    return req.CreateResponse(HttpStatusCode.OK);   
}

bindings:
{
  "bindings": [
    {
      "authLevel": "function",
      "name": "req",
      "type": "httpTrigger",
      "direction": "in"
    },
    {
      "type": "http",
      "name": "res",
      "direction": "out"
    },
    {
      "type": "apiHubFile",
      "name": "output",
      "path": "path/b.txt",
      "connection": "dropbox_DROPBOX",
      "direction": "out",
    }
  ],
  "disabled": false
}

In order to bind to different file names, you will need to have an input or input trigger and pass the file name to output. same as all other samples.



回答4:

Good news.. External File trigger is available for Azure functions.

If you want to process file in an external FTP folder, create a FTP connection first and then use it.

So your bindings array for FTP connection in function.json shown below.

{
  "bindings": [
    {
      "type": "apiHubFileTrigger",
      "name": "inputFile",
      "direction": "in",
      "path": "input-cs/{name}",
      "connection": "ftp_FTP"
    },
    {
      "type": "apiHubFile",
      "name": "$return",
      "direction": "out",
      "path": "output-cs/{name}",
      "connection": "ftp_FTP"
    }
  ],
  "disabled": false
}

In the above JSON,

path

Represents the path of the file to be processed. So in above case, azure function will be triggered when a file is added/modified in input-cs folder.

connection

Represents the External File connector name.