.Net Fluent Validation กำหนดลำดับการดำเนินการ

ฉันต้องตั้งค่าลำดับการดำเนินการสำหรับการตรวจสอบเพื่อหยุดการตรวจสอบหลังจากความล้มเหลวครั้งแรก

อย่างไรก็ตาม สิ่งนี้ไม่พร้อมใช้งาน ดังนั้นฉันจึงสงสัยว่ามีวิธีอื่นในการดำเนินการนี้อย่างไร

โดยปกติฉันจะมีสิ่งนี้:

public Constructor(){

    // Simple validation
    RuleFor(x => x.Id).NotNull().NotEmpty();

    // advanced validation
    // item must exist in database
    RuleFor(x => x.Id).Must(ExistsInDatabase);

    // item must exist in database previously
    // item must be some of the allowed names -- fetched from db
    RuleFor(x => x.Id).Must(BeAReferenceInSomeTable);

    private bool ExistsInDatabase(){}

    private bool BeAReferenceInSomeTable(){}

}

แต่ด้วย BeAReferenceInSomeTable นี้สามารถดำเนินการได้ก่อน ExistsInDatabase ดังนั้นการตรวจสอบ BeAReferenceInSomeTable จะทำให้เกิดข้อยกเว้นเมื่อไม่มี Id ในตารางแทนที่จะตรวจสอบล้มเหลวเนื่องจากการตรวจสอบ ExistsInDatabase

ในการแก้ไขปัญหานี้ก่อนอื่นที่นึกถึงมีดังนี้:

public Constructor(){

    CascadeMode = FluentValidation.CascadeMode.StopOnFirstFailure;

    // simple validation stays the same
    ...

    // advanced validation
    RuleFor(x => x.Id)
        .Must(ExistsInDatabase)
        .Must(BeAReferenceInSomeTable)
        .When(x => !string.IsNullOrEmpty(x.Id) &&
                    !string.IsNullOrEmpty(x.Name)
        );  
}

แต่ในกรณีนี้ ฉันจะตั้งค่าข้อความที่เหมาะสมเพื่อการตรวจสอบได้อย่างไร เนื่องจากจะต้องได้รับข้อความก่อนดำเนินการ


person Matija K.    schedule 12.06.2014    source แหล่งที่มา
comment
คุณสามารถใช้ .WithMessage("your message"); เพื่อเพิ่มข้อความที่เหมาะสมสำหรับการตรวจสอบความถูกต้องที่ล้มเหลว และวิธีนี้ใช้ได้กับการผูกมัดด้วยเช่นกัน (ซึ่งเป็นสิ่งที่คุณกำลังทำในตัวอย่างที่สองของคุณ)   -  person Moo    schedule 12.06.2014
comment
ใช่ แต่ ExistsInDatabase ควรส่งคืน: Id ไม่มีหมายเหตุอยู่ในฐานข้อมูล และ BeAReference ควรส่งคืน: Id ไม่ได้ถูกอ้างอิงในบางตาราง ด้วย WithMessage คุณสามารถส่งผ่านสตริงที่กำหนดไว้ล่วงหน้าแบบคงที่เท่านั้น แต่นี่ไม่ดีเลยเพราะฉันต้องการเพียง 1 ข้อความเท่านั้นที่จะส่งคืน   -  person Matija K.    schedule 12.06.2014


คำตอบ (1)


ลองสิ่งนี้:

public Constructor(){

    // Simple validation
    RuleFor(x => x.Id).Cascade(CascadeMode.StopOnFirstFailure).NotNull().WithMessage("Must not be null");

    RuleFor(x => x.Id).NotEmpty().WithMessage("Must not be empty");


    // advanced validation
    // item must exist in database
    RuleFor(x => x.Id).Must(ExistsInDatabase).WithMessage("Must exist in database");

    // item must exist in database previously
    // item must be some of the allowed names -- fetched from db
    RuleFor(x => x.Id).Must(BeAReferenceInSomeTable).WithMessage("Must not be referenced");

    private bool ExistsInDatabase(){}

    private bool BeAReferenceInSomeTable(){}

}

และถูกล่ามโซ่เพื่อสั่งการ:

RuleFor(x => x.Id).Cascade(CascadeMode.StopOnFirstFailure)
    .NotNull().WithMessage("Must not be null")
    .NotEmpty().WithMessage("Must not be empty")
    .Must(ExistsInDatabase).WithMessage("Must exist in database")
    .Must(BeAReferenceInSomeTable).WithMessage("Must not be referenced");
person Moo    schedule 12.06.2014
comment
เมื่อคุณตั้งค่าโหมด Cascade ในบรรทัดแรก โหมดนั้นจะถูกใช้สำหรับเชนนั้นเท่านั้น ดังนั้นการใช้โดยไม่มีเงื่อนไขหลายข้อจึงไม่มีผล โค้ดที่เหลือนำฉันไปสู่ปัญหาเดียวกันกับที่เปิดหัวข้อ ด้วยข้อความที่คุณเพิ่มจะทำให้เกิดข้อผิดพลาดในการตรวจสอบที่ถูกต้อง แต่การตรวจสอบอาจไม่ดำเนินการตามลำดับ - person Matija K.; 12.06.2014
comment
จากนั้นใช้การผูกมัดเพื่อให้ได้คำสั่งดำเนินการ - person Moo; 12.06.2014
comment
ฉันขยายตัวอย่างของคุณเพื่อให้ได้สิ่งที่ฉันต้องการ แต่นี่เป็นการดำเนินการที่ซ้ำซ้อน คุณคิดว่ามีวิธีที่ดีกว่านี้หรือไม่? ฉันจะทำเครื่องหมายโซลูชันของคุณว่าถูกต้องเนื่องจากใกล้เคียงกับสิ่งที่ฉันต้องการ (แต่ยังไม่ใช่ทั้งหมด) RuleFor(x =› x.Id).Must(ExistsInDatabase).WithMessage(ต้องมีอยู่ในฐานข้อมูล).When(x =› x.Id.NotNullOrEmpty()) RuleFor(x =› x.Id).Must(BeAReferenceInSomeTable) .WithMessage(ต้องไม่ถูกอ้างอิง).เมื่อ(x =› x.NotNullOrEmpty() && ExistsInDatabase(x)); - person Matija K.; 12.06.2014
comment
มีการดำเนินการซ้ำซ้อนอะไรบ้าง? - person Moo; 12.06.2014
comment
สำหรับการตรวจสอบความถูกต้อง BeAReferenceInSomeTable ExistsInDatabase จะถูกดำเนินการก่อนการตรวจสอบความถูกต้อง สำหรับการตรวจสอบความถูกต้อง ExistsInDatabase วิธีการเดียวกันนี้จะถูกดำเนินการอีกครั้ง นี่ไม่ใช่ปัญหาสำหรับการทดสอบเล็กๆ นี้ แต่จะขยายในการทดสอบที่ใหญ่กว่า - person Matija K.; 12.06.2014
comment
ฉันไม่ได้คิดเลยว่าคุณสามารถเพิ่มข้อความแบบนั้นได้หลายข้อความ (ฉันคิดว่าอันสุดท้ายคงถูกใช้) นี่คือคำตอบที่ฉันกำลังมองหา ขอบคุณ - person Matija K.; 12.06.2014