2

oof 多么美好的一天,试图找出动态注入 sdk.js 并使用 src = some url 创建按钮标签。

我已将所有 js 代码添加到文件脚本中,以基于参数注入 sdk 并保存在 wwwroot 下,但由于某种原因,我的函数无法被 server.js 检测到

得到的异常是 - 错误:Microsoft.JSInterop.JSException:在“窗口”中找不到“initializeSDK”。

这是我的js代码

    window.initializeSDK = {

    ejectInjectSdk: function (action, environment) {
        var script = document.createElement('script');
        if (action == "inject") {
            if (self === top) {
                var antiClickjack = document.getElementById("antiClickjack");
                antiClickjack.parentNode.removeChild(antiClickjack);
            } else {
                top.location = self.location;
            }


            if (environment == 'Sandbox') {

                script.type = 'text/javascript';
                script.src = "https://sandbox-assets.secure.checkout.visa.com/checkout-widget/resources/js/integration/v1/sdk.js";
                document.body.append(script);
            } else if (environment == 'live') {
                script.type = 'text/javascript';
                script.src = "https://assets.secure.checkout.visa.com/checkout-widget/resources/js/integration/v1/sdk.js";
                document.body.append(script);
            }

        } else if (action == "eject") {
            if (environment == 'Sandbox') {
                $("script[src='https://sandbox-assets.secure.checkout.visa.com/checkout-widget/resources/js/integration/v1/sdk.js']").remove();
            } else if (environment == 'live') {
                $("script[src='https://assets.secure.checkout.visa.com/checkout-widget/resources/js/integration/v1/sdk.js']").remove();
            }

        }
        $("#vcoholder").hide();
    },

    ejectInjectBtn: function (initpayload) {
        $("#vcoholder").append("<img alt='Visa Checkout' class='v-button' role='button' src='https://sandbox.secure.checkout.visa.com/wallet-services-web/xo/button.png' />");
        onVisaCheckoutReady(initpayload);
        $("#vcoholder").show();

    },

    onVisaCheckoutReady: function (initpayload) {

        console.log(initpayload);
        V.init(initpayload);
        V.on("payment.success", function (payment) {
            console.log(payment);
            var obj = {};
            obj.isLive = false;
            obj.apikey = $.trim($("#apikey").val());
            obj.sharedsecretkey = $.trim($("#sharedsecretkey").val());
            obj.encapikey = $.trim($("#encapikey").val());
            obj.encsharedsecretkey = $.trim($("#encsharedsecretkey").val());
            obj.encKey = payment.encKey;
            obj.encPaymentData = payment.encPaymentData;
            obj.vInitRequest = payment.vInitRequest;
            obj.callid = payment.callid;

            console.log("Payload sending to server " + JSON.stringify(obj));

            $.ajax({
                type: "POST",
                url: '../api/Restful/Getresultsv2',
                data: JSON.stringify(obj),
                dataType: "json",
                success: function (result) {
                    console.log(result);
                    $("#displayJson").jsonViewer(result, {
                        collapsed: false,
                        withQuotes: true
                    })
                }
            });

        });
        V.on("payment.cancel", function (payment) {
            console.log(JSON.stringify(payment));
        });
        V.on("payment.error", function (payment, error) {
            console.log(JSON.stringify(error));
        });
    }
};

并在下面完成剃须刀页面-

@page "/ClicktoPay"
@using Microsoft.AspNetCore.Authorization
@using Zapy.Server.ViewModels
@using Zapy.Server.Servcies
@using Zapy.Server.Models.Clicktopay;
@using Newtonsoft.Json;
@inject CheckoutService Checkoutservice
@inject IJSRuntime JSRuntime
@using Microsoft.Extensions.Configuration
@inject IConfiguration Configuration


<h3>Component1</h3>

<div id="nonsegmentedkeys" class="row">

    <div class="col">
        <div class="card" style="height: 560px;">
            <div class="card-body">
                <EditForm Model="@clicktoPayViewModel">
                    <div id="segmentedkeys">
                        <div class="form-group">
                            <label for="encryptionapikey">Encryption's Apikey</label>
                            <InputText class="form-control form-control-sm" id="encryptionapikey" @bind-Value="clicktoPayViewModel.EncryptionKey" />
                        </div>
                        <div class="form-group">
                            <label for="encryptionsharedsecretkey">Encryptions's Sharedsecret</label>
                            <InputText class="form-control form-control-sm" id="encryptionsharedsecretkey" @bind-Value="clicktoPayViewModel.EncryptionSharedsecret" />
                        </div>
                        <div class="form-group ">
                            <label for="inboundapikey">Inbound Apikey</label>
                            <InputText class="form-control form-control-sm" id="inboundapikey" @bind-Value="clicktoPayViewModel.InboundApikey" />
                        </div>
                        <div class="form-group">
                            <label for="inboundsharedsecret">Inbound Sharedsecret</label>
                            <InputText class="form-control form-control-sm" id="inboundsharedsecret" @bind-Value="clicktoPayViewModel.InboundSharedsecret" />
                        </div>

                    </div>
                </EditForm>
                <div id="vcoholder">
                </div>

            </div>
            <div class="card-footer">
                <button class="btn btn-primary" @onclick="CreateClicktopay">Initialize ClicktoPay</button>
            </div>
        </div>
    </div>

    <div class="col">
        <div class="card">
            <div class="card-body">
                <h5 class="card-title">Initialize parameters here</h5>
                <textarea id="displayJson" value="@clicktoPayViewModel.InitParameters" style="width: 550px; height: 480px;" rows="10"></textarea>
            </div>
        </div>
    </div>

</div>


@code {
    private ClicktoPayViewModel clicktoPayViewModel = new ClicktoPayViewModel();

    protected override async Task OnInitializedAsync()
    {

        clicktoPayViewModel = await Checkoutservice.GetClicktoPayDefaultAsync();

    }

    public async Task CreateClicktopay()
    {

        await JSRuntime.InvokeVoidAsync("initializeSDK.ejectInjectSdk", "inject", "Sandbox");
        await JSRuntime.InvokeVoidAsync("initializeSDK.ejectInjectBtn", clicktoPayViewModel.InitParameters);

    }
}
4

2 回答 2

0

需要记住的是官方的 Microsoft 文档,虽然我在关注它,但我没有注意到我正在阅读 ASP Core 6.0 文档而不是 ASP Core 5.0,在左上角的菜单中您可以选择它。在我的 ASP Core 5.0 的情况下,应该注意<script>应该进入_Host.cshtml并且在 ASP Core 6.0<script>中进入_Layoult.cshtml

在此处输入图像描述

于 2022-02-04T22:44:01.443 回答
0

不知道你是否还在为此烦恼。

但我也偶然发现了类似的问题,我已经在(我在 Blazor Server 上)的附件中声明了我的脚本<body>_Layout.cshtml但我无法调用它,错误说“未定义”。

所以我所做的基本上是JS Isolation (MS Docs)

  1. 将上述脚本放在一个单独的 .js 文件中,导出函数
  2. 准备一个IJSObjectReference作为 C# 对象引用。
  3. 在您的组件或组件的类中,覆盖OnAfterRenderAsync(),检查它是否是firsRender
  4. 将您的 .js 脚本加载到 JS 对象引用中。
  5. 然后您可以在该当前组件的范围内使用它

这是我能举出的最小例子

@using Microsoft.JSInterop;
@inject IJSRuntime jsInvoker
@page "/ThePage"

<h1>Hello<h1>
<Button @onClick=consoom>Text</Button>

@code {
    private IJSObjectReference? jsModule;
    protected override async Task OnAfterRenderAsync(bool firstRender) {
        if (firstRender)
        {
            module = await jsInvoker.InvokeAsync<IJSObjectReference>("import", "./script/CWriter.js");
        }
        await base.OnAfterRenderAsync(firstRender);
    }
    private async Task<bool> Consoom() {
        await module.InvokeVoidAsync("someFunc", "someArgs");
    }
}

这对我有用,我在带有 .NET 6 的 Blazor Server 上。

有一点需要注意,JS 对象有DisposeAsync(),所以你也要注意它的生命周期,也许让你的组件也实现IAsyncDisposable

于 2021-11-22T21:24:15.407 回答