我制作了一个页面,用于查询结果并将其显示在表格上。该表上有一个字段,用于获取我查询的结果之一,并使用我创建的服务对其进行解密。我的问题是,当我单击对表中的结果进行解密的按钮时,它会在所有表行而不是已单击的一个表行中普遍显示结果。这是我的代码,请看一下UnmaskPan方法
@page "/"
@using TranactionJournalV4.Models;
@using TranactionJournalV4.Data;
@using TranactionJournalV4.Controllers;
@using System.ComponentModel.DataAnnotations;
@using System.Configuration;
@using Encryption_Handler;
@inject SearchService searchService
@inject SearchDropDownService searchDropDownService
@inject IJSRuntime JsRuntime
@implements IDisposable
<EditForm Model="formValues" OnValidSubmit="@SearchTransactions">
<DataAnnotationsValidator />
<MatThemeProvider Theme="@theme">
<div class="row formRow">
<div class="col-12 text-center pb-4">
<MatDatePicker Label="Transaction Date" @bind-Value="@formValues.startDate" EnableTime="true"></MatDatePicker>
<ValidationMessage For="@(() => formValues.startDate)" />
</div>
<div class="col-4 text-center">
<MatSelect Label="Region" @bind-Value="@formValues.Region">
@foreach (var region in Regions)
{
<MatOptionString Value="@region.RegionCode.ToString()">@region.RegionName</MatOptionString>
}
</MatSelect>
</div>
<div class="col-4 text-center">
<MatSelect Label="MCC" @bind-Value="@formValues.Mcc">
@foreach (var MCode in MCCs)
{
<MatOptionString Value="@MCode.Mcc">@MCode.Mcc - @MCode.Description</MatOptionString>
}
</MatSelect>
</div>
<div class="col-4 text-center">
<MatTextField @bind-Value="@formValues.MerchantID" Label="Merchant ID"></MatTextField>
<ValidationMessage For="@(() => formValues.MerchantID)" />
</div>
<div class="col-4 text-center">
<MatSelect Label="Transaction Currency" @bind-Value="@formValues.CurrencyCode">
@foreach (var CCode in CurrencyCodes)
{
<MatOptionString Value="@CCode.Numeric">@CCode.Numeric - @CCode.ShortName</MatOptionString>
}
</MatSelect>
</div>
<div class="col-4 text-center">
<MatTextField @bind-Value="@formValues.TerminalID" Label="Terminal ID"></MatTextField>
<ValidationMessage For="@(() => formValues.TerminalID)" />
</div>
<div class="col-4 text-center">
<MatTextField @bind-Value="@formValues.TxnAmount" Label="Transaction Amount"></MatTextField>
</div>
<div class="col-4 text-center">
<MatTextField maxlength="8" @bind-Value="@formValues.BIN" Label="BIN"></MatTextField>
<ValidationMessage For="@(() => formValues.BIN)" />
</div>
<div class="col-4 text-center">
<MatSelect Label="Message Type" @bind-Value="@formValues.MessageType">
@foreach (var MType in MessageTypes)
{
<MatOptionString Value="@MType.MessageType">@MType.MessageType - @MType.Description</MatOptionString>
}
</MatSelect>
</div>
<div class="col-4 text-center">
<MatTextField maxlength="19" @bind-Value="@formValues.MaskedPan" Label="Masked PAN"></MatTextField>
<ValidationMessage For="@(() => formValues.MaskedPan)" />
</div>
<div class="col-4 text-center">
<MatSelect Label="Processing Code" @bind-Value="@formValues.ProcessingCode">
@foreach (var procCode in ProcessingCodes)
{
<MatOptionString Value="@procCode.ProcessingCode"> @procCode.ProcessingCode - @procCode.Description</MatOptionString>
}
</MatSelect>
</div>
<div class="col-4 text-center">
<MatTextField maxlength="19" @bind-Value="@formValues.ClearPan" Label="Clear PAN"></MatTextField>
<ValidationMessage For="@(() => formValues.ClearPan)" />
</div>
<div class="col-4 text-center">
<MatSelect Label="Response Code" @bind-Value="@formValues.ResponseCode">
@foreach (var ResCode in ResponseCodes)
{
<MatOptionString Value="@ResCode.ResponseCode">@ResCode.ResponseCode - @ResCode.Description</MatOptionString>
}
</MatSelect>
</div>
<div class="col-4 text-center">
<MatTextField maxlength="6" @bind-Value="@formValues.AuthCode" Label="Authorization Code"></MatTextField>
<ValidationMessage For="@(() => formValues.AuthCode)" />
</div>
<div class="col-4 text-center pb-4">
<MatSelect Label="Entry Code" @bind-Value="@formValues.EntryCode">
@foreach (var entryCode in EntryModes)
{
<MatOptionString Value="@entryCode.EntryCode">@entryCode.EntryModeDescription</MatOptionString>
}
</MatSelect>
</div>
</div>
<div class="row text-right pt-3">
<div class="col-12 text-right">
<MatButton Raised="true" Type="submit">Search</MatButton>
</div>
</div>
</MatThemeProvider>
</EditForm>
@if (transactions == null)
{
}
else
{
<table class="table">
<thead>
<tr>
<th>Transaction Date</th>
<th>Merchant ID</th>
<th>Terminal ID</th>
<th>Trace</th>
<th>Amount</th>
<th>Currency</th>
<th>Authorization Code</th>
<th>Response Code</th>
<th>Masked PAN</th>
<th>PAN</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var transaction in NextTransactions)
{
<tr class="tableInfo">
<td>@transaction.TransactionDateTime</td>
<td>@transaction.MerchantID</td>
<td>@transaction.TerminalID</td>
<td>@transaction.SystemTrace</td>
<td>$@transaction.TransactionAmount</td>
<td>@transaction.Currency</td>
<td>@transaction.AuthorizationCode</td>
<td>@transaction.ResponseCode</td>
<td>@transaction.PANM</td>
<td id="@transaction.ID">@ClearPAN</td>
<td class="btn btn-warning" @onclick="@(e => UnmaskPan(transaction.IV, transaction.PAN))">Unmask</td>
</tr>
<tr>
<td colspan="12">
<MatAccordion Class="w-100">
<MatExpansionPanel>
<MatExpansionPanelSummary>
<MatExpansionPanelHeader Class=" w-100 text-center">Details</MatExpansionPanelHeader>
</MatExpansionPanelSummary>
<MatExpansionPanelDetails>
<table class="table">
<thead>
<tr>
<th>Acquirer ID</th>
<th>Merchant Name</th>
<th>MCC</th>
<th>Message Type</th>
<th>Processing Code</th>
<th>Entry Mode</th>
<th>Condition Code</th>
<th>Network Transaction ID</th>
<th>Network POS Data</th>
<th>Service Code</th>
</tr>
</thead>
<tbody>
<tr>
<td>@transaction.AcquirerID</td>
<td>@transaction.MerchantNameAddress</td>
<td>@transaction.MerchantCategoryCode</td>
<td>@transaction.MessageType</td>
<td>@transaction.ProcessingCode</td>
<td>@transaction.PosEntryMode</td>
<td>@transaction.PosConditionCode</td>
<td>@transaction.NetworkTransactionID</td>
<td>@transaction.NetworkPOSData</td>
<td>@transaction.ServiceCode</td>
</tr>
</tbody>
</table>
</MatExpansionPanelDetails>
</MatExpansionPanel>
</MatAccordion>
</td>
</tr>
}
</tbody>
</table>
@if (StopLoading)
{
<div>
<h4>End Of List</h4>
</div>
}
<div id="list-end" class="mt-5 mb-5 p-5">
<p></p>
@if (IsLoading)
{
<div class="d-flex justify-content-center">
<div class="spinner-grow" style="width: 3rem; height: 3rem;" role="status">
<span class="sr-only">Loading...</span>
</div>
</div>
}
</div>
@*<input type="button" value="More Results" @onclick="@MoreResults" />*@
}
@code {
MatTheme theme = new MatTheme()
{
Primary = "#002888",
Secondary = "#EFD409"
};
FormValues formValues = new FormValues();
public class FormValues
{
[Required]
public DateTime startDate { get; set; } = DateTime.Now;
public string Region { get; set; }
public string Mcc { get; set; }
[MaxLength(15, ErrorMessage = "Merchant ID cannot be longer than 15 characters")]
public string MerchantID { get; set; }
[MaxLength(8, ErrorMessage = "Terminal ID cannot be longer than 8 characters")]
public string TerminalID { get; set; }
public decimal TxnAmount { get; set; }
[RegularExpression("^[0-9]*$", ErrorMessage = "BIN must be numeric")]
public string BIN { get; set; }
[RegularExpression("^[0-9]*$", ErrorMessage = "Masked PAN must be numeric")]
public string MaskedPan { get; set; }
[RegularExpression("^[0-9]*$", ErrorMessage = "Clear PAN must be numeric")]
public string ClearPan { get; set; }
public string AuthCode { get; set; }
public string CurrencyCode { get; set; }
public string MessageType { get; set; }
public string ProcessingCode { get; set; }
public string ResponseCode { get; set; }
public string EntryCode { get; set; }
}
private List<TransactionModel> transactions { get; set; }
private PaginationDTO pagination = new PaginationDTO();
private List<TransactionModel> NextTransactions = new List<TransactionModel>();
private string ClearPAN;
public string txnID { get; set; }
public List<CommonMerchantCatagoryCodes> MCCs;
public List<CommonCurrencyCodes> CurrencyCodes;
public List<CommonPosmessageTypeRecords> MessageTypes;
public List<CommonPosprocessingCodeRecords> ProcessingCodes;
public List<CommonResponseCodeRecords> ResponseCodes;
public List<EntryModes> EntryModes = new List<EntryModes>
{
new EntryModes{EntryCode= "05", EntryModeDescription = "Chip Card"},
new EntryModes{EntryCode= "92", EntryModeDescription = "Chip Card - Fallback"},
new EntryModes{EntryCode= "02", EntryModeDescription = "Magnetic Stripe"},
new EntryModes{EntryCode= "94", EntryModeDescription = "Magnetic Stripe - No AID"},
new EntryModes{EntryCode= "01", EntryModeDescription = "Manually Keyed"},
new EntryModes{EntryCode= "07", EntryModeDescription = "NFC"}
};
public List<Regions> Regions = new List<Regions>
{
new Regions{RegionCode = "419733", RegionName = "Antigua and Barbuda (05)"},
new Regions{RegionCode = "457947", RegionName = "Aruba (16)"},
new Regions{RegionCode = "457944", RegionName = "Bahamas (02)"},
new Regions{RegionCode = "457944", RegionName = "Bahamas - Agency (32)"},
new Regions{RegionCode = "483172", RegionName = "Barbados (15)"},
new Regions{RegionCode = "419640", RegionName = "Bonaire (17)"},
new Regions{RegionCode = "457946", RegionName = "Cayman Islands (07)"},
new Regions{RegionCode = "419639", RegionName = "Curaçao (13)"},
new Regions{RegionCode = "483174", RegionName = "Grenada (09)"},
new Regions{RegionCode = "419641", RegionName = "Saba (18)"},
new Regions{RegionCode = "419735", RegionName = "Saint Kitts and Nevis (11)"},
new Regions{RegionCode = "419736", RegionName = "Saint Lucia (12)"},
new Regions{RegionCode = "483173", RegionName = "Saint Vincent (20)"},
new Regions{RegionCode = "419638", RegionName = "Sint Maarten (Dutch part) (19)"},
new Regions{RegionCode = "415536", RegionName = "Trinidad and Tobago (03)"},
new Regions{RegionCode = "457945", RegionName = "Turks and Caicos Islands (14)"},
};
protected override async Task OnInitializedAsync()
{
MCCs = searchDropDownService.GetAllMCCs().ToList();
CurrencyCodes = searchDropDownService.GetAllCurrencies().ToList();
MessageTypes = searchDropDownService.GetAllMessages().ToList();
ProcessingCodes = searchDropDownService.GetAllProcessingCodes().ToList();
ResponseCodes = searchDropDownService.GetAllResponseCodes().ToList();
}
async Task SearchTransactions()
{
NextTransactions.Clear();
await LoadMore();
await InitJsListenerAsync();
}
bool IsLoading { get; set; } = false;
//int PageSize = 30;
int PageNumber = 0;
bool StopLoading = false;
protected async Task InitJsListenerAsync()
{
await JsRuntime.InvokeVoidAsync("ScrollList.Init", "list-end", DotNetObjectReference.Create(this));
}
[JSInvokable]
public async Task LoadMore()
{
if (!IsLoading)
{
IsLoading = true;
StateHasChanged();
await Task.Delay(1000);
//for (int i = 0; i < pagination.Page; i++)
transactions = await searchService.SearchNextResults(formValues.startDate, formValues.Region, formValues.Mcc, formValues.MerchantID, formValues.CurrencyCode, formValues.TerminalID, formValues.TxnAmount, formValues.BIN, formValues.MessageType, formValues.MaskedPan, formValues.ProcessingCode, formValues.ClearPan, formValues.ResponseCode, formValues.AuthCode, formValues.EntryCode, pagination);
//}
pagination.Page++;
foreach (var txn in transactions)
{
NextTransactions.Add(txn);
}
PageNumber++;
IsLoading = false;
StateHasChanged();
//at the end of pages or results stop loading anymore
if (PageNumber > 50)
{
await StopListener();
}
}
}
public async Task StopListener()
{
StopLoading = true;
IsLoading = false;
await JsRuntime.InvokeVoidAsync("ScrollList.RemoveListener");
StateHasChanged();
}
public void Dispose()
{
JsRuntime.InvokeVoidAsync("ScrollList.RemoveListener");
}
protected void UnmaskPan(string IV, string PAN)
{
ExcryptProvider exp = new ExcryptProvider("10.61.131.14", 9000, false);
try
{
var currentRecord = exp.DecryptASCIICBC(searchDropDownService.GetDataEncryptionKey().ToString(), IV, PAN).Replace("\0", string.Empty);
ClearPAN = currentRecord;
}
catch (Exception)
{
var currentRecord = "Decryption Error";
ClearPAN = currentRecord;
}
}
}