WCF usernamepasswordValidator에서 현재 InstanceContext에 액세스하십시오

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

  •  27-09-2020
  •  | 
  •  

문제

사용자 정의 UserNamePasswordValidator를 사용하는 WCF 서비스가 있습니다. 유효성 검사기는 내 엔티티 프레임 워크 컨텍스트에 액세스해야합니다.

전체 서비스 호출에 대해 하나의 ObjectContext를 만들고 통화가 끝나면 파괴 / 처분을하고 싶습니다. 그래서이 기능을 제공하는 싱글 톤 정적 클래스를 만들었습니다. 이제는 두 가지 서비스 호출이 동시에 발생하는 경우 통화 중 하나가 싱글 톤을 처분합니다.

i는 objectContext에 로컬 참조를 유지하고 두 번째 서비스가 사용하는 두 번째 서비스가 처분되고 던지기 및 오류로 표시되거나, 내가 필요가있는 싱글 톤 클래스 주위에 래퍼 속성을 넣은 다음 내 모든 것입니다. 다른 호출이 처분 된 경우 객체의 새 인스턴스를 얻기 때문에 변경 사항이 던져집니다.

그래서 기본적으로 내 질문은 서비스 호출 당 objectContext를 인스턴스화합니까?

주 : 인스턴스는 서비스 코드와 사용자 정의 UserNamepassWordValidator 코드 모두에서 깊이 있어야합니다.

나는 생성자에서 그것을 할 수 없거나 사용자 정의 usernamepasswordValidator가 에 액세스 할 수 없기 때문에 사용하는 명령문을 사용하지 못합니다. 통화 당 정적 클래스를 가질 수있는 방법이 있습니까? 그것은 불가능한 소리가납니다. 그러나 이것의 주위는 무엇입니까? 세션에서 개체를 캐싱해야합니까?

내 서비스가 IIS에서 호스팅됩니다.

업데이트 :
그래서 저는 iExtension 객체를 사용하여 InstanceContext에 상태를 저장하기 위해 이렇게 해제했습니다. 그러나 UsernamepAsswordValidator에서 현재 InstanceContext에 액세스하려면 어떻게합니까?

도움이 되었습니까?

해결책

확인이므로 다음 정적 클래스를 사용하고 ASP.NET에 의지하여 ASP.NET에 의존하여 저에게 컨텍스트를 캐시합니다.

나는 이것이 일을하는 것이 가장 좋은 방법인지 확실하지 않지만, 이것은 요청 당 하나의 objectContext를 사용하여 너무 많은 것을 회전시키지 않고 이것이 또한 잠금을 사용하지 않아도된다는 것을 의미합니다.많은 사용자가 서비스를 사용하고있는 경우 악몽이되는 물체에 있습니다.

public static class MyContextProvider
    {
        public static MyModel Context
        {
            get
            {
                if (HttpContext.Current.Items["context"].IsNull())
                {
                    HttpContext.Current.Items["context"] = new MyModel();
                }

                return HttpContext.Current.Items["context"] as MyModel;
            }
        }    
    }
.

그런 다음 앱에서 objectContext가 필요할 때마다

var context = MyContextProvider.Context;
.

다른 팁

호출 당 하나의 인스턴스가 있으면 인스턴스 당 1 호의 호출이 있습니다.

은 매우 간단해야하며 OperationContract 메서드의 Toplevel에서 using () { } 블록을 사용해야합니다.

OK, 모든 WCF 서비스 호출에 대해 단일 ObjectContext Entity Model 객체를 제공하고 통화가 끝나면 자동으로 폐기하는 Safe State 메서드가있는 클래스가 있습니다.

public static class EntityModelProvider
{
    private static readonly Dictionary<OperationContext, MyEntityModel> _entityModels = new Dictionary<OperationContext, MyEntityModel>();

    public static MyEntityModel GetEntityModel()
    {
        if (OperationContext.Current == null)
            throw new Exception("OperationContext is missing");

        lock (_entityModels)
        {
            if (!_entityModels.ContainsKey(OperationContext.Current))
            {
                _entityModels[OperationContext.Current] = new MyEntityModel();
                OperationContext.Current.OperationCompleted += delegate
                {
                    lock (_entityModels)
                    {
                        _entityModels[OperationContext.Current].Dispose();
                        _entityModels.Remove(OperationContext.Current);
                    }
                };
            }

            return _entityModels[OperationContext.Current];
        }
    }
.

서비스의 경우 서비스의 인스턴스 모드를 자세히 설명하는 서비스 동작을 지정할 수 있습니다.

[ServiceBehaviour(InstanceContextMode = InstanceContextMode.PerCall)]
public class MyService : IMyService {
    ObjectContext context;
}
.

클리너 방법은 .NET 4에있는 ServiceAuthenticationManager를 사용할 수 있습니다.

http://msdn.microsoft.com/ko. - 수 / 라이브러리 / System.ServiceModel.ServiceAuthenticationManager.aspx

Authenticate 메소드 (오버라이드)에서 메시지 개체에 액세스하고 속성을 설정할 수 있습니다. 나는 분노로 그것을 사용하지 않았으므로 ymmv :)

이 접근 방식으로 문제점을 편집하는 것은 사용자 이름과 암호가 없으므로 사용자 정의 인증이 필요합니다.

usernameSecurityTokenAuthenticator를 살펴보십시오 ... http : // msdn. .microsoft.com / en-us / library / system.identitymodel.selectors.usernamesecurityTokenAuthenticator (v= vs.90) .aspx


내 연구에서 추가 읽기 :

이 질문에 대한 답변은 사용 방법에 대한 힌트를 제공합니다.

System.ServiceModel.ServiceAuthenticationManager와 사용자 정의 WCF 인증? / P>

러시아어를 읽을 수있는 경우 러시아어를 읽을 수 있다면 :

에 유용한 힌트를 발견했습니다.

http://www.sql.ru/forum/actualthread.aspx. ? tid= 799046

이 오히려 양호한 CodeProject 기사는 추가 (암호화 및 압축뿐만 아니라 사용자 정의 권한 부여)

http : //www.codeproject .com / 기사 / 165844 / wcf-client-server-application-with-custom-authati

서비스에 할당 할 때 customValidator에 컨텍스트를 전달하지 않으므로 유효성 검사기에 오브젝트 컨텍스트를 저장하고 필요한 경우 새로피드 유효성 검사 메소드에서 새로피드 유효성 검사 메소드에서 새롭게 전달되지 않습니다.그런 다음 Services CutomUsernameValidator를 통해 객체에 액세스 할 수 있습니다.

묻는 것에 따라 : Dynamic Object로 별도의 ObjectContext 클래스를 만듭니다.이를 CustomValidator에 속성으로 추가하십시오. 사용자 지정 유효성 검사기에서 이제 객체가 처분되었는지 확인하고 필요할 경우 객체를 다시 작성할 수 있습니다. 그렇지 않으면 이것이 당신이 아닌 것이 아닌 경우 - 유효성 검사기에 컨텍스트를 저장하십시오. 서버 측에 여전히 액세스 할 수 있습니다. 여기서 코드는 일반적인 일반화 된 아이디어입니다 - 나는 그것이 내가 말하는 것에 대한 아이디어를 가질 수 있도록 그냥 참조의 프레임으로 그것을 게시하고 있습니다.

public DynamicObjectContextObjectClass
{
  ObjectContext internalObjectContext;

}
public class ServiceUserNamePasswordValidator : UserNamePasswordValidator
{

    public DynamicObjectContextObjectClass dynamiccontext;


    public override void Validate(string userName, string password)
    {
        if(dynamiccontext.internalObjectContext.isdisposed)
        {

        dynamiccontext.internalObjectContext = new Context;

            }
            try
            {
                if (string.IsNullOrEmpty(userName) || password == null)
                {
                    //throw new ArgumentNullException();
                    throw new FaultException("Username cannot be null or empty; Password cannot be null and should not be empty");
                }
       }
   }
} 
.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top