在我们的应用程序中,WCF 层中的 PublicManagerService 类显示出指数级增长的迹象,这导致方法暴露在公共 API 中,这可能导致我们的安全风险增加、恶意攻击的入口以及性能下降.
这方面的一个例子可以在我们的 AccountController 类中看到,在用户单击电子邮件中的超链接时使用的 Accept 和 Decline 方法中。对公共 API 中的方法进行以下调用:
- 通过 GUID 获取事务电子邮件日志
- UpdateTransactionHitCount
- 保存审批日志
- 生成PDF
- 上传BlobByType
- SetCurrentCulture(这被其他方法使用,但是可能会保留)
- 发送电子邮件
我们的目标应该是只公开一种方法来执行 Accept 过程,对于 Decline 方法也是如此,它使用完全相同的调用。
/// <summary>
/// Response to Accept
/// </summary>
/// <param name="guid"></param>
/// <param name="comment"></param>
/// <returns></returns>
public ActionResult Accept(string guid,string comment)
{
Gateway.Instance.Logger.LogDebug("[Accept] method entered.");
IEnumerable<TransactionEmailLog> transactionEmailLogs = _publicServiceManager.GetTransactionEmailLogByGUID(guid.Trim());
ViewBag.GUID = guid.Trim();
if (transactionEmailLogs != null && transactionEmailLogs.Count() > 0)
{
var transactionEmailLog = transactionEmailLogs.FirstOrDefault();
if (transactionEmailLog.HitCount < 50)
{
_publicServiceManager.UpdateTransactonHitCount(transactionEmailLog.GUID);
var transaction = transactionEmailLog.Transaction;
if (transaction != null)
{
ViewBag.InvoiceDate = transaction.InvoiceIssueDate != null ? Convert.ToDateTime(transaction.InvoiceIssueDate).ToShortDateString() : "";
ViewBag.InvoiceNumber = transaction.InvoiceNumber != null ? Convert.ToString(transaction.InvoiceNumber) : "";
ViewBag.DueDate = transaction.PaymentDueDate != null ? Convert.ToDateTime(transaction.PaymentDueDate).ToShortDateString() : "";
ViewBag.AmountDue = transaction.PaymentDueDate != null ? transaction.CurrencyCode + " " + Convert.ToDecimal(transaction.InvoiceTotalPayable, CultureInfo.CurrentCulture.NumberFormat).ToString("N") : "";
}
ViewBag.IsAcceptOrDecline = "True";
TransactionApprovalLog approvalLog = new TransactionApprovalLog { IsAccepted = true, CreatedBy = transactionEmailLog.ReferredTo, CreatedDate = DateTime.UtcNow, Transaction = transaction };
if (!string.IsNullOrWhiteSpace(comment))
{
approvalLog.Comments = comment;
}
this._publicServiceManager.SaveApprovalLog(approvalLog);
if (transaction != null)
{
this.SendEmailNotficationOfInvoiceVerification(transaction, guid, comment, Language.Accepted, transactionEmailLog);
}
}
}
ViewBag.Message =Language.InvoiceVerificationAcceptMessage;
Gateway.Instance.Logger.LogDebug("[Accept] method exited.");
if (Request.IsAjaxRequest())
{
return Json(new { result = "success" }, JsonRequestBehavior.AllowGet);
}
return View("InvoiceVerification");
}
如您所见,“_publicServiceManager”中有许多不同的公开方法。我所做的是创建一个 DataContract 对象,其中包含 GUID、CultureName 等所需的信息,我的目标是将其传递给 PublicManagerService 中的一个新方法。
public void VerifyInvoice (InvoiceVerificationDataContract invoiceVerificationDetails){}
我的问题是,我将如何最好地处理此代码的重构?我应该在 WCF 层中有任何逻辑,还是应该全部保留在业务层中?非常感谢您提前提出的所有建议。