从Razor Pages App向API发送HTTP请求

时间:2019-08-21 14:59:54

标签: c# http asp.net-core razor-pages

我正在创建一个向用户展示表单的应用程序。当用户提交表单时,我的应用程序将使用这些值并将其格式化为查询字符串。然后,该字符串用于调用第三方API。该应用程序是使用Visual Studio 2019中的ASP.NET Core Razor Pages模板以C#编写的。我首先进行了尝试创建HTTPClient并使用控制台应用程序中的硬编码值将HTTPRequestMessage发送给第三方API的方法,该方法运行良好。但是,当将我的代码移到Razor Pages应用程序中以为该应用程序添加前端时,我似乎无法让该应用程序调用我创建的代码。由于我仅采用表单值并将它们以查询字符串的形式传递给第三方API(不需要我定义自己的模型),因此我决定使用Razor Pages代替ASP.NET MVC。

这是我在应用程序中设置的Index.cshtml页面:

@page
@model IndexModel
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@{
    ViewData["Title"] = "Home page";
}

    <div>
        <form asp-page-handler="ProcessRequest" method="post">
            <label for="FirstName">First Name:</label>
            <input type="text" name="FirstName" value="" />
            <label for="LastName">Last Name:</label>
            <input type="text" name="LastName" value="" />
            <label for="Email">Email:</label>
            <input type="text" name="Email" value="" />
            <button type="submit">Send Request</button>
        </form>
    </div>

如您所见,它只是具有三个输入字段的简单表单,没有花哨的地方。

包含模型逻辑的基础Index.cshtml.cs文件具有以下代码:

public class IndexModel : PageModel
{
    static HttpClient myAppHTTPClient = new HttpClient();

    public async void OnPostProcessRequestAsync()
    {            
        string firstName, lastName, email;
        string host = "https://thirdparty.app.com:443/";
        string pathname = "path/to/api/endpoint/?operation=create";

        firstName = "Test";
        LastName = "User";
        email = "TestUser@email.com";

        string path = pathname + "&first_name=" + firstName + "&last_name=" + lastName + "&email=" + email;
        string requestUrl = host + path;

        HttpRequestMessage httpRequestMessage = new HttpRequestMessage();

        try
        {
            HttpResponseMessage responseMessage = await myAppHTTPClient.PostAsync(requestUrl, httpRequestMessage.Content);
            HttpContent content = responseMessage.Content;
            string message = await content.ReadAsStringAsync();
            Console.WriteLine("The output from thirdparty is: {0}", message);
            RedirectToPage();
        }
        catch (HttpRequestException exception)
        {
            Console.WriteLine("An HTTP request exception occurred. {0}", exception.Message);
        }
    }
}

ASP.NET Razor页面的文档说,当您的表单中有一个asp-page-handler标记助手时,提交表单将调用页面处理程序方法OnPost[method_name]Async()。就我而言,表单中的行<form asp-page-handler="ProcessRequest" method="post">应该调用public async void OnPostProcessRequestAsync()方法。但是,这没有按照我的预期工作。我尝试在表单和“提交”按钮中使用其他标记帮助器。有没有一种方法可以让Razor Page调用运行我的代码的方法。我知道我缺少RedirectToPage()方法,但我首先想让方法调用起作用。

1 个答案:

答案 0 :(得分:0)

尽管该线程上已有两个人提出了答案,但我没有找到一种方法可以将他们的评论标记为已回答问题。因此,为了公平起见,在应归功的地方给予好评,他们的建议使我可以修改自己的代码。基本上,我错误地定义了页面处理程序方法。我将其定义为:

public async void OnPostProcessRequestAsync()...

但是,这种类型的应用程序需要页面处理程序方法来返回诸如Task之类的东西。当将返回类型从void更改为Task时,这可以完美地工作。我的猜测是,由于我是异步定义此代码的,因此返回值必须是异步的。由于Task <>类用于线程化(异步)代码,因此可以正常工作。