باستخدام MVC و يجيد Nhibernate, كيف يمكنني التحقق من صحة فريدة من نوعها الحقول على ViewModel قبل أن ربط لهم إلى كائن المجال و حفظها ؟

StackOverflow https://stackoverflow.com/questions/1440440

سؤال

لدي موقع على شبكة الانترنت حيث تسمح للمستخدمين إنشاء جزء جديد السجلات.أنا في محاولة لمعرفة أفضل طريقة للتحقق من مجالات محددة من أجل التفرد.أريد أن تأكد من أن شخص ما لا تحاول أن إضافة جزء مع PartNumber 1234 إذا كان هذا PartNumber موجود بالفعل على جزء مختلف.

تطبيق ويب باستخدام Asp.net MVC مع يجيد nHibernate لرسم خرائط بلدي الكائنات في قاعدة البيانات.أنا باستخدام القلعة المصادقة على عرض نماذج لأشياء مثل ValidateNonEmpty, ValidateRange ، إلخ.يجب استخدام ValidateSelf طريقة الاستعلام عن مستودع لمعرفة ما إذا كان رقم الجزء بالفعل ؟ شيء لا يشعر الحق حول استخدام بلدي مستودع على ViewModel.

سيكون من الأفضل بالنسبة لي أن مكان هذا المنطق على وحدة تحكم العمل ؟ هذا لا يبدو صحيحا لأن أتوقع ViewModel أن يكون بالفعل التحقق من صحتها عند النقطة (خلال ModelBind).

أو ربما لا شيء مما سبق.شكرا على أي مساعدة على هذا واحد.

التحديث حسنا, لست متأكدا إذا كان هذا سوف يساعد ، ولكن هنا هو ما حفظ العمل يبدو نموذجية إنشاء العمل في المشروع:

public ActionResult Create(PartViewModel viewModel)
{
 //I think I'd like to know if its Valid by this point, not on _repository.Save
 if(ModelState.IsValid)
 {
    try
    {
        var part = _partCreateViewModelMap.MapToEntity(viewModel);

        _repository.Save(part);
        return Redirect("~/Part/Details/" + part.Id);
    }
    catch (Exception e)
    {
        // skip on down...
    }
 }

 // return view to edit 
 return View(viewModel);
}
هل كانت مفيدة؟

المحلول

لقد سئلت هذا السؤال مرات عديدة.أصدقائي كانوا قلقين حول ما إذا كان يمكن أن تؤدي الوصول إلى البيانات من مدقق رمز.الجواب بسيط.إذا كنت بحاجة إلى القيام بذلك ، يجب أن تفعل ذلك.عادة ما نحتاج إلى القيام به تلك الشيكات في كل مستوى من التجريد.و بعد كل الشيكات يجب أن تكون على استعداد للقبض استثناء ، الناجمة عن انتهاك القيد.

نصائح أخرى

إذا قمت بتعريف فريدة من نوعها القيد في قاعدة البيانات, ثم لماذا لا تفويض المسؤولية إلى التحقق من ما إذا كانت قيمة فريدة من نوعها بالفعل إلى قاعدة البيانات ؟ باستخدام NHibernate ، يمكنك استخدام NHibernate.Exceptions.ISQLExceptionConverter واجهة لالتقاط وتحويل أخطاء المعروفة المتعلقة القيد الانتهاكات.يمكنك أيضا استخدام NHibernate.Exceptions.IViolatedConstraintNameExtracter منفذي (انظر NHibernate.Exceptions.TemplatedViolatedConstraintNameExtracter) للحصول على ضيع تفاصيل قاعدة البيانات الخاصة بك استثناء ، وتحويلها إلى صديقة للمستخدم رسالة حزم مثل التحقق من صحة الاستثناء من تنحاز وقبض عليه في ذات تحكم.

مثال سريع جدا محددة سريعة وقذرة استثناء محول من أحد المشاريع:


Imports NHibernate
Imports NHibernate.Exceptions
Imports System.Data.SqlClient
Imports System.Data.Common

Namespace NHibernate

    Public Class ConstraintViolationExceptionConverter
        Implements ISQLExceptionConverter

        Public Function Convert(ByVal adoExceptionContextInfo As Global.NHibernate.Exceptions.AdoExceptionContextInfo) As System.Exception Implements Global.NHibernate.Exceptions.ISQLExceptionConverter.Convert

            Dim dbEx As DbException = ADOExceptionHelper.ExtractDbException(adoExceptionContextInfo.SqlException)

            If TypeOf dbEx Is SqlException Then
                Dim sqlError As SqlException = DirectCast(dbEx, SqlException)

                Select Case sqlError.Number
                    Case 547
                        Return New ConstraintViolationException(adoExceptionContextInfo.Message, adoExceptionContextInfo.SqlException)

                End Select

            End If

            Return SQLStateConverter.HandledNonSpecificException(adoExceptionContextInfo.SqlException, adoExceptionContextInfo.Message, adoExceptionContextInfo.Sql)

        End Function


    End Class

End Namespace

تكوين من خلال web.config/nhibernate-configuration/session-factory عنصر الملكية:


<property name="sql_exception_converter">csl.NHibernate.ConstraintViolationExceptionConverter, csl</property>

تحرير: ربما ينبغي الإشارة إلى أن تحويل واجهة تغير في الإصدارات الأخيرة من NHibernate ، واجهة من هذا المثال هو من NHibernate.dll v2.1.0.4000

أنا عادة وضع طبقة الخدمة بين وحدات التحكم و مستودعات.
خدمة طبقة ثم التعامل مع التحقق من صحة و يدعو إلى مستودع.

ثم إذا كان هناك خطأ في التحقق من صحة في خدمة طبقة أرمي مخصص استثناء ، قبض عليه في تحكم وحقن أخطاء في نموذج الدولة.

ليس لدي جواب لسؤالك لكن يمكنك التحقق sharparchitecture.net الموقع.أنه يحتوي على بعض أفضل practives على asp.net mvc و nhibernate.كما يمكن أن ننصح للتحقق xval المشروع و الدروس حول التحقق من صحة البيانات مع الشرح المصادقون

لقد وجدت الحل الذي يعمل بالنسبة لي هو

1.) اسأل إذا كان الكيان صالحة لتنفيذ التحقق من صحة العمل.
2.) بعد الانتهاء من ذلك يجب أن يكون شيئا على كائن تبين انها صحيحة أم لا (في حالة استخدام CSLA مثل مفهوم "كسر القواعد").
3.) إذا كان لديك شيء من هذا القبيل يمكنك التحقق من وجوه صحيحة قبل NHibernate يحاول أن تستمر كما هو موضح أدناه.

المشكلة الوحيدة مع هذا النهج هو أن تحتاج إلى تنفيذ واجهة على كل كيان تتطلب التحقق من الصحة.إذا كنت تستطيع العيش مع هذا سوف تتوقف NHibernate من استمرار التغييرات كائن غير صالحة وفقا القواعد الخاصة بك.

using System;
using NHibernate;
using NHibernate.Event;
using Validation.Entities.Interfaces;
using Persistence.SessionBuilder;

namespace Persistence.Validation
{
    public class ValidationEventListener : IPreInsertEventListener, IPreUpdateEventListener
    {

        public bool OnPreInsert(NHibernate.Event.PreInsertEvent @event)
        {
            var entityToInsert = @event.Entity as IBusinessBase;

            if (entityToInsert != null)
            {
                if (entityToInsert.BrokenRules != null)
                {
                    RollbackTransactionBecauseTheEntityHasBrokenRules();
                }
            }

            return false;
        }

        public bool OnPreUpdate(NHibernate.Event.PreUpdateEvent @event)
        {
            var entityToUpdate = @event.Entity as IBusinessBase;

            if (entityToUpdate != null)
            {
                if (entityToUpdate.BrokenRules != null)
                {
                    RollbackTransactionBecauseTheEntityHasBrokenRules();
                }
            }

            return false;
        }

        private void RollbackTransactionBecauseTheEntityHasBrokenRules()
        {
            try
            {
                ISession session = SessionBuilderFactory.GetBuilder().CurrentSession;

                if (session != null)
                {
                    session.Transaction.Rollback();
                }
            }
            catch (Exception ex)
            {
                //this will force a rollback if we don't have a session bound to the current context 
                throw new NotImplementedException();
            }
        }
    }
}

أود أن أقول هذه المسائل في الهندسة.مع MVC التطبيقات التي كنت قد فعلت في الماضي كنا مجردة بعيدا المجال الاشياء بعيدا عن شبكة الإنترنت الاشياء و بطبيعة الحال نحن نستخدم حقن التبعية لتجنب بجد التبعيات.

عندما يتعلق الأمر إلى التحقق من صحة النموذج عندما كنت في قانون ملزم ، نعم يمكن بسهولة استخدام الخدمة, مستودع, أو أيا كان لديك المقبل في العمارة في ValidateSelf الأسلوب.أعتقد أن السؤال ارتفاع ماذا عن التبعية.

إذا كنت أتذكر بشكل صحيح يمكنك إنشاء الخاص بك مخصص الموثق أن استخدام حقن التبعية إطار المكونات في أي خدمات النموذج الخاص بك يحتاج للمصادقة عند إنشائه ، اتصل MVC الافتراضي الموثق لملء كائن ، ثم الدعوة إلى القلعة التحقق من صحة إطار القيام التحقق من الصحة.هذا ليس فكر بشكل كامل الحل ، ولكن نأمل أن يثير بعض الأفكار.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top