jquery - 为什么通过 jQuery Ajax 将 Plaid 链接结果发布到 ASP.NET MVC 控制器时缺少属性数据?
问题描述
我的网站可以使用 Plaid 创建链接令牌,但是每当我尝试将此数据发送回服务器时,都会丢失一些数据。
这是我的 .csthml 文件
@section scripts_upper
{
<!-- Include the Plaid Link initialize script on each page of your site. -->
<!-- It should always be loaded directly from https://cdn.plaid.com, rather -->
<!-- than included in a bundle or hosted yourself. -->
<script src="https://cdn.plaid.com/link/v2/stable/link-initialize.js"></script>
}
@model SS.PFS.WebApp.Models.PlaidLinkResults
@{
ViewBag.Title = "Link";
}
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<h2>Link</h2>
<p>
LinkToken: @ViewBag.LinkToken
</p>
<p>
Accesstoken: @ViewBag.Accesstoken
</p>
<div class="col-md-offset-2 col-md-10">
<input type="button" value="Link" onclick="launchPlaid()" class="btn btn-default" />
</div>
<label>Plaid Public Token</label>
<br>
<p id='plaidToken'></p>
<BR>
<label>MetaData</label>
<br>
<textarea id='plaidMetadata2' rows='30' cols='100'></textarea>
}
@section scripts
{
<script>
function launchPlaid() {
const handler = Plaid.create({
//token: document.getElementById('linkToken').value,
token: '@ViewBag.LinkToken',
// The onSuccess() function of the Plaid plugin will return a public
// token and metadata object to your code. Please use our API to send
// us the public token, and we will query the routing number and account
// number of the bank account from Plaid and store it securely on our systems.
onSuccess: (public_token, metadata) => {
document.getElementById('plaidToken').innerHTML = public_token;
document.getElementById('plaidMetadata2').value = JSON.stringify(metadata, null, 2);
//testPost(JSON.stringify(metadata, null, 2));
// testPost(metadata);
testPost(JSON.stringify(metadata));
return true;
},
onLoad: () => { },
onExit: (err, metadata) => {
document.getElementById('plaidToken').innerHTML = err;
document.getElementById('plaidMetadata2').value = JSON.stringify(metadata, null, 2);
},
onEvent: (eventName, metadata) => { },
receivedRedirectUri: null,
});
// Calling open() will display the "Institution Select" view to your user,
// starting the Link flow.
handler.open();
}
function testPost(valueToPost) {
$.ajax({
type: "POST",
url: "/BankAccount/Link",
data: '{ results: ' + valueToPost+ '}',
// data: valueToPost,
//contentType: "application/json; charset=utf-8",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
alert("Hello: " + response.Name + " .\nCurrent Date and Time: " + response.DateTime);
},
failure: function (response) {
alert('failure: ' + response.responseText);
},
error: function (response) {
//alert('error: ' + response.responseText);
//document.getElementById('plaidMetadata2').value = response.responseText;
document.getElementById('plaidMetadata2').value = valueToPost;
}
});
}
</script>
}
这是 /BankAccount/Link 控制器/动作
[HttpPost]
public async Task<ActionResult> Link(Models.PlaidLinkResults results)
{
var resultsetToSaveAsLinkedAccounts = results;
return View("Index");
}
我可以看到填充的数据,因为最终结果显示在 plaidMetadata2 中。它包含 Accounts 的值,但机构->Id、LinkSessionId 和 PublicToken 等属性为空。帐户也有一些数据。
这是 PlaidLinkResults 模型
using System.Collections.Generic;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
namespace SS.PFS.WebApp.Models
{
public class PlaidLinkResults
{
[JsonProperty("institution") ]
public Acklann.Plaid.Entity.Institution Institution { get; set; }
public Acklann.Plaid.Entity.Account Account { get; set; }
public string AccountId { get; set; }
public List<Acklann.Plaid.Entity.Account> Accounts { get; set; }
[JsonProperty("link_session_id")]
public string LinkSessionId { get; set; }
[JsonProperty("public_token")]
public string PublicToken { get; set; }
}
}
这是机构模型的代码
using Acklann.Plaid.Institution;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
namespace Acklann.Plaid.Entity
{
/// <summary>
/// Represents a banking institution.
/// </summary>
public class Institution
{
/// <summary>
/// Gets or sets the identifier.
/// </summary>
/// <value>The identifier.</value>
[JsonProperty("institution_id")]
public string Id { get; set; }
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>The name.</value>
[JsonProperty("name")]
public string Name { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this instance has Multi-Factor Authentication.
/// </summary>
/// <value><c>true</c> if this instance has Multi-Factor Authentication; otherwise, <c>false</c>.</value>
[JsonProperty("has_mfa")]
public bool HasMfa { get; set; }
/// <summary>
/// Gets or sets the Multi-Factor Authentication selections.
/// </summary>
/// <value>The mfa selections.</value>
[JsonProperty("mfa")]
public string[] MfaSelections { get; set; }
[JsonProperty("mfa_code_type")]
public string MfaType { get; set; }
/// <summary>
/// Gets or sets the hexadecimal representation of the primary color used by the institution.
/// </summary>
[JsonProperty("primary_color")]
public string PrimaryColor { get; set; }
/// <summary>
/// Gets or sets the Base64 encoded representation of the institution's logo.
/// </summary>
[JsonProperty("logo")]
public string Logo { get; set; }
/// <summary>
/// Gets or sets the URL for the institution's website.
/// </summary>
/// <value>
/// The URL.
/// </value>
[JsonProperty("url")]
public string Url { get; set; }
/// <summary>
/// Gets or sets the credentials.
/// </summary>
/// <value>The credentials.</value>
[JsonProperty("credentials")]
public Credential[] Credentials { get; set; }
/// <summary>
/// Gets or sets the products.
/// </summary>
/// <value>The products.</value>
[JsonProperty("products")]
public string[] Products { get; set; }
/// <summary>
/// Gets or sets the country codes using the ISO-3166-1 alpha-2 country code standard.
/// </summary>
/// <value>
/// The countries.
/// </value>
[JsonProperty("country_codes")]
public string[] Countries { get; set; }
/// <summary>
/// Gets or sets the information about the institution's current status.
/// </summary>
[JsonProperty("status")]
public StatusSchema Status { get; set; }
/// <summary>
/// Represents an <see cref="Institution"/> login credentials.
/// </summary>
public struct Credential
{
/// <summary>
/// Gets or sets the label.
/// </summary>
/// <value>The label.</value>
[JsonProperty("label")]
public string Label { get; set; }
/// <summary>
/// Gets or sets the name.
/// </summary>
/// <value>The name.</value>
[JsonProperty("name")]
public string Name { get; set; }
/// <summary>
/// Gets or sets the type of the data.
/// </summary>
/// <value>The type of the data.</value>
[JsonProperty("type")]
public string DataType { get; set; }
}
public class StatusSchema
{
/// <summary>
/// Gets or sets status information regarding Item adds via Link.
/// </summary>
[JsonProperty("item_logins")]
public InstitutionStatus ItemLogin { get; set; }
/// <summary>
/// Gets or sets the status information regarding transactions updates.
/// </summary>
[JsonProperty("transactions_updates")]
public InstitutionStatus Transactions { get; set; }
/// <summary>
/// Gets or sets the status information regarding Auth requests..
/// </summary>
/// <value>
/// The authentication.
/// </value>
[JsonProperty("auth")]
public InstitutionStatus Auth { get; set; }
/// <summary>
/// Gets or sets the status information regarding Balance requests.
/// </summary>
/// <value>
/// The balance.
/// </value>
[JsonProperty("balacne")]
public InstitutionStatus Balance { get; set; }
/// <summary>
/// Gets or sets the status information regarding Identity requests.
/// </summary>
[JsonProperty("identity")]
public InstitutionStatus Identity { get; set; }
}
}
}
解决方案
大多数情况下发生这种情况是因为发送了格式错误的数据。
注意到您如何格式化要发送的数据的一些问题导致您的 JSON 格式不正确。
请注意该results
字段如何没有引号
因为您尝试自己构建字符串
//...
data: '{ results: ' + valueToPost+ '}',
//...
然后模型绑定器的任务是尝试从格式错误的有效负载中推断出所需的数据并将它们映射到模型。
我首先建议只是将元数据传递给testPost
按原样运行
//...
onSuccess: (public_token, metadata) => {
//...
testPost(metadata);
return true;
},
//...
并让该函数处理格式。
function testPost(valueToPost) {
var data = { results : valueToPost }; //creating payload object
$.ajax({
type: "POST",
url: "/BankAccount/Link",
data: JSON.stringify(data), //formatting to JSON here
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
alert("Hello: " + response.Name + " .\nCurrent Date and Time: " + response.DateTime);
},
failure: function (response) {
alert('failure: ' + response.responseText);
},
error: function (response) {
//alert('error: ' + response.responseText);
//document.getElementById('plaidMetadata2').value = response.responseText;
document.getElementById('plaidMetadata2').value = valueToPost;
}
});
}
该操作还应该明确告诉模型绑定器在哪里查找数据
[HttpPost]
public ActionResult Link([FromBody]Models.PlaidLinkResults results) {
var resultsetToSaveAsLinkedAccounts = results;
return View("Index");
}
这样它就不必从可能的来源之一推断数据
推荐阅读
- git - git filter-branch - 删除许多子模块之一
- java - 滚动窗格放大 Java
- react-native - 如何处理非规范化数据以传递给平面列表?
- node.js - serveIndex 模块更改 UI
- xslt - 根据条件更改 XSLT 中的节点值
- odoo - 什么是无效的叶子[odoo中的错误?
- javascript - HTML一个没有href属性的标签,点击时会发生什么
- php - 如何在 Laravel 查询中使用 where 和 skip 在相同的条件下?
- node.js - 如何使用 Electron、NW.js 来“服务”可在本地网络上访问的 React 应用程序
- sql - 外键缺少括号