사용 MVC 과 유창한 Nhibernate,어떻게 검증하는 독특한 분야에서 뷰 모델하기 전에 나는 그들을 결박하는 내 도메인을체 및 저장되나요?

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

문제

I 웹사이트가 있는 나는 사용자가를 만드는 새로운 부분에 기록합니다.하려고 해요 최고의 방법을 확인하는 특정 분야를 위해 고유성입니다.내가 있는지 확인하려면 누군가 시도하지 않는 부분을 추가로 부품 번호 1234 는 경우에는 부품 번호에 이미 존재하는 다른 부분입니다.

웹 응용 프로그램을 사용하여 Asp.net MVC fluent nHibernate 매핑하기 위한 내 개체 데이터베이스에 있습니다.나는 성을 사용하여 검증에 내 모델 보기 같은 것들에 대한 ValidateNonEmpty,ValidateRange,etc.하게 사용 ValidateSelf 메서드를 쿼리하는 저장소하시는 경우에는 부품 번호 이미 존재합니까?뭔가 느낌이 좋지 않을 사용에 대해 저장소 내에서 뷰 모델.

는 것이 더 나을 로직 컨트롤러에서 작업?그렇지 않기 때문에 기대 내 뷰 모델을 이미 검증된 지점에서(동안 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

TH를 통해 구성되었습니다 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 사이트를 확인할 수 있습니다. 여기에는 ASP.NET MVC 및 NHibernate의 모범 사례가 포함되어 있습니다. 또한 데이터 주석 유효성 검사기를 사용한 유효성 검사에 대한 XVal 프로젝트 및 튜토리얼을 확인하는 것이 좋습니다.

나에게 적합한 솔루션은

1.) 유효성 검사 작업을 실행하는 데 엔터티가 유효한 지 물어보십시오.
2.)이 작업이 완료된 후에는 객체에 유효하거나 그렇지 않다는 것을 보여줄 무언가가 있어야합니다 (제 경우에는 "깨진 규칙"의 개념과 같은 CSLA를 사용합니다).
3.) 이와 같은 것이 있으면 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