从表单获取信息以调用api

时间:2019-06-26 07:23:28

标签: rest api .net-core

我正在尝试使用MVC和剃须刀页面使用.netcore调用api。作为.netcore的新手,我很难掌握MVC的工作方法。我正在尝试使用“提交”按钮从用户信息中填写表格,然后将该信息带入请求正文以使用控制器命中端点。到现在我的代码看起来像这样。

***View/ Index.cshtml***
@using PTCConnector.Models.DB
@{
    ViewData["Title"] = SharedLocalizer["Users"];
    var user = ViewData["User"] as List<User>;
    List<PTCConnector.Areas.Subscription.Models.SubscriptionModel> filePaths = ViewData["FilePaths"] as List<PTCConnector.Areas.Subscription.Models.SubscriptionModel>;
}
<form method="post" class="form-control-dark">
    <label>
        Username:
        <input type="text" placeholder="admin" readonly />
    </label>
    <br />
    <label>
        Password:
        <input type="text" placeholder="*****" readonly />
    </label>
    <br />
    <label>
        Enter New Password:
        <input type="password" placeholder="New Password" name="new_password" />
    </label>
    <br />
    <button class="btn btn-default" type="submit">SignUp as Admin</button>
</form>

***Models/ wh_adminLoginModel.cs***
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

using PTCConnector.Views;
namespace PTCConnector.Areas.Whatsapp.Models
{
    public class wh_adminLoginModel
    {
        public string df_username = "admin";
        public string df_password = "helloWorld";

        public string new_password { get; set; }


    }
}

***Controller/ AuthAdminController.cs
***
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using PTCConnector.Data;
using PTCConnector.Areas.Settings.Models;
using Microsoft.AspNetCore.Mvc.Rendering;
using PTCConnector.Models.DB;
using Microsoft.EntityFrameworkCore;
using Microsoft.AspNetCore.Authorization;
using PTCConnector.Areas.Whatsapp.Models;
using System.Net.Http;
using System.Text;
using PTCConnector.Areas.Whatsapp.Models;

namespace PTCConnector.Areas.Whatsapp.Controllers
{
    [Area("Whatsapp")]
    [TypeFilter(typeof(AdminActionFilter))]
    [Authorize(Roles = "Admin")]
    public class WhAuthController : Controller
    {
        public wh_adminLoginModel whLogin = new wh_adminLoginModel();
        public async Task Login()
        {
            HttpClientHandler clientHandler = new HttpClientHandler
            {
                ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => { return true; }
            };
            var client = new HttpClient(clientHandler);

            byte[] bytes = Encoding.UTF8.GetBytes($"{whLogin.df_username}:{whLogin.df_password}");

            var Base64Credentials = Convert.ToBase64String(bytes);

            System.Diagnostics.Debug.WriteLine(Base64Credentials);

            // Set Base64Credentials as Authorization header with Prefix `Basic`
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", Base64Credentials);

            // Just some data for POST, change freely!
            var data = new Dictionary<string, string>
            {
//This new_password should come from Model from user view.
                { "new_password", $"{whLogin.new_password}" } 

            };
            System.Diagnostics.Debug.WriteLine(data.Values);
            Console.WriteLine("here 1");
            // Encode the data in FORM URL Data
            var content = new FormUrlEncodedContent(data);

            // Make Async Post Call with Client. Parameters are URL and Data to POST!
            var response = await client.PostAsync("https://localhost:9090/v1/users/login", content);

            // Async!! - Read the response content as String
            var responseString = await response.Content.ReadAsStringAsync();

            // Print out the Response String for Debugging! 
            //Console.WriteLine(responseString);

            System.Diagnostics.Debug.WriteLine(responseString);
            System.Diagnostics.Debug.WriteLine("Check");
            Console.WriteLine("CheckNow");
        }

    }
}

1 个答案:

答案 0 :(得分:1)

在MVC中,默认情况下,所有未标记的方法都被视为GET方法。如果您以POST形式将数据发送回服务器,则需要通过添加HttpPost方法属性来声明该方法。

[HttpPost]
public IActionResult Login(LoginViewModel model)
{
    ...
}

是否注意到该方法上方的HttpPost属性?

您还需要遵守表单中方法的签名(通过传递有效的模型类型)。您可以尝试像这样构建视图

***View/ Index.cshtml***
@using PTCConnector.Models.DB
@model PTCConnector.ViewModels.LoginViewModel

@{
    ViewData["Title"] = SharedLocalizer["Users"];
    var user = ViewData["User"] as List<User>;
    List<PTCConnector.Areas.Subscription.Models.SubscriptionModel> filePaths = ViewData["FilePaths"] as List<PTCConnector.Areas.Subscription.Models.SubscriptionModel>;
}

@using(Html.BeginForm("Login", "WhAuth", FormMethod.Post))
{
    <label>
        Username:
        @Html.TextBoxFor(m => m.Username, null, new {})
    </label>
    <br />
    <label>
        Password:
        @Html.TextBoxFor(m => m.Password, null, new {})
    </label>
    <br />
    <label>
        Enter New Password:
        @Html.TextBoxFor(m => m.NewPassword, null, new {})
    </label>
    <br />
    <button class="btn btn-default" type="submit">Sign up as Admin</button>
}

您会发现我已经向其中添加了一个视图模型,其中包含值UsernamePasswordNewPassword。您需要在PTCConnector下的LoginViewModel.cs下的新ViewModels文件夹下创建一个类,并将这3个变量作为类属性(字符串)。这样,您就可以为前端使用单独的模型,并且其中不包含任何后端信息。下面的示例:

~/PTCConnector/ViewModels/LoginViewModel.cs

using System;

namespace PTCConnector.ViewModels
{
    public class LoginViewModel
    {
        public string Username { get; set; }
        public string Password { get; set; }
        public string NewPassword { get; set; }
    }
}

使用此设置,当您在表单中输入信息并点击“提交”时,它应该到达后端并能够处理模型。如果要使其完全独立,则可以开始使用Ajax建立呼叫并通过Json发出请求。但是我觉得这是一个全新的球类游戏