Если об ошибке нужно уведомить пользователя (чтобы можно было исправить данные в форме), то лучший способ уведомить пользователя - использовать exception
вместо использования загадочных кодов ошибок для обозначения ошибки.
Предположим, у вас есть метод в модуле Validation
, который принимает экземпляр Invoice
, тогда код в методе Validate()
должен выглядеть примерно так:
Подход 1: перерыв при первом обнаружении исключения
public void Validate(Invoice invoiceInstance)
{
foreach(InvoiceDetail invoiceDetail in invoiceInstance.InvoiceDetailsList)
{
if(invoiceDetail.quantity < 0)
{
throw new InvoiceDetailException("The invoice detail quantity is less than zero", InvoiceDetailExceptionType.Quantity, invoiceDetail);
}
// Validate other details
}
}
и в пользовательском интерфейсе catch
the exception
и его обработка,
try
{
businessLayer.Validate();
}
catch(InvoiceDetailException invoiceDetailException)
{
MessageBox.Show(invoiceDetailException.Message);
}
Пользовательский InvoiceException
может быть создан следующим образом:
[Serializable]
public class InvoiceDetailException : Exception
{
public InvoiceDetailExceptionType ExceptionType {get; private set;}
public InvoiceDetail Detail {get; private set; }
public InvoiceDetailException () { }
public InvoiceDetailException (string message, InvoiceDetailExceptionType exType, InvoiceDetail detail) : base(message)
{
this.ExceptionType = exType;
this.Detail = detail;
}
public InvoiceDetailException (string message, Exception inner) : base(message, inner) { }
protected InvoiceDetailException (
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
И перечисление InvoiceDetailExceptionType
:
public enum InvoiceDetailExceptionType
{
Quantity,
ProductId
}
Подход 2: Показать совокупные исключения
Классы сущностей,
class Invoice
{
public int Id { get; set; }
public List<InvoiceDetail> Details { get; set; }
public Invoice()
{
Details = new List<InvoiceDetail>();
}
}
class InvoiceDetail
{
public int InvoiceId
{ get; set; }
public int Quantity
{ get; set; }
public int ProductId
{ get; set; }
}
Валидатор
static class InvoiceValidator
{
public static void Validate(Invoice invoice)
{
List detailsException = new List<InvoiceDetailException>();
foreach (InvoiceDetail detail in invoice.Details)
{
try
{
ValidateDetail(detail);
}
catch (InvoiceDetailException detailException)
{
detailsException.Add(detailException);
}
}
InvoiceException invoiceException = null;
if (invoice.Id < 0)
{
// If error in the invoice field
invoiceException = new InvoiceException("InvoiceId is invalid");
}
// Validate other fields of invoice...
if (detailsException.Count > 0)
{
// If error in the details list
if (invoiceException == null)
{
// If there is no error in the invoice field, then error only in details
invoiceException = new InvoiceException("Exception only in details", detailsException);
}
else
{
// If there is error in invoice field as well as details
invoiceException.DetailExceptionList = detailsException;
}
}
if (invoiceException != null)
{
// If there is an error then throw exception
throw invoiceException;
}
}
private static void ValidateDetail(InvoiceDetail detail)
{
if (detail.Quantity <= 0)
{
throw new InvoiceDetailException("Quantity is invalid", InvoiceDetailExceptionType.Quantity, detail.InvoiceId, detail.ProductId);
}
// Validate other fields of invoice details...
}
}
Пользовательские исключения,
[Serializable]
public class InvoiceDetailException : Exception
{
public InvoiceDetailExceptionType DetailExceptionType { get; private set; }
public int InvoiceId { get; private set; }
public int ProductId { get; private set; }
public InvoiceDetailException() { }
public InvoiceDetailException(string message, InvoiceDetailExceptionType exceptionType, int invoiceId, int productId)
: base(message)
{
this.DetailExceptionType = exceptionType;
this.InvoiceId = invoiceId;
this.ProductId = productId;
}
public InvoiceDetailException(string message, Exception inner) : base(message, inner) { }
protected InvoiceDetailException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
[Serializable]
public class InvoiceException : Exception
{
public List<InvoiceDetailException> DetailExceptionList { get; set; }
public InvoiceException() { }
public InvoiceException(string message): base(message) { }
public InvoiceException(string message, List detailsExceptions) : base(message)
{
DetailExceptionList = detailsExceptions;
}
public InvoiceException(string message, Exception inner) : base(message, inner) { }
protected InvoiceException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
Перечисление типа исключения,
public enum InvoiceDetailExceptionType
{
Quantity,
ProductId
}
И, наконец, вызов валидатора,
try
{
InvoiceValidator.Validate(invoice);
}
catch (InvoiceException invoiceException)
{
MessageBox.Show(invoiceException.Message);
if (invoiceException.DetailExceptionList != null && invoiceException.DetailExceptionList.Count > 0)
{
Console.WriteLine("Exception in details :");
foreach (InvoiceDetailException detailException in invoiceException.DetailExceptionList)
{
string printMessage = string.Format("{0}, InvoiceId = {1}, ProductId = {2}", detailException.Message, detailException.InvoiceId, detailException.ProductId);
Console.WriteLine(printMessage);
}
}
// If you want the caller to further handle the exception
//throw;
}
Дополнительная информация