I have functions which serialize and base64 convert objects and vice versa. It uses Newtonsoft to serialize and deserialize Objects. The code works but is there a way to do this without using Newtonsoft?
Public Shared Function SerializeAndBase64(ObjectToSerialize As Object) As ReturnObject(Of String)
Dim rtnObj As New ReturnObject(Of String)
Try
Dim SerializedObjectJson As String = Newtonsoft.Json.JsonConvert.SerializeObject(ObjectToSerialize)
Dim Base64String As String = Convert.ToBase64String(Encoding.UTF8.GetBytes(SerializedObjectJson))
rtnObj.Item = Base64String
Catch ex As Exception
rtnObj.ErrorID = ErrorHandler.handleError(ex)
rtnObj.ErrorMessage = ex.Message
rtnObj.IsError = True
End Try
Return rtnObj
End Function
Public Shared Function DeserializeFromBase64(Of t)(Base64Json As String) As ReturnObject(Of t)
Dim rtnObj As New ReturnObject(Of t)
Try
Dim SerializedObjectJson As String = Encoding.UTF8.GetString(Convert.FromBase64String(Base64Json))
Dim DeserializedObject As t = Newtonsoft.Json.JsonConvert.DeserializeObject(Of t)(SerializedObjectJson)
rtnObj.Item = DeserializedObject
Catch ex As Exception
rtnObj.ErrorID = ErrorHandler.handleError(ex)
rtnObj.ErrorMessage = ex.Message
rtnObj.IsError = True
End Try
Return rtnObj
End Function
Thanks in advance.
You can Serialize/Deserialize it yourself. You just have to come up with a way to save everything into a single string, or XML or even a byte array if you want. Your choice.
Public Class Class1
Public Property MyValue As String
Public Function Serialize() As String
Return MyValue
End Function
Public Sub Deserialize(ByVal value As String)
MyValue = value
End Sub
End Class
Related
In the following method I am trying to add a dynamic member to an expando object but it throws an exception:
public member not found for expand object
Private Sub GetAckValues()
Try
Dim ack_duration As String = String.Empty
Dim ack_by_user_fkid As String = String.Empty
Dim ack_time As String = String.Empty
ack_duration = txtdefaultack.Text
ack_by_user_fkid = Convert.ToString(Session("user_code"))
Dim Ack_Detail As Object = New ExpandoObject()
Ack_Detail.ack_duration = ack_duration
Ack_Detail.ack_by_user_fkid = ack_by_user_fkid
receiptObject.StatusObject = Ack_Detail
Catch ex As Exception
logger.Error("Enter JobRequest form done by :" & LoggedinUserId, ex)
End Try
End Sub
Should this:
Ack_Detail.ack_duration = Ack_Detail.ack_duration
actually be this:
Ack_Detail.ack_duration = ack_duration
I am developing a set of Office add ins that reads and writes templates and other files from a locally stored serialized object. Until now it has been going well, however, since I have been stress testing it by writing big amounts of data to this local object, and loading it into memory when reading from it, I have been getting SystemOutOfMemory exceptions. I do clean memory out each time I am done with this object, but simply loading it into memory can cause the exception be thrown.
The object is at most 100mb in size at any given time, so there is no way that it is using all the desktop resources to load this object into memory, so I have been wondering whether it may be that Microsoft limits the amount of memory that an add in may use.
What I would like to know is of anyone knows if there is a size limit and what it may be, as well as how to increase it if there is a limit present?
Thank you in advance for any advice given.
UPDATE:
Here is the code of the class that I am serializing:
Imports System.Environment
Imports Microsoft.Win32.SafeHandles
Imports System.Runtime.InteropServices
<Serializable()> _
Public Class LocalDBObject
Private aOfficesDS As DataSet = New DataSet()
Private aFieldDS As DataSet = New DataSet()
Private aSectorsDS As DataSet = New DataSet()
Private aDocumentsDS As DataSet = New DataSet()
Private aLibraryDS As DataSet = New DataSet()
Private aRolesDS As DataSet = New DataSet()
Private aSettings As mySettings = New mySettings()
Private aUpdateDate As DateTime = DateTime.Now
Private aUser As UserInfo = New UserInfo()
Private aDistributionFilesDS As DataSet = New DataSet()
Public Property UpdateDate() As DateTime
Get
UpdateDate = aUpdateDate
End Get
Set(ByVal Value As DateTime)
aUpdateDate = Value
End Set
End Property
Public Property Settings() As mySettings
Get
Settings = aSettings
End Get
Set(ByVal Value As mySettings)
aSettings = Value
End Set
End Property
Public Property RolesDS() As DataSet
Get
RolesDS = aRolesDS
End Get
Set(ByVal Value As DataSet)
aRolesDS = Value
End Set
End Property
Public Property UserInfo() As UserInfo
Get
UserInfo = aUser
End Get
Set(ByVal Value As UserInfo)
aUser = Value
End Set
End Property
Public Shared Userfolder As String = GetFolderPath(SpecialFolder.ApplicationData) + "\CIM\" + Environment.UserName
Public Shared UserDistributionfolder As String = GetFolderPath(SpecialFolder.ApplicationData) + "\CIM\CIM Distribution Files"
Public Shared Function CheckFile() As Boolean
Return System.IO.File.Exists(Userfolder + "\LocalDB.dat")
End Function
Public Shared Sub Write(ByVal obj As LocalDBObject)
Serializer.Serialize2(obj, Userfolder + "\LocalDB.dat")
End Sub
Public Shared Function Read() As LocalDBObject
If Not System.IO.Directory.Exists(Userfolder) Then
System.IO.Directory.CreateDirectory(Userfolder)
End If
Dim obj As LocalDBObject = Serializer.deSerialize2(Userfolder + "\LocalDB.dat")
Return obj
End Function
Public Property DocumentsDS() As DataSet
Get
DocumentsDS = aDocumentsDS
End Get
Set(ByVal Value As DataSet)
aDocumentsDS = Value
End Set
End Property
Public Property LibraryDS() As DataSet
Get
LibraryDS = aLibraryDS
End Get
Set(ByVal Value As DataSet)
aLibraryDS = Value
End Set
End Property
Public Property OfficesDS() As DataSet
Get
OfficesDS = aOfficesDS
End Get
Set(ByVal Value As DataSet)
aOfficesDS = Value
End Set
End Property
Public Property FieldDS() As DataSet
Get
FieldDS = aFieldDS
End Get
Set(ByVal Value As DataSet)
aFieldDS = Value
End Set
End Property
Public Property SectorsDS() As DataSet
Get
SectorsDS = aSectorsDS
End Get
Set(ByVal Value As DataSet)
aSectorsDS = Value
End Set
End Property
Public Property DistributionDS() As DataSet
Get
DistributionDS = aDistributionFilesDS
End Get
Set(ByVal Value As DataSet)
aDistributionFilesDS = Value
End Set
End Property
Public Shared Function GetNameForLibaryGroup(ByVal FieldID As Integer, ByVal obj As LocalDBObject) As String
For Each dr As DataRow In obj.aFieldDS.Tables(0).Rows
If dr("FieldID") = FieldID Then
Return dr("FieldName")
End If
Next
Return ""
End Function
Public Shared Function GetFileForTemplate(ByVal DocID As Integer) As Byte()
Dim obj As CIMShared.LocalDBObject = CIMShared.LocalDBObject.Read()
For Each dr As DataRow In obj.DocumentsDS.Tables(0).Rows
If dr("docid") = DocID Then
Try
Dim data As Byte() = CType(dr("docdata"), Byte())
Return data
Catch ex As Exception
Return Nothing
End Try
End If
Next
Return Nothing
End Function
Public Shared Function GetFilenameForTemplate(ByVal DocID As Integer) As String
Dim obj As CIMShared.LocalDBObject = CIMShared.LocalDBObject.Read()
For Each dr As DataRow In obj.DocumentsDS.Tables(0).Rows()
If dr("docid") = DocID Then
Return Convert.ToString(LocalDBObject.Userfolder + "\" + dr("docName")) + "_" + Convert.ToString(dr("DocID")) + "." + Convert.ToString(dr("docext")).Substring(1)
End If
Next
Return Guid.NewGuid().ToString().Replace("-", "") + ".txt"
End Function
Public Shared Function GetFilenameOnlyForTemplate(ByVal DocID As Integer) As String
Dim obj As CIMShared.LocalDBObject = CIMShared.LocalDBObject.Read()
For Each dr As DataRow In obj.DocumentsDS.Tables(0).Rows()
If dr("docid") = DocID Then
Return Convert.ToString(dr("docName")) + "." + Convert.ToString(dr("docext")).Substring(1)
End If
Next
Return Guid.NewGuid().ToString().Replace("-", "") + ".txt"
End Function
Public Shared Function GetFilenameForPicture(ByVal DocID As Integer) As String
Dim obj As CIMShared.LocalDBObject = CIMShared.LocalDBObject.Read()
For Each dr As DataRow In obj.DocumentsDS.Tables(0).Rows()
If dr("docid") = DocID Then
Return Convert.ToString(LocalDBObject.Userfolder + "\" + dr("docName")) + "." + Convert.ToString(dr("docext")).Substring(1)
End If
Next
Return Guid.NewGuid().ToString().Replace("-", "") + ".txt"
End Function
Public Shared Function GetFileForLibrary(ByVal DocID As Integer) As Byte()
Dim obj As CIMShared.LocalDBObject = CIMShared.LocalDBObject.Read()
For Each dr As DataRow In obj.LibraryDS.Tables(0).Rows
If dr("docid") = DocID Then
Try
Dim data As Byte() = CType(dr("docdata"), Byte())
Return data
Catch ex As Exception
Return Nothing
End Try
End If
Next
Return Nothing
End Function
Public Shared Function GetFileLibaryDate(ByVal DocID As Integer) As DateTime
Dim obj As CIMShared.LocalDBObject = CIMShared.LocalDBObject.Read()
For Each dr As DataRow In obj.LibraryDS.Tables(0).Rows
If dr("docid") = DocID Then
Try
Dim adate As DateTime = Convert.ToDateTime(dr("docdateupdated"))
Return adate
Catch ex As Exception
Return DateTime.Now.AddYears(-100)
End Try
End If
Next
Return DateTime.Now.AddYears(-100)
End Function
Public Shared Function GetFilenameForLibary(ByVal DocID As Integer) As String
Dim obj As CIMShared.LocalDBObject = CIMShared.LocalDBObject.Read()
For Each dr As DataRow In obj.LibraryDS.Tables(0).Rows
If dr("docid") = DocID Then
Return Convert.ToString(LocalDBObject.Userfolder + "\" + dr("docName")) + "_" + Convert.ToString(dr("DocID")) + "." + Convert.ToString(dr("docext")).Substring(1)
End If
Next
Return Guid.NewGuid().ToString().Replace("-", "") + ".txt"
End Function
'EUGENE: Added this to get the distribution folders.
Public Shared Function GetDistributionFileDS() As List(Of Integer)
Dim LocalDocIDList As New List(Of Integer)
Dim obj As CIMShared.LocalDBObject = CIMShared.LocalDBObject.Read()
If obj.aDistributionFilesDS.Tables.Count > 0 Then
For Each Row As DataRow In obj.aDistributionFilesDS.Tables(0).Rows
LocalDocIDList.Add(Row("docid"))
Next
End If
Return LocalDocIDList
End Function
Public Shared Function GetDistributionFilePath(DocumentID As Integer) As String
Dim LocalDocumentPath As String = ""
Dim obj As CIMShared.LocalDBObject = CIMShared.LocalDBObject.Read()
For Each Row As DataRow In obj.aDistributionFilesDS.Tables(0).Rows
If Row("docid") = DocumentID Then
LocalDocumentPath = LocalDBObject.UserDistributionfolder + "\" + CStr(Row("docid")) + "-" + CStr(Row("docName")) + CStr(Row("docext"))
End If
Next
Return LocalDocumentPath
End Function
Public Shared Function GetDistributionFileData(DocumentID As Integer) As Byte()
Dim LocalDocumentData As Byte() = Nothing
Dim obj As CIMShared.LocalDBObject = CIMShared.LocalDBObject.Read()
For Each Row As DataRow In obj.aDistributionFilesDS.Tables(0).Rows
If Row("docid") = DocumentID Then
LocalDocumentData = CType(Row("docdata"), Byte())
End If
Next
Return LocalDocumentData
End Function
End Class
Here are the serializer functions that serializes the class, and that deserilizes the class.
Public Shared Sub Serialize(ByVal obj As LocalDBObject, ByVal FileName As String)
Dim Stream As New FileStream(FileName, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite)
Dim objStreamWriter As New StreamWriter(Stream)
Dim x As New XmlSerializer(obj.GetType)
x.Serialize(objStreamWriter, obj)
objStreamWriter.Close()
End Sub
Public Shared Function deSerialize(ByVal FileName As String) As LocalDBObject
Dim obj As New LocalDBObject()
Dim Stream As FileStream
Dim objStreamReader As StreamReader
Try
Stream = New FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)
objStreamReader = New StreamReader(Stream)
Dim x As New XmlSerializer(obj.GetType)
obj = x.Deserialize(objStreamReader)
objStreamReader.Close()
Catch ex As Exception
obj = New LocalDBObject()
Try
Stream.Close()
Catch
End Try
Try
objStreamReader.Close()
Catch
End Try
End Try
Return obj
End Function
NOTE: I realize this is not the cleanest or neatest code, this is a former colleagues code that I am using and trying to resolve bugs on.
What is currently happening is that every time I de-serialize the class, which is about 300MB in size, I get a Out Of Memory Exception. In no way is this using all the computer memory, hence why I would like to find out if there is a memory usage limit on Microsoft Office add-ins?
What object are you talking about? Could you be more specific?
Anyway, I always suggest releasing underlying COM objects insteatly. Use System.Runtime.InteropServices.Marshal.ReleaseComObject to release an Office object when you have finished using it. Then set a variable to Nothing in Visual Basic (null in C#) to release the reference to the object. Read more about that in the Systematically Releasing Objects article.
At the moment I am using VB.Net.
I build my string, post it out and then parse the results.
Parsing Example for XML
Dim xml As New MWXMLDocument()
Dim sReason As String = "Unknown"
Try
xml.LoadXml(sresult)
If xml.SelectSimpleNode("AcceptedLead").InnerText = "true" Then
app.Outcome.RedirectURL = xml.SelectSimpleNode("result/redirecturl").InnerText
AcceptLead()
Return True
End If
sReason = xml.SelectSimpleNode("Reason").InnerText
Catch ex As Exception
sReason = "Error: " & ex.Message
End Try
DeclineLead(sReason)
Return False
End Function
How would I parse a result sent back in JSON, here is an example of the result I want to parse in using VB : Can i not just get the data from the string and parse as normal XML.
{"RedirectUrl":"www.test.com","Commission":5.0000,"Status":"accepted"}
You can use the JSON.NET Library
Example in C#:
var result = JsonConvert.DeserializeObject<RootObject>(string json);
The RootObject should be your own class.
You could use the .Net built in JavaScriptSerialiser
First add a reference to System.Web.Extensions and then
Imports System.Web.Script.Serialization
Followed by...
Dim sExampleJSON As String = "{""RedirectUrl"":""www.test.com"",""Commission"":5.0000,""Status"":""accepted""}"
Dim MySerializer As JavaScriptSerializer = New JavaScriptSerializer()
Dim MyDictionary As Dictionary(Of String, Object) = MySerializer.Deserialize(Of Dictionary(Of String, Object))(sExampleJSON)
If MyDictionary.ContainsKey("RedirectUrl") Then
Console.WriteLine(MyDictionary("RedirectUrl"))
End If
in global.asax.cs
using System.Data.Entity;
namespace RpManticSolAPI
{
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
}
}
}
The complete Answer
sResult = sResult.Replace("""", String.Empty)
If sResult.Contains("Status:accepted") Then
Dim parts = sResult.Replace("{", String.Empty).Replace("}", String.Empty).Split(",")
For i As Int16 = 0 To parts.Length - 1
If parts(i).StartsWith("RedirectUrl") Then
app.Outcome.RedirectURL = parts(i).Substring(12)
End If
If parts(i).StartsWith("Commission") Then
lendertier.LenderComm = CDec(parts(i).Substring(11))
End If
If parts(i).StartsWith("ApplicationRef") Then
app.Outcome.LenderReference = parts(i).Substring(15)
End If
Next
AcceptLead()
Return True
End If
If sResult.Contains("Reason:Duplicate") Then
sReason = "Duplicate"
ElseIf sResult.Contains("{Error:invalid credentials") Then
sReason = "Error: Invalid credentials"
ElseIf sResult.Contains("ValidationErrors:") Then
sReason = "Invalid call:" + sResult.Replace("ValidationErrors:", String.Empty).Replace(",Status:rejected", String.Empty)
Else
sReason = "Rejected"
End If
DeclineLead(sReason)
Return False
I am successfully converted structure data to string here in plain and (as suggested) in XML serialized way which obviously every has it's own good and bad side effects.
This is sample structure:
Public Structure myList
Dim a As String
Dim b As Integer
Dim c As Double
End Structure
Dim myInstance As New myList
myInstance.a = "Nemo"
myInstance.b = 10
myInstance.c = 3.14
Now I have 2 functions for converting structure data to string:
Dim xString As String = oStructToString(myInstance)
Public Function oStructToString(ByVal obj As Object) As String
Dim structString As String = ""
Dim i As Integer
Dim myType As Type = obj.GetType()
Dim myField As System.Reflection.FieldInfo() = myType.GetFields()
For i = 0 To myField.Length - 1
structString &= myField(i).GetValue(obj)
If i = myField.Length - 1 Then Exit For
structString &= Convert.ToChar(161)
Next i
Return structString
End Function
Dim xString As String = xStructToString(myInstance)
Public Function xStructToString(ByVal obj As Object) As String
Dim x As New Xml.Serialization.XmlSerializer(obj.GetType)
Dim sw As New IO.StringWriter()
x.Serialize(sw, obj)
Return sw.ToString
End Function
But I can't get data back from string to structure.
Public Function oStringToStruct(ByVal xString As String) As Object
So I can call:
Dim mySecondInstance As New myList = oStringToStruct(xString)
Or
Dim mySecondInstance As New myList = xStringToStruct(xString)
How to do that?
So far I came to this:
Public Function xStringToStruct(ByVal xString As String) As Object
Dim x As New Xml.Serialization.XmlSerializer() ''<- what here?
Dim sr As New IO.StringReader(xString)
Return x.Deserialize(sr)
End Function
and this...
By help of har07 still one error remains here...
Public Function oStringToStruct(ByVal xString As String, ByVal type As Type) As Object
Dim structString() As String = xString.Split(Convert.ToChar(161))
Dim myType As Type = type.GetType()
Dim myField As System.Reflection.FieldInfo() = myType.GetFields()
For i As Integer = 0 To structString.Length - 1
myField(i).SetValue(type, structString(i)) ''here crashes
Next i
Return type
End Function
Deserialize xml string back to struct is easier :
Public Function xStringToStruct(ByVal xString As String, ByVal type As Type) As Object
Dim x As New Xml.Serialization.XmlSerializer(type)
Dim sw As New IO.StringReader(xString)
Return x.Deserialize(sw)
End Function
You can use it like so :
Dim xObject As myList = xStringToStruct(xString, GetType(myList))
I've recently been updating a lot of my code to comply with proper n-tier architecture and OO programming, following examples from a book.
I'm starting to get problems now because I don't fully understand the access modifiers.
If I run the following code I get an error at the line
Dim clientFamilyDataAccessLayer As New ClientFamilyDAO
in the BLL at the point it creates an instance of the DAL. The full error message is: "The type initializer for 'ClientFamilyDAO' threw an exception. ---> System.NullReferenceException: Object reference not set to an instance of an object."
How do I use these function to create a list of ClientFamily objects that I can then work with?
On my UI layer I'm creating a list of objects; ClientFamilies
Dim listOfClientFamilies As List(Of ClientFamily) = ClientFamily.GetClientFamiliesByKRM(selectedEmployee.StaffNumber)
This is the function in the BLL
Public Shared Function GetClientFamiliesByKRM(ByVal krmStaffNumber As Integer) As List(Of ClientFamily)
Dim clientFamilyDataAccessLayer As New ClientFamilyDAO
Return clientFamilyDataAccessLayer.GetClientFamiliesByKRM(krmStaffNumber)
End Function
and this is function in the DAL
Public Function GetClientFamiliesByKRM(ByVal staffNumber As Integer) As List(Of ClientFamily)
Dim currentConnection As SqlConnection = New SqlConnection(_connectionString)
Dim currentCommand As New SqlCommand
currentCommand.CommandText = mainSelectStatement & " WHERE Key_Relationship_Manager = #StaffNumber ORDER BY Client_Family_Name"
currentCommand.Parameters.AddWithValue("#StaffNumber", staffNumber)
currentCommand.Connection = currentConnection
Dim listOfClientFamilies As New List(Of ClientFamily)
Using currentConnection
currentConnection.Open()
Dim currentDataReader As SqlDataReader = currentCommand.ExecuteReader()
Do While currentDataReader.Read
Dim newClientFamily As AECOM.ClientFamily = PopulateClientFamily(currentDataReader)
listOfClientFamilies.Add(newClientFamily)
Loop
End Using
Return listOfClientFamilies
End Function
Here's the full ClientFamilyDAO Class:
Public Class ClientFamilyDAO
Private Const mainSelectStatement As String = "SELECT Client_Family_ID, Client_Family_Name, Key_Relationship_Organisation, Key_Relationship_Manager, Obsolete, Market_Sector_ID FROM Client_Families"
Private Shared ReadOnly _connectionString As String = String.Empty
Shared Sub New()
_connectionString = WebConfigurationManager.ConnectionStrings("ClientFamilyManagementConnectionString").ConnectionString
End Sub
Public Function GetClientFamiliesByKRM(ByVal staffNumber As Integer) As List(Of ClientFamily)
Dim currentConnection As SqlConnection = New SqlConnection(_connectionString)
Dim currentCommand As New SqlCommand
currentCommand.CommandText = mainSelectStatement & " WHERE Key_Relationship_Manager = #StaffNumber ORDER BY Client_Family_Name"
currentCommand.Parameters.AddWithValue("#StaffNumber", staffNumber)
currentCommand.Connection = currentConnection
Dim listOfClientFamilies As New List(Of ClientFamily)
Using currentConnection
currentConnection.Open()
Dim currentDataReader As SqlDataReader = currentCommand.ExecuteReader()
Do While currentDataReader.Read
Dim newClientFamily As AECOM.ClientFamily = PopulateClientFamily(currentDataReader)
listOfClientFamilies.Add(newClientFamily)
Loop
End Using
Return listOfClientFamilies
End Function
Private Function PopulateClientFamily(ByVal currentDataReader As SqlDataReader) As AECOM.ClientFamily
Dim newClientFamily As New AECOM.ClientFamily
If Not (currentDataReader.IsDBNull(currentDataReader.GetOrdinal("Client_Family_ID"))) Then
newClientFamily.ClientFamilyID = currentDataReader("Client_Family_ID")
End If
If Not (currentDataReader.IsDBNull(currentDataReader.GetOrdinal("Client_Family_Name"))) Then
newClientFamily.ClientFamilyName = currentDataReader("Client_Family_Name")
End If
If Not (currentDataReader.IsDBNull(currentDataReader.GetOrdinal("Key_Relationship_Organisation"))) Then
Select Case currentDataReader("Key_Relationship_Organisation")
Case False
newClientFamily.IsKeyRelationshipOrganisation = False
Case True
newClientFamily.IsKeyRelationshipOrganisation = True
End Select
End If
If Not (currentDataReader.IsDBNull(currentDataReader.GetOrdinal("Key_Relationship_Manager"))) Then
newClientFamily.KeyRelationshipManagerStaffNumber = currentDataReader("Key_Relationship_Manager")
End If
If Not (currentDataReader.IsDBNull(currentDataReader.GetOrdinal("Obsolete"))) Then
Select Case currentDataReader("Obsolete")
Case False
newClientFamily.Obsolete = False
Case True
newClientFamily.Obsolete = True
End Select
End If
If Not (currentDataReader.IsDBNull(currentDataReader.GetOrdinal("Market_Sector_ID"))) Then
newClientFamily.MarketSectorID = currentDataReader("Market_Sector_ID")
End If
Return newClientFamily
End Function
End Class
The issue doesn't relate to access modifiers, rather it is more to do with the exception message you get. The following line within the constructor of ClientFamilyDAO would seem to be causing the issue:
_connectionString = WebConfigurationManager.ConnectionStrings("ClientFamilyManagementConnectionString").ConnectionString
Are you sure ClientFamilyManagementConnectionString exists in the configuration?