1

在我们的应用程序中,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 层中有任何逻辑,还是应该全部保留在业务层中?非常感谢您提前提出的所有建议。

4

1 回答 1

1

我认为重构此代码的第一步是将您对 Accept 和 Decline 操作的调用包装在某种集成测试中。

这将允许您在知道您不会倒退或损害整个过程的情况下对服务的组合进行处理。

这个流程看起来好像是对某种业务流程进行建模,因此要将其整合到一组整合的公共操作中,我想您需要解决以下问题:

  • 是否每个步骤都需要成功执行才能使整体操作成功?
  • 每个步骤都必须按特定顺序执行吗?
  • 您将如何处理一个或多个步骤中的故障/恢复?
  • 组合单独的功能是否有意义?
  • 整体业务流程是否需要同步调用?

您可能已经考虑了所有这些要点以及更多内容,因此此答案可能没有太大价值,但很难以当前形式回答您的问题。您可以将命令处理器模式视为解耦过程中各个步骤的一种方式。

欣赏这并不能直接回答您的问题。

于 2013-09-04T10:26:37.473 回答