Chúng tôi thực hiện phần lớn các quy tắc kinh doanh của chúng tôi trong cơ sở dữ liệu, sử dụng procs được lưu trữ.Làm cách nào để xử lý các vi phạm ràng buộc db trong giao diện người dùng?
Tôi không bao giờ có thể quyết định cách tốt nhất để truyền dữ liệu ràng buộc các lỗi vi phạm từ cơ sở dữ liệu trở lại giao diện người dùng. Những hạn chế mà tôi đang nói đến được gắn liền với quy tắc kinh doanh hơn là tính toàn vẹn dữ liệu.
Ví dụ: lỗi db như "Không thể chèn hàng khóa trùng lặp" giống với quy tắc kinh doanh "bạn không thể có nhiều hơn một Foo có cùng tên". Nhưng chúng tôi đã "triển khai" nó ở vị trí có ý nghĩa phổ biến nhất: là một ràng buộc duy nhất cho phép ngoại lệ khi quy tắc bị vi phạm.
Các quy tắc khác như "Bạn chỉ được phép 100 Foos mỗi ngày" không gây ra lỗi cho mỗi người nói, vì chúng được xử lý một cách duyên dáng bằng mã tùy chỉnh như return empty dataset
mà mã ứng dụng kiểm tra và chuyển về lớp ui.
Và trong đó có chà. đang ui của chúng tôi trông như thế này (đây là AJAX.NET webservices mã, nhưng bất kỳ khuôn khổ ajax sẽ làm):
WebService.AddFoo("foo", onComplete, onError); // ajax call to web service
function onComplete(newFooId) {
if(!newFooId) {
alert('You reached your max number of Foos for the day')
return
}
// update ui as normal here
}
function onError(e) {
if(e.get_message().indexOf('duplicate key')) {
alert('A Foo with that name already exists');
return;
}
// REAL error handling code here
}
(Như một mặt lưu ý: Tôi nhận thấy đây là những gì stackoverflow làm khi bạn gửi ý kiến quá nhanh: máy chủ tạo ra một phản hồi HTTP 500
và ui bắt được nó.)
Vì vậy, bạn thấy, chúng tôi đang xử lý vi phạm quy tắc kinh doanh ở hai nơi ở đây, một trong số đó (tức là lỗi constaint duy nhất) đang được xử lý như trường hợp đặc biệt mã được cho là xử lý lỗi thực sự (không vi phạm quy tắc kinh doanh), vì .NET truyền bá Ngoại lệ tất cả các cách lên đến trình xử lý onError()
.
Điều này cảm thấy sai. lựa chọn của tôi, tôi nghĩ là:
- bắt các 'chủ chốt vi phạm bản sao' ngoại lệ ở cấp máy chủ ứng dụng và chuyển đổi nó để bất cứ điều gì nó là ui hy vọng là "quy tắc kinh doanh vi phạm" cờ,
- preempt lỗi (giả sử, với số
"select name from Foo where name = @Name"
) và trả về bất kỳ máy chủ ứng dụng nào được mong đợi là cờ "quy tắc kinh doanh bị vi phạm", - trong cùng một ballpark như 2): tận dụng ràng buộc duy nhất được xây dựng trong lớp db và mù quáng
insert into Foo
, bắt bất kỳ ngoại lệ nào và chuyển đổi ngoại lệ thành bất kỳ ứng dụng nào r dự kiến là "quy tắc kinh doanh vi phạm" cờ - mù quáng
insert into Foo
(như 3) và để cho Ngoại lệ đó lan truyền đến ui, và có máy chủ ứng dụng tăng vi phạm quy tắc kinh doanh làExceptions
thực (trái ngược với 1). Bằng cách này, tất cả các lỗi được xử lý trong mãonError()
(hoặc tương tự) của lớp ui.
Điều tôi thích về 2) và 3) là vi phạm quy tắc kinh doanh được "ném" nơi chúng được triển khai: trong proc được lưu trữ. Những gì tôi không thích về 1) và 3) là tôi nghĩ rằng chúng liên quan đến kiểm tra ngu ngốc như "if error.IndexOf('duplicate key')"
, giống như những gì đang có trong lớp ui hiện tại.
Sửa: Tôi thích 4), nhưng hầu hết mọi người nói để sử dụng Exception
s chỉ trong đặc biệt hoàn cảnh.
Vì vậy, làm cách nào để mọi người xử lý việc vi phạm quy tắc kinh doanh đến thanh lịch?
Tôi muốn người đã bỏ phiếu này và http://stackoverflow.com/questions/581994/-net-coding-standards-and-framework-for-a-web-service/582429#582429 sẽ đưa ra lý do. Hai câu trả lời rất khác nhau, cùng một kết quả, trong vòng một phút. –
Mã mà cuối cùng gọi là "RAISERROR' sẽ vẫn cần thực hiện" kiểm tra ngu ngốc "như' CHARINDEX ('khóa trùng lặp', @errorMessage)> 0' và tôi tìm thấy câu hỏi này vì kịch bản ví dụ của tôi liên quan đến * hai * khóa duy nhất tiềm năng hạn chế vi phạm và tôi đã tò mò liệu có một số cách để xác định khóa nào đã bị vi phạm mà không tìm kiếm tên của các khóa hoặc tên của các cột có liên quan. –