System.NotImplementedException: DataPortal_Fetch not implemented

System.NotImplementedException: DataPortal_Fetch not implemented

Old forum URL: forums.lhotka.net/forums/t/7767.aspx


GregDobbs posted on Sunday, October 11, 2009

Hello all.

I am attempting to build my first SL application. Using partial classes to separate SL client functionality from server-side functionality.

I'm trying to get SL login to work as per Rocky's examples. In my SL application, the partial identity class has the following:

Private Shared Sub desIdentityFetchComplete(ByVal sender As Object, ByVal e As DataPortalResult(Of desIdentity))
Dim callback = DirectCast(e.UserState, EventHandler(Of DataPortalResult(Of desIdentity)))
'Process results here - the object can now be manipulated before being passed back to the callback
callback.Invoke(sender, e)
End Sub

Public Shared Sub GetdesIdentity(ByVal entityid As String, ByVal username As String, ByVal password As String, ByVal callback As EventHandler(Of DataPortalResult(Of desIdentity)))
'Asynchronous Get method.
Dim dp = New DataPortal(Of desIdentity)
AddHandler dp.FetchCompleted, AddressOf desIdentityFetchComplete
dp.BeginFetch(New LoginCriteria(entityid, username, password), callback)
End Sub

When I run the SL application, I get the runtime error:

An unhandled exception ('Unhandled Error in Silverlight Application Code: 4004
Category: ManagedRuntimeError
Message: System.NotImplementedException: DataPortal_Fetch not implemented

All the service references appear valid in the solution. The DataPortal_Fetch routine is in the server-side partial class, and works fine when using non-asynchronous login via WPF. Only trying to login via Silverlight am I having problems.

Any ideas why this may be happening?

Thanks in advance!

sergeyb replied on Sunday, October 11, 2009

Are you missing private sub DataPortal_Fetch(criteria as LoginCirteria) in that class?

Sergey Barskiy
Principal Consultant
office: 678.405.0687 | mobile: 404.388.1899

Microsoft Worldwide Partner of the Year | Custom Development Solutions, Technical Innovation

-----Original Message-----
From: GregDobbs [mailto:cslanet@lhotka.net]
Sent: Sunday, October 11, 2009 5:47 PM
To: Sergey Barskiy
Subject: [CSLA .NET] System.NotImplementedException: DataPortal_Fetch not implemented

Hello all.

I am attempting to build my first SL application. Using partial classes to separate SL client functionality from server-side functionality.

I'm trying to get SL login to work as per Rocky's examples. In my SL application, the partial identity class has the following:

Private Shared Sub desIdentityFetchComplete(ByVal sender As Object, ByVal e As DataPortalResult(Of desIdentity))
Dim callback = DirectCast(e.UserState, EventHandler(Of DataPortalResult(Of desIdentity)))
'Process results here - the object can now be manipulated before being passed back to the callback
callback.Invoke(sender, e)
End Sub

Public Shared Sub GetdesIdentity(ByVal entityid As String, ByVal username As String, ByVal password As String, ByVal callback As EventHandler(Of DataPortalResult(Of desIdentity)))
'Asynchronous Get method.
Dim dp = New DataPortal(Of desIdentity)
AddHandler dp.FetchCompleted, AddressOf desIdentityFetchComplete
dp.BeginFetch(New LoginCriteria(entityid, username, password), callback)
End Sub

When I run the SL application, I get the runtime error:

An unhandled exception ('Unhandled Error in Silverlight Application Code: 4004
Category: ManagedRuntimeError
Message: System.NotImplementedException: DataPortal_Fetch not implemented

All the service references appear valid in the solution. The DataPortal_Fetch routine is in the server-side partial class, and works fine when using non-asynchronous login via WPF. Only trying to login via Silverlight am I having problems.

Any ideas why this may be happening?

Thanks in advance!

GregDobbs replied on Monday, October 12, 2009

Hello, Sergey.

The DataPortal_fetch() private sub exists in the server-side partial class.

e.g.
desIdentity.shared.vb
desIdentity.vb
Does this separation look correct?

Thanks!

GregDobbs replied on Monday, October 12, 2009

Oops - used some illegal characters that nuked my response. Try this again:

The desIdentity.shared.vb partial class is available to the SL client (linked file). It contains the asynchronous methods (beginfetch, fetchcomplete) and all property declarations.

The Dataportal_xxx methods, however, exists in the partial class desIdentity.vb, which is a server-only file.

Is this separation correct?

sergeyb replied on Monday, October 12, 2009

Sounds correct to me. Maybe the method signature for DP_Fetch is not correct?

Sergey Barskiy
Principal Consultant
office: 678.405.0687 | mobile: 404.388.1899

Microsoft Worldwide Partner of the Year | Custom Development Solutions, Technical Innovation

-----Original Message-----
From: GregDobbs [mailto:cslanet@lhotka.net]
Sent: Monday, October 12, 2009 2:04 PM
To: Sergey Barskiy
Subject: Re: [CSLA .NET] RE: System.NotImplementedException: DataPortal_Fetchnot implemented

Oops - used some illegal characters that nuked my response. Try this again:

The desIdentity.shared.vb partial class is available to the SL client (linked file). It contains the asynchronous methods (beginfetch, fetchcomplete) and all property declarations.

The Dataportal_xxx methods, however, exists in the partial class desIdentity.vb, which is a server-only file.

Is this separation correct?

GregDobbs replied on Monday, October 12, 2009

Thanks, Sergey.

Yes, the signatures are all correct. The same problem seems to be happening in all other BOs I am testing (not many yet, since I can't get past login).

Could this be a configuration issue? Testing the code in a WPF client all works fine (no asynch usage there). It's only in the SL client where the problem arises in attempting to access the underlying DataPortal_fetch method when a BeginFetch is called - it's almost as if the Silverlight partial class can't find its other half on the server side.

GregDobbs replied on Tuesday, October 13, 2009

OK - here is the full code that's exhibiting the problem. I hope someone can figure this out - I am going crazy! I still get the DataPortal_Fetch not implemented error.

Identity Server-side class:

Imports System
Imports System.Security.Principal
Imports System.Collections.Generic
Imports System.Runtime.Serialization
Imports System.Data.SqlClient
Imports Csla
Imports Csla.Core
Imports Csla.Data
Imports Csla.Security
Imports Csla.Serialization
Imports Csla.Core.FieldManager
Namespace Security

_
Public Class desIdentity
Inherits ReadOnlyBase(Of desIdentity)
Implements IIdentity

Private mRoles As New List(Of String)

Friend Function IsInRole(ByVal role As String) As Boolean
Return mRoles.Contains(role)
End Function


#Region " Factory Methods "

Friend Shared Function GetIdentity(ByVal entityid As String, ByVal username As String, ByVal password As String) As desIdentity
Return DataPortal.Fetch(Of desIdentity)(New LoginCriteria(entityid, username, password))
End Function

#End Region

#Region " Data Access "

Private Overloads Sub DataPortal_Fetch(ByVal criteria As LoginCriteria)
Try
Using cxmgr As Csla.Data.ConnectionManager(Of SqlConnection) = Csla.Data.ConnectionManager(Of SqlConnection).GetManager("clientNet", True)
Dim cn As SqlConnection = cxmgr.Connection
Using cm As SqlCommand = cn.CreateCommand()
cm.CommandText = "admin_CSLALogin"
cm.CommandType = CommandType.StoredProcedure
cm.Parameters.AddWithValue("@EntityID", criteria.EntityID)
cm.Parameters.AddWithValue("@UserName", criteria.UserName)
cm.Parameters.AddWithValue("@Password", criteria.Password)
Using dr As SafeDataReader = New SafeDataReader(cm.ExecuteReader())
If dr.Read() Then

LoadProperty(IsAuthenticatedProperty, True)
LoadProperty(CSLAUserKeyProperty, dr.GetInt32("CSLAUserKey"))
LoadProperty(NameProperty, criteria.UserName)
LoadProperty(FirstNameProperty, dr.GetString("FirstName"))
LoadProperty(LastNameProperty, dr.GetString("LastName"))
LoadProperty(FullNameProperty, dr.GetString("FullName"))
LoadProperty(EntityNameProperty, dr.GetString("EntityName"))
LoadProperty(EntityNameProperty, dr.GetString("EntityName"))
LoadProperty(LoginTypeProperty, dr.GetString("LoginType"))
LoadProperty(ResultMessageProperty, "Loaded Identity for " & criteria.UserName)

If dr.NextResult Then
While dr.Read
mRoles.Add(dr.GetString(0))
End While
End If

Else
LoadProperty(IsAuthenticatedProperty, False)
LoadProperty(CSLAUserKeyProperty, 0)
LoadProperty(NameProperty, "")
LoadProperty(FirstNameProperty, "")
LoadProperty(LastNameProperty, "")
LoadProperty(FullNameProperty, "")
LoadProperty(EntityNameProperty, "")
LoadProperty(EntityNameProperty, "")
LoadProperty(LoginTypeProperty, "")
LoadProperty(ResultMessageProperty, "No data returned for " & criteria.UserName)
mRoles.Clear()

End If
End Using
End Using
End Using
Catch ex As Exception
LoadProperty(IsAuthenticatedProperty, False)
LoadProperty(CSLAUserKeyProperty, 0)
LoadProperty(NameProperty, "")
LoadProperty(FirstNameProperty, "")
LoadProperty(LastNameProperty, "")
LoadProperty(FullNameProperty, "")
LoadProperty(EntityNameProperty, "")
LoadProperty(EntityNameProperty, "")
LoadProperty(LoginTypeProperty, "")
LoadProperty(ResultMessageProperty, "Exception Occured for " & criteria.UserName & vbCrLf & ex.ToString)
mRoles.Clear()
End Try

End Sub

#End Region

End Class

End Namespace



Identity Partial SL class:

Imports System
Imports System.Security.Principal
Imports System.Collections.Generic
Imports System.Runtime.Serialization
Imports Csla
Imports Csla.Core
Imports Csla.Data
Imports Csla.Security
Imports Csla.Serialization
Imports Csla.Core.FieldManager
Namespace Security

Partial Public Class desIdentity
Inherits ReadOnlyBase(Of desIdentity)
Implements IIdentity

#Region " Business Methods "

Protected Overrides Function GetIdValue() As Object
Return GetProperty(NameProperty)
End Function


#Region " IIdentity "


Private Shared ClientKeyProperty As PropertyInfo(Of Integer) = RegisterProperty(New PropertyInfo(Of Integer)("ClientKey"))

Private Shared IsAuthenticatedProperty As PropertyInfo(Of Boolean) = RegisterProperty(New PropertyInfo(Of Boolean)("IsAuthenticated"))
Private Shared AuthenticationTypeProperty As PropertyInfo(Of String) = RegisterProperty(New PropertyInfo(Of String)("AuthenticationType"))
Private Shared CSLAUserKeyProperty As PropertyInfo(Of Integer) = RegisterProperty(New PropertyInfo(Of Integer)("CSLAUserKey"))
Private Shared NameProperty As PropertyInfo(Of String) = RegisterProperty(New PropertyInfo(Of String)("Name"))
Private Shared FirstNameProperty As PropertyInfo(Of String) = RegisterProperty(New PropertyInfo(Of String)("FirstName"))
Private Shared LastNameProperty As PropertyInfo(Of String) = RegisterProperty(New PropertyInfo(Of String)("LastName"))
Private Shared FullNameProperty As PropertyInfo(Of String) = RegisterProperty(New PropertyInfo(Of String)("FullName"))
Private Shared EntityNameProperty As PropertyInfo(Of String) = RegisterProperty(New PropertyInfo(Of String)("EntityName"))
Private Shared EntityKeyProperty As PropertyInfo(Of Integer) = RegisterProperty(New PropertyInfo(Of Integer)("EntityKey"))
Private Shared LoginTypeProperty As PropertyInfo(Of String) = RegisterProperty(New PropertyInfo(Of String)("LoginType"))
Private Shared ResultMessageProperty As PropertyInfo(Of String) = RegisterProperty(New PropertyInfo(Of String)("ResultMessage"))


Public ReadOnly Property AuthenticationType() As String _
Implements System.Security.Principal.IIdentity.AuthenticationType
Get
Return "Csla"
End Get
End Property


Public ReadOnly Property IsAuthenticated() As Boolean _
Implements System.Security.Principal.IIdentity.IsAuthenticated
Get
Return GetProperty(IsAuthenticatedProperty)
End Get
End Property

Public ReadOnly Property CSLAUserKey() As Integer 'Added 3/20/2008 - gpd
Get
Return GetProperty(CSLAUserKeyProperty)
End Get
End Property


Public ReadOnly Property Name() As String _
Implements System.Security.Principal.IIdentity.Name
Get
Return GetProperty(NameProperty)
End Get
End Property

Public ReadOnly Property FirstName() As String
Get
Return GetProperty(FirstNameProperty)
End Get
End Property


Public ReadOnly Property LastName() As String
Get
Return GetProperty(LastNameProperty)
End Get
End Property

Public ReadOnly Property FullName() As String
Get
Return GetProperty(FullNameProperty)
End Get
End Property

Public ReadOnly Property EntityName() As String
Get
Return GetProperty(EntityNameProperty)
End Get
End Property

Public ReadOnly Property EntityKey() As Integer
Get
Return GetProperty(EntityKeyProperty)
End Get
End Property

Public ReadOnly Property LoginType() As String
Get
Return GetProperty(LoginTypeProperty)
End Get
End Property

Public ReadOnly Property ResultMessage() As String
Get
Return GetProperty(ResultMessageProperty)
End Get
End Property

#End Region

#End Region

#Region "Asynchronous/Shared Factory Methods "

Public Sub New()
' require use of factory methods
'When used, set Authenticated to false by default
LoadProperty(IsAuthenticatedProperty, False)
LoadProperty(CSLAUserKeyProperty, 0)
LoadProperty(NameProperty, "")
LoadProperty(FirstNameProperty, "")
LoadProperty(LastNameProperty, "")
LoadProperty(FullNameProperty, "")
LoadProperty(EntityNameProperty, "")
LoadProperty(EntityNameProperty, "")
LoadProperty(LoginTypeProperty, "")
LoadProperty(ResultMessageProperty, "Created new unauthenticated identity")
End Sub

Private Shared Sub desIdentityFetchComplete(ByVal sender As Object, ByVal e As DataPortalResult(Of desIdentity))

Dim callback = DirectCast(e.UserState, EventHandler(Of DataPortalResult(Of desIdentity)))

'Process results here - the object can now be manipulated before being passed back to the callback
'Callback to the UI that the identity has been established
callback.Invoke(sender, e)
End Sub

Public Shared Sub GetIdentityAsynch(ByVal entityid As String, ByVal username As String, ByVal password As String, ByVal callback As EventHandler(Of DataPortalResult(Of desIdentity)))
'Asynchronous Get method.
Dim dp = New DataPortal(Of desIdentity)
AddHandler dp.FetchCompleted, AddressOf desIdentityFetchComplete
dp.BeginFetch(New LoginCriteria(entityid, username, password), callback)
End Sub


Friend Shared Function UnauthenticatedIdentity() As desIdentity
Return New desIdentity
End Function


#End Region
End Class

End Namespace


Call to establish Authentication from XAML:

Imports System
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Media
Imports System.Windows.Media.Animation
Imports System.Windows.Shapes
Imports Csla
Imports Csla.Security
Imports clientNet.Library
Imports clientNet.Library.Security

Partial Public Class acLogin
Inherits UserControl

Public Sub New()
' Required to initialize variables
InitializeComponent()
End Sub


Private Sub btnLogin_Click(ByVal Sender As Object, ByVal e As RoutedEventArgs)

Dim UserName As String = tbUserName.Text
Dim Password As String = passboxPassword.Password

'asynch
clientNet.Library.Security.desIdentity.GetIdentityAsynch("entityID", UserName, Password, AddressOf LoginComplete)


End Sub

Private Sub LoginComplete(ByVal sender As Object, ByVal e As DataPortalResult(Of desIdentity))

Dim identity As desIdentity
identity = e.Object
Csla.ApplicationContext.User = New desPrincipal(identity)

If Csla.ApplicationContext.User.Identity.IsAuthenticated Then
Me.tblockLoginResult.Text = "Logged In: " & Csla.ApplicationContext.User.Identity.Name & identity.ResultMessage
Else
Me.tblockLoginResult.Text = "Not: " & identity.ResultMessage
End If

End Sub



End Class


GregDobbs replied on Friday, October 16, 2009

Hello, all.

I've been working on this gnashing my teeth for four days - no luck!

For the following discussion I am working on an Identity object called desIdentity. This is a typical CSLA Identity object paired with a typical principal object - no surprises.

Here's the situation:

1) I have an application with both WPF and Silverlight clients.

2) All BOs, including the Identity and Principal authorization objects, are split into partial classes. The partial classes all reside on the Server side of things, and the partial classes specific to SL are linked into the SL client. The SL partial classes contain asynchronous methods, e.g. calling BeginFetch and handling FetchComplete.

3) From WPF, I can use EITHER the synchronous or asynchronous methods successfully. So, I know the Dataportal_Fetch works, both synchronously and asychronously. The BeginFetch procedure in the SL partial class when used by WPF works fine.

4) However, trying to call the BeginFetch FROM SL results in an error: DataPortal_fetch not implemented.

SO - I must surmise that there is something not correctly set up in my service references that is causing SL to not send the BeginFetch command properly down the wire to the server to call DataPortal_Fetch.

I have attached all the various config files: I hope someone can see a glaring error here!!! It all looks OK to me. Note that there are BOTH WcfPortal AND WcfSLPortal ClientConfig files to support both UIs.

Copyright (c) Marimer LLC