我正在将业务逻辑代码从我的控制器转移到业务类。我的页面需要大量的用户输入验证。这在我的代码中创建了许多嵌套级别。所以我在业务层重新编写了代码,如下所示:
public RmaDetail SerialNumberScan(int rmaNumber, int serialNumber, RepairInvoice repairInvoice) {
var result = SelectRmaDetail(rmaNumber, serialNumber);
if (result != null) throw new BusinessException("Serial Number not found.");
if (result.Received != 1) throw new BusinessException("Line item has not been received.");
bool? workOrderClosed = WorkOrderClosed(result.LNSEQNBR, result.LNSEQNBR, serialNumber);
if (!workOrderClosed.HasValue) throw new BusinessException("Work order not found.");
if (workOrderClosed.Value == false) throw new BusinessException("Work order not closed.");
repairInvoice.TerminalType = result.ITEMNMBR.Trim();
repairInvoice.UnderWarranty = RepairInvoiceDataLayer.UnderWarranty(result.RETDOCID, result.LNSEQNBR, serialNumber, result.CUSTNMBR);
return result;
}
这是我的控制器:
public ActionResult SerialNumberScan(string rmaNumber, string serialNumber)
{
if (ModelState.IsValid)
{
ModelState["SerialNumber"].Value = new ValueProviderResult(serialNumber, serialNumber, CultureInfo.CurrentCulture);
try
{
var rmaDetail = BusinessLayer.SerialNumberScan(rmaNumber, serialNumber, repairInvoice);
Session["RmaDetail"] = rmaDetail;
ViewBag.SetFocusTo = "#RepairLevels";
}
catch (BusinessException ex)
{
ViewBag.AlertMessage = ex.Message;
}
}
return View("Index", repairInvoice);
}
行ViewBag.AlertMessage
是显示在我页面顶部的消息。我喜欢这种方法,因为它非常易读。但是,我知道异常非常昂贵。有更好的方法吗?
答案 0 :(得分:2)
只有当您将它们作为正常程序流程的一部分抛出时,异常才会变得昂贵。一般情况下,应该使用异常来处理异常情况,因此您的用例肯定符合条件:缺少序列号或行项目的情况确实异常。
但是,我要改变的一件事是使用相同的异常(即BusinessException
)来处理所有验证。一方面,这使得您的代码非常简单,因为您总是抛出相同的异常 - 唯一不同的是消息。另一方面,它会以不同的方式消除您处理每种情况的灵活性。
我认为向BusinessException
引入sublcasses会带来更好的方法。添加新的异常 - 在这种情况下,MissingSerialNumber
和MissingLineItem
异常,使它们成为BusinessException
的子类,以便您可以根据需要一起处理它们,并在这些点使用无参数构造函数你抛出这些例外的地方。
答案 1 :(得分:2)
首先,例外情况只有在被抛出时才会很昂贵。如果出现问题,应该抛出它们。在性能方面,我不认为你应该在这种情况下担心它,我们不是在这里谈论秒,我们谈的是毫秒。用户肯定不会注意到抛出异常并告诉他们的费用。
同样偏离主题,您可以编写一个扩展方法,例如:
public static void Throw<T>(this bool expression, string alert) where T : Exception
{
if (!expression)
throw (T)Activator.CreateInstance(typeof(T), alert);
}
然后你可以用:
替换所有if / throw检查(result.Received != 1).Throw<BusinessException>("message");