How to convert a business object to a string using StringbuilderHow to convert a business object to a string using Stringbuilder
Old forum URL: forums.lhotka.net/forums/t/3558.aspx
yimiqi posted on Monday, September 17, 2007
You can convert a dataset or dataview to a tab, comma or any character separated string using StringBuilder, as follows (a comma separated string in this example):
Dim StrObj As New System.Text.StringBuilder
Dim aCol As DataColumn
For Each aCol In srcDataView.Table.Columns
StrObj.Append(aCol.ColumnName)
StrObj.Append(",")
Next
Dim aRow As DataRowView
For Each aRow In srcDataView
For Each aCol In srcDataView.Table.Columns
StrObj.Append(aRow(aCol.ColumnName))
StrObj.Append(",")
Next aCol
Next aRow
Return StrObj.ToString()
This is all straightforward.
But If I have a ReadOnlyList ProjectList ( it is the collection of the ReadOnly object ProjectInfo) in place of the dataview in the example and try to achieve the same results (convert the list of ProjectInfo to a comma separated string), how do I go about doing that?
The part I'm stuck is that what qualifier I should use to access the column names in ProjectInfo object and be able to loop through them? Has anyone done similar implementation as this? The column names are properties of the ProjectInfo object.
Thanks in advance.
xal replied on Monday, September 17, 2007
Unfortunately, you'll have to fallback to hand coding it property by property or use reflection in order to read all the properties dynamically.
Andrés
yimiqi replied on Monday, September 17, 2007
Hummm, hard coding all the column names seems a bit akward. Do you have code sample how to use reflection get all the properties dynamically?
By the way, are you the Cslagen guy? I think you are. Great tool, I use it to gen all my BOs.
Thank you for the suggestion on my problem, and hats off to all your hard work on Cslagen.
JoeFallon1 replied on Monday, September 17, 2007
Here is some reflection code that should get you started:
Protected mProps As List(Of PropertyInfo)
Private
ReadOnly Property Props() As List(Of PropertyInfo)
Get
If mProps Is Nothing Then
mProps = New List(Of PropertyInfo)
'This code ensures you get the correct Type of a ROC based on the Item method which uses index As Integer.
'I have 2 overloads of the Item method which can cause problems if you do not specify the correct one.
Dim infoType As Type = mROC.GetType().GetProperty("Item", New Type() {GetType(Integer)}).PropertyType
'get an array of all Properties of the ROC (could be 50 or more)
Dim tempProps() As PropertyInfo = infoType.GetProperties(flags)
'add all Properties to mProps. Other conditional code was removed for clarity.
For Each prop As PropertyInfo In tempProps
mProps.Add(prop)
Next
End If
Return mProps
End Get
End Property
Joe
yimiqi replied on Monday, September 17, 2007
Thank you Joe, for posting the reflection code sample.
I don't exactly know how I am going to use the code to do what I'm trying to achieve yet, but this definitly will get me started in that direction. I will post back on progress.
Thanks.
yimiqi replied on Wednesday, September 19, 2007
I'm back...
Joe, what flags am I supposed to use in the following statement? I used BindingFlags.Default, .GetField and .GetProperty, all gave me Nothing back (tempProps.length = 0). So, the mProps also returns Nothing.
'get an array of all Properties of the ROC (could be 50 or more)
Dim tempProps() As PropertyInfo = infoType.GetProperties(flags)
Apparently I missed something, but what was it?
JoeFallon1 replied on Wednesday, September 19, 2007
Protected flags As BindingFlags = BindingFlags.Public Or BindingFlags.IgnoreCase Or BindingFlags.Instance
Joe
yimiqi replied on Wednesday, September 19, 2007
Thanks Joe, that worked. BindingFlag has about 20 enum values you could set, I was very confused with what values to use.
That part worked, now I'm getting something back, following is in the command window
>? tempprops
{Length=14}
(0): {System.Reflection.RuntimePropertyInfo}
(1): {System.Reflection.RuntimePropertyInfo}
(2): {System.Reflection.RuntimePropertyInfo}
....
(14): {System.Reflection.RuntimePropertyInfo}
Versus before, length was 0.
But, when I tried to add the propertyinfo in tempprops to the property list as in your sample code, I got NullReferenceException was unhandled error - I probably be able to figure this one out myself
For Each prop As PropertyInfo In tempProps
mProps.Add(prop)
Next
But any insights is always welcome.
I'm new to reflection, please bare with all my newbie questions.
xal replied on Wednesday, September 19, 2007
Try something like this. You probably want to make adjustments to order the properties or something, but this should get you 80% there... Just pass an object to the function and get the string.
Public Shared Function ObjToString(ByVal obj As Object) As String
Dim sb As New System.Text.StringBuilder()
Dim t As Type = obj.GetType()
Dim props() As System.Reflection.PropertyInfo = t.GetProperties(Reflection.BindingFlags.Public Or Reflection.BindingFlags.Instance)
For Each p As System.Reflection.PropertyInfo In props
Dim val As Object = p.GetValue(obj, Nothing)
Dim stringVal As String
If val Is Nothing Then
stringVal = "Null Reference"
Else
stringVal = val.ToString()
End If
sb.AppendFormat("{0}: {1}", p.Name, stringVal)
sb.AppendLine()
Next
Return sb.ToString()
End Function
Andrésyimiqi replied on Wednesday, September 19, 2007
Andrés
Thank you for posting the reflection code. I wish I knew a bit more about refection so that not to bother you guys with such basic simple questions here.
With your and Joe's code, I think I'm going to (I'll have to) accomplish my requirement.
Just in case you are interested, there is another post in this forum discussing export data from BO to a CSV string then file. The author of that post didn't use reflection to do his work.
http://forums.lhotka.net/forums/17708/ShowThread.aspx#17708
yimiqi replied on Thursday, September 20, 2007
Joe or Andrés
I'm getting the TargetException was unhandled error "Object does not match target type" when at line
Dim val As Object = p.GetValue(obj, Nothing)
If I replace line Dim t As Type = obj.GetType()
with Dim t As Type = obj.GetType().GetProperty("Item", New Type() {GetType(Integer)}).PropertyType
(from Joe's)
I did that because the line from Joe's code ensures getting the correct type of a ROC object based on the item method which uses index as integer, which is what I wanted - the item properties of the object.
obj.GetType() gives me all other properties of the object, like AllowRemove, AllowEdit, AllowNew etc. which isn't what I wanted.
If I don't change that line, the GetValue works for the first 4 properties, then will also fail but on different error - TargetParameterCountException ("Parameter count mismatch)
But I'm more concerned with the TargetException error.
So, is there a different way to get the value of an object's item properties (= column names, e.g firstname, age etc.) other than using GetValue(obj, Nothing)?
Thanks in advance for any help. (I will do some lookup on reflection too)
yimiqi replied on Thursday, September 20, 2007
If I don't change that line, the GetValue works for the first 4 properties, then will also fail but on different error - TargetParameterCountException ("Parameter count mismatch)
I found out what caused the ParameterCountException error.
When you use this line of code: Dim t As Type = obj.GetType()
Then do GetProperties, you will get list of propertyinfo like AllowRemove, AllowEdit, AllowNew, Count etc. and Item.
When you loop through each p as propertyinfo in the property list to GetValue, when hits the Item propertyinfo in the loop, you will get the above parameter error. It makes sense, because Item propertyinfo has its own child collection (the item properties of the object - in my case is the collection of my grid column names I'm after to build a string for). This problem can be resolved by replace one line of code (as in my last message in this thread).
But, my headache problem still there, TargetException was unhandled error "Object does not match target type" [;)]
I did a bit search on PropertyInfo.GetValue() on MSDN and found the following
PropertyInfo.GetValue Method
Returns the value of the property.
var ExpCollDivStr = ExpCollDivStr;
ExpCollDivStr = ExpCollDivStr + "ctl00_LibFrame_ctl097156fab,";
var ExpCollImgStr = ExpCollImgStr;
ExpCollImgStr = ExpCollImgStr + "ctl00_LibFrame_ctl09img,";
Overload List
But I'm lost as to what values I should set as parameters when Call GetValue(). I'm using GetValue(obj, Nothing), and this one gives me the target type exception error.
Could you help me out? Thanks in advance.
yimiqi replied on Friday, September 21, 2007
I figured out the problem.
the obj value passed in calling GetValue(obj, Nothing) is a ROC object. But when I use
Dim t As Type = obj.GetType().GetProperty("Item", New Type() {GetType(Integer)}).PropertyType to get the type
rather than
Dim t As Type = obj.GetType()
then to get the properties of t, I need to pass in the ROC's child object - RO object (e.g. ProjectInfo in ProjecList)
when propertyinfo.name = "Item", if you want to get all the properties exposed in the ROC.
Thanks.
xal replied on Friday, September 21, 2007
The code I sent is not intended to loop through collections by itself. It's just code for getting properties for a single instance.
If you need all the "ToStrings" in a collection, then you should loop through the collection and run each item agains the method I sent.
Otherwise, you'll have to use recursion, but first checking that the properties don't have indexers.
I assume you don't want to get the properties for the collection itself, just the items in the collection. Right?
Andrés
yimiqi replied on Friday, September 21, 2007
xal:
I assume you don't want to get the properties for the collection itself, just the items in the collection. Right?
Andrés
That's correct. I only want to get the items in the collection. E.g. ROC object ProjectList has its properties, and item is one of them. Item then has its own properties which is a list of public properties/fields (=column names) exposed by the business object. Item actually is the RO object, ProjectInfo in this case. I only want to get all the properties/fields in ProjectInfo.
Thanks for the help.
xal replied on Friday, September 21, 2007
So again, loop through the list yourself and pass each of the items to the method I sent you.
Andrés
yimiqi replied on Friday, September 21, 2007
Got it. Thanks a lot.
Copyright (c) Marimer LLC