programing

POST를 통해 파라미터를 Azure 함수로 전달하는 방법은 무엇입니까?

jooyons 2023. 5. 15. 21:40
반응형

POST를 통해 파라미터를 Azure 함수로 전달하는 방법은 무엇입니까?

저는 그것에 대해 배우기 위해 간단한 애저 함수를 하려고 합니다.세 가지 기능이 있습니다.

  • 데이터베이스의 테이블에 행을 삽입하는 1 함수입니다.이 테이블에는 현재 날짜와 사용자가 입력하고 GET가 전달한 문자열 매개 변수가 포함됩니다.
  • 1 기능은 이전 기능과 유사하지만 POST를 통해 매개 변수를 전달합니다.
  • 표를 읽고 내용을 보여주는 1개의 기능.

첫 번째와 세 번째를 할 수 있었습니다.하지만 POST로 파라미터를 전달할 수 없습니다.저는 사례를 찾아봤지만 성공적으로 실행할 수 없었습니다.클라이언트 앱은 Windows Forms 앱입니다.

POST를 통해 기능에 매개 변수를 전달하는 방법과 매개 변수를 읽는 방법을 예로 보여줄 수 있는 사람이 있습니까?

미리 감사드립니다.

편집:

GET로 매개 변수를 전달하는 코드는 다음과 같습니다(이것은 정상적으로 작동합니다).

private void button2_Click(object sender, EventArgs e)
{
    string cadena = lsql1.Text + "?notas=" + tNotas.Text;

    try
    {
        HttpWebRequest req = (HttpWebRequest)WebRequest.Create(cadena);
        HttpWebResponse res = (HttpWebResponse)req.GetResponse();

        if (res.StatusCode == HttpStatusCode.OK)
        {
            MessageBox.Show("Grabado");
        }
        else
        {
            MessageBox.Show(res.StatusDescription);
        }
    }catch (WebException ex)
    {
        using (Stream s = ex.Response.GetResponseStream())
        {
            StreamReader sr = new StreamReader(s);
            string text = sr.ReadToEnd();
            text = text.Substring(1, text.Length - 2);
            sr.Close();
            text = text.Replace("\\", "");
            text = "{" + text + "}";
            Error mensajeError = JsonConvert.DeserializeObject<Error>(text);

            MessageBox.Show(mensajeError.ExceptionMessage);
        }

    }
}

다음은 수신하고 삽입하는 코드입니다(이것도 작동합니다).

[FunctionName("sql1")]
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
{
    try
    {
        log.Info("C# HTTP trigger function processed a request.");

        var cnnString = "Server=SERVIDOR;Database=base_prueba;User ID =azure;Password=0000;Trusted_Connection=False;Encrypt=False;";

        using (SqlConnection connection = new SqlConnection(cnnString))
        {
            connection.Open();
            SqlCommand cmd = connection.CreateCommand();

            DateTime fecha = DateTime.Today;

            string notas = req.GetQueryNameValuePairs()
            .FirstOrDefault(q => string.Compare(q.Key, "notas", true) == 0)
            .Value;

            // insert a log to the database
            cmd.CommandText = "INSERT INTO Prueba_Azure (fecha, notas) VALUES ('" + fecha.ToString() + "', '" + notas + "')";
            cmd.ExecuteNonQuery();
        }

        // Get request body
        dynamic data = await req.Content.ReadAsAsync<object>();

        return name == req.CreateResponse(HttpStatusCode.OK, "Done");
    }
    catch (Exception ex)
    {
        HttpResponseMessage res = req.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
        return res;
    }
}

제가 찾고 있는 것은 POST로 이것을 하는 것입니다.

구글이 당신을 여기로 데려간 경우, 2019년 3월에 하는 방법은 다음과 같습니다(Azure Functions v3).

public static async void Run(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]
            HttpRequest req,
            ILogger log)
        {
            var content = await new StreamReader(req.Body).ReadToEndAsync();

            MyClass myClass = JsonConvert.DeserializeObject<MyClass>(content);
            
        }

요청 본문(포스트 요청)에서 요청 내용을 가져오려면 req를 사용할 수 있습니다.내용물.AsAsync 메서드를 읽습니다.여기 코드 샘플이 있습니다.

샘플 요청 본문입니다.

{
    "name": "Azure"
}

사후 데이터를 역직렬화할 클래스를 정의합니다.

public class PostData
{
    public string name { get;set; }    
}

게시 데이터를 가져와 표시합니다.

PostData data = await req.Content.ReadAsAsync<PostData>();
log.Info("name:" + data.name);

게시 요청을 보낼 클라이언트 사이드 코드입니다.

HttpWebRequest req = (HttpWebRequest)WebRequest.Create("function-url");
req.Method = "POST";
req.ContentType = "application/json";
Stream stream = req.GetRequestStream();
string json = "{\"name\": \"Azure\" }";
byte[] buffer = Encoding.UTF8.GetBytes(json);
stream.Write(buffer,0, buffer.Length);
HttpWebResponse res = (HttpWebResponse)req.GetResponse();

사용 중인 경우System.Text.JsonPOST 데이터를 한 줄로 읽을 수 있습니다.

public static async Task Run(
    [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]
    HttpRequest req,
    ILogger log)
{
    MyClass myClass = await JsonSerializer.DeserializeAsync<MyClass>(req.Body);
}

사용 중인 경우Newtonsoft.JsonAllen Zhang의 답을 보세요.

POST 요청으로 매개 변수를 전달하려면 다음 작업을 수행해야 합니다.

  1. 전달해야 하는 매개 변수의 Json 모델을 만듭니다. 예:

    {"UserProfile":{ "UserId":"xyz1","FirstName":"Tom","LastName":"Hank" }}
    
  2. POSTMAN과 같은 클라이언트를 사용하여 데이터 모델 게시

    여기에 이미지 설명 입력

  3. 이제 HttpRequestMessage 본문에 게시된 콘텐츠를 받게 됩니다. 샘플 코드는 다음과 같습니다.

    [FunctionName("TestPost")]
    public static HttpResponseMessage POST([HttpTrigger(AuthorizationLevel.Function, "put", "post", Route = null)]HttpRequestMessage req, TraceWriter log)
    {
        try
        {
            //create redis connection and database
            var RedisConnection = RedisConnectionFactory.GetConnection();
            var serializer = new NewtonsoftSerializer();
            var cacheClient = new StackExchangeRedisCacheClient(RedisConnection, serializer);
    
            //read json object from request body
            var content = req.Content;
            string JsonContent = content.ReadAsStringAsync().Result;
    
            var expirytime = DateTime.Now.AddHours(Convert.ToInt16(ConfigurationSettings.AppSettings["ExpiresAt"]));
    
            SessionModel ObjModel = JsonConvert.DeserializeObject<SessionModel>(JsonContent);
            bool added = cacheClient.Add("RedisKey", ObjModel, expirytime); //store to cache 
    
            return req.CreateResponse(HttpStatusCode.OK, "RedisKey");
        }
        catch (Exception ex)
        {
            return req.CreateErrorResponse(HttpStatusCode.InternalServerError, "an error has occured");
        }
    }
    

사용자 정의 데이터 클래스를 매개 변수로 제공할 수 있습니다.HttpTrigger논쟁.이렇게 하면 json 역직렬화를 직접 처리할 필요가 없습니다.

public async Task<IActionResult> UpdateAccount(
        [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "api/v1/accounts/{id:guid}")] 
        SomeData someData,  // <----- Post body ends up here automatically
        HttpRequest req,
        Guid id,
        ILogger log)
{
    log.LogInformation ("Got POST with " + someData.Foo);
}


public class SomeData
{
    public string Foo { get; set; } = null!;
}

쿼리 문자열(이름/값 쌍)은 기본적으로 POST 요청의 HTTP 메시지 본문으로 전송되며 쿼리 문자열로 전송되지 않습니다.GetQueryNameValuePairs 메서드는 쿼리 문자열을 구문 분석하며 기본적으로 POST 요청과 함께 작동하지 않습니다.

POST 요청의 경우 다음과 유사한 방법을 사용할 수 있습니다.

var content = request.Content;
string contentInString = content.ReadAsStringAsync().Result;

게시 요청의 본문에 데이터를 첨부하고 적절하게 처리해야 합니다.

public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log) {
    // This reads your post request body into variable "data"
    string data = await req.Content.ReadAsStringAsync();
    // Here you can process json into an object
    dynamic parsed = JsonConvert.DeserializeObject(data);

    return exitstring == null
        ? req.CreateResponse(HttpStatusCode.BadRequest, "Something went wrong, sorry")
        : req.CreateResponse(HttpStatusCode.OK);
}

여기에서는 약간 다른 를 찾을 수 있고 여기서는 정확한 예를 찾을 수 있습니다.

다음과 같은 방법으로 수행할 수 있습니다.custom class

애저 함수

[FunctionName("PostParameterFunction")]
public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)]HttpRequestMessage req, ILogger log)
   {
      log.LogInformation("C# HTTP trigger function processed a request.");

       try
        {
             // Convert all request perameter into Json object

                var content = req.Content;
                string jsonContent = content.ReadAsStringAsync().Result;
                dynamic requestPram = JsonConvert.DeserializeObject<RequestModel>(jsonContent);

                // Validate the required param

                if (string.IsNullOrEmpty(requestPram.FirstName))
                {
                    return req.CreateResponse(HttpStatusCode.OK, "Please enter First Name!");
                }
                if (string.IsNullOrEmpty(requestPram.LastName))
                {
                    return req.CreateResponse(HttpStatusCode.OK, "Please enter Last Name!");
                }


                //Create object for partner Model to bind the response on it

                RequestModel objRequestModel = new RequestModel();

                objRequestModel.FirstName = requestPram.FirstName;
                objRequestModel.LastName = requestPram.LastName;

                //Return Request Model

                return req.CreateResponse(HttpStatusCode.OK, objRequestModel);
         }
        catch (Exception ex)
         {

                return req.CreateResponse(HttpStatusCode.OK, "Cannot Create Request! Reason: {0}", string.Format(ex.Message));
         }

        }

요청 클래스:

 public class RequestModel
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }

    }

요청 입력:

{
    "FirstName": "Kiron",
    "LastName":"Test"
}

포스트맨 출력 예:

여기에 이미지 설명 입력

저는 Azure Function App에서 POST 요청을 사용하여 데이터를 얻는 매우 간단한 예를 수행했습니다.다음 예시를 찾아주세요.

using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Azure.WebJobs.Host;

namespace MyFunctions
{
    public static class MyFunctionsOperations
    {
        [FunctionName("MyFunctionsOperations")]
        public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]HttpRequestMessage req, TraceWriter log)
        {
            log.Info("C# HTTP trigger function processed a request.");
            var headers = req.Headers;
            string collection = headers.GetValues("collection").First();   //getting parameter from header

            CosmosdbOperation obj = new CosmosdbOperation();
            dynamic data = await req.Content.ReadAsAsync<object>();  //getting body content
            Boolean response = await obj.MyFunctionExecution(data.ToString(), collection);

            return (response)
                ? req.CreateResponse(HttpStatusCode.BadRequest, "Please pass a proper argument in the request body")
                : req.CreateResponse(HttpStatusCode.OK, "Operation successfully executed..");
        }
    }
}

저는 웹 API를 사용하는 방법을 좋아합니다.[FromBody] 속, 사를 사용합니다.IBinding제가 직접 만들었어요.이제 저는 그 물체를 그냥 넘길 수 있습니다.

[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<IValueProvider> BindAsync(BindingContext context)
    {
        // Get the HTTP request
        var request = context.BindingData["req"] as DefaultHttpRequest;

        return Task.FromResult<IValueProvider>(new FromBodyValueProvider(request, logger));
    }

    public bool FromAttribute => true;


    public Task<IValueProvider> 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<IBinding> 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<object> 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<Startup> logger)
    {
        this.logger = logger;
    }

    public void Initialize(ExtensionConfigContext context)
    {
        // Creates a rule that links the attribute to the binding
        context.AddBindingRule<FromBodyAttribute>().Bind(new FromBodyBindingProvider(this.logger));
    }
}

그런 다음 Startup.cs 파일 안에 바인딩을 추가합니다.

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<BindingExtensionProvider>();

    }
}

이제 WebApi처럼 일반적인 오래된 수업을 들을 수 있습니다!

[FunctionName("MyFunction")]
public async Task<IActionResult> 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;
    ...
}

요점은 --> https://learn.microsoft.com/en-us/azure/azure-functions/functions-bindings-http-webhook-trigger?tabs=in-process%2Cfunctionsv2&pivots=programming-language-csharp 입니다.

    [FunctionName("LuckyNumber")]
    public static async Task<IActionResult> Run(
        [HttpTrigger(
        AuthorizationLevel.Function,
        "get", "post",
        Route = "max/{max:int?}/min/{min:int?}")] HttpRequest req,
        int? max, <-- Parameter max
        int? min, <-- Parameter min
        ILogger log)
    {
        int? maxInternal = max;
        int? minInternal = min;
    }

PS: 사용하고 있습니다.NET 6

다음을 사용하여 하나의 라인 코드로 수행할 수 있습니다.System.Text.Json.

public static async void Run(
        [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]
        HttpRequest req,
        ILogger log)
    {
        MyClass myClass = await JsonSerializer.DeserializeAsync<MyClass>(req.Body);
        
    }

언급URL : https://stackoverflow.com/questions/45183820/how-to-pass-parameters-by-post-to-an-azure-function

반응형