I'm using a postcode lookup service provided online using a class they provide.
The returned information is a list of addresses in the format
<XmlRootAttribute("Addresses")> _
Public Class Addresses
<XmlElementAttribute("Address")> _
Public Address As List(Of Address)
End Class
where Address is
Public Class Address
Public organisation As String
Public premise As String
Public dependentstreet As String
Public street As String
Public doubledependentlocality As String
Public dependentlocality As String
Public posttown As String
Public county As String
Public postcode As String
Public summaryline As String
Public Overrides Function ToString() As String
Return summaryline
End Function
End Class
The summaryline property returns a comma separated list of the Address class (e.g)
Fox Road, Framingham Pigot, Norwich, Norfolk, NR14 7PZ
I'm using this list of returned addresses to populate a dropdownlist, which will then split up the selected address into "Address 1", "Address 2", "Town" etc.
In the code example provided they are using a Windows Form and populate a Combobox and the line that splits the comma seperated address into an Address class is this line
Dim address As Address = DirectCast(addresses_ComboBox.SelectedItem, Address)
organisation_TextBox.Text = address.organisation
premise_TextBox.Text = address.premise
dependentStreet_TextBox.Text = address.dependentstreet
street_TextBox.Text = address.street
doubleDependentLocality_TextBox.Text = address.doubledependentlocality
locality_TextBox.Text = address.dependentlocality
town_TextBox.Text = address.posttown
county_TextBox.Text = address.county
postcode_TextBox.Text = address.postcode
Is there a way for me to convert that top line but using dropdownlist.SelectedValue instead of addresses_ComboBox.SelectedItem
I can split the string into an array but not all addresses have all of the Address class properties returned. Some addresses may not have a Premise for example so I can't convert the comma separated address back into the Address class perfectly into each property.
Thanks for looking!
Related
I have a WEB Method in my ASPX page that retrieves a List from SQL DB using Entity Framework.
Using rep As New RBZPOSEntities
q = rep.getSalesByLocation(fDate, tDate).ToList
End Using
Thereafter i use javascriptserializer to convert this list into a JSON string
Dim jss As JavaScriptSerializer = New JavaScriptSerializer()
Dim json As String = jss.Serialize(q)
So the above works great and i can use AJAX on the client side to display the results successfully.
The problem i am having now is converting a Flat List into a Nested JSON string.
So consider a list like:
locationName as string
MonthName as string
totalAmount as string
Which needs to be converted into a JSON like this:
[{locationName:'Tokyo',totalAmount:[100,200,300,400]},
{locationName:'New York',totalAmount:[500,600,700,800]}]
So the totalAmount values in the above case correspond to totalAmounts for a Location for a specific month. E.g. Tokyo total amount in January is 100, in February is 200 and etc.
What i can do:
I can create a nested list and populate it with results from EF and then serialize to JSON.
What i am asking:
Is there any other cleaner way to do it.
Thank you
As Todd has already said you need to convert your flat list into a list of another intermediate type. Let's call your existing Type the "InputType" and the Type you want the "OutputType"
Public Class InputClass
Public locationName as String
Public MonthName as String
Public totalAmount as String
End Class
Public Class OutputClass
Public LocationName As String
Public TotalAmount As List(Of String)
Public Sub New(groupedInputClass As IGrouping(Of String, InputClass))
LocationName = groupedInputClass.Key
TotalAmount = groupedInputClass.Select(Function(x) x.totalAmount).ToList()
End Sub
End Class
Then all you need to do is transform a List of InputType into a List of OutputType which is really easy with LINQ.
Public Class MappingHelper
Public Function Map (inputList as List(Of InputClass)) As List(Of OutputClass)
Dim groupedByLocation = inputList.GroupBy(Function(k) k.LocationName)
Dim nestedLocations = groupedByLocation.Select(Function(x) new OutputClass(x)).ToList()
Return nestedLocations
End Function
End Class
If you use an intermediate type, it may be helpful. Something like:
class RbzposInfo {
public string Location {get;set;}
public List<MonthlyRevenue> Monthlies {get;set;}
}
class MonthlyRevenue {
public string Month {get;set;}
public int Revenue {get;set;}
}
var result = new List<RbzposInfo>();
foreach (var r in q) { // q from your code
var info = new RbzposInfo();
// TODO: put r values into info.
result.Add(info);
}
Dim json As String = jss.Serialize(result);
(PS, sorry I mixed .NET languages on you. My code is C#.)
I am currently working on the return class. The problem is I want to show the certain member only when some of the condition meet. Below is my code. I only want to show ResponseMsg member when the ResponseCode is 99 otherwise it will be hidden.
Public Class LoginResponse
Public Property TerminalID As String
Public Property ReaderID As String
Public Property TransRef As String
Public Property TransDateTime As String
Public Property Timeout As Integer
Public Property ResponseCode As String
Public Property ResponseMsg As String
Public Property Cryptogram As String
End Class
You can't that I know of. But you can do something like this:
Public Property ResponseMsg
Get
If ResponseCode <> SomeCodeValue
Return _responseCode
Else
Return Nothing
End if
End Get
End Property
You might want to think about making a specialized class.
Let's say you have your basic LoginResponse
Public Class LoginResponse
Public Property TerminalID As String
Public Property ReaderID As String
Public Property TransRef As String
Public Property TransDateTime As String
Public Property Timeout As Integer
Public Property ResponseCode As String
' Note: no ResponseMsg here
Public Property Cryptogram As String
End Class
Then you'd have an extended response class inheriting your basic LoginResponse:
Public Class LoginResponseEx : Inherits LoginResponse
Public Property ResponseMsg As String
End Class
Then where ever you create those LoginResponse objects, you just create one of the apropriate.
Let's say you have a GetResponse() procedure like:
Public Function GetResponse() As LoginResponse
Dim result As LoginResponse = Nothing
Dim code As Integer = GetSomeCode()
' ... get the other properties
' Say you have a const or something with the appropriate code: SPECIAL_CODE
If code = SPECIAL_CODE Then
Dim msg As String = GetSomeMessage()
result = New LoginResponseEx(..., code, msg, ...) ' have a special Response
Else
result = New LoginResponse(..., code, ...) ' have a normal Response
End If
Return result
End Function
Finally when checking the response you just check whether you have a special value in ResponseCode and cast the object respectivly.
'...
Dim resp as LoginResponse = GetResponse()
If resp.ResponseCode = SPECIAL_CODE Then
Dim respx as LoginResponseEx = CType(resp, LoginResponseEx)
Console.WriteLine("ResponseMessage was: " & respx.ResponseMsg
Else
Console.WriteLine("No ResponseMessage")
End If
'...
This way you have your basic LoginResponse with the ResponseMsg hidden in the special class ResponseLoginEx
Note when you do this you should think about how you implement virtual classes. e.g. the fields might have to be declared as Protected instead of Private, though i'm sure you'll do fine.
This also works with Serializable classes, of course.
I have a Hospital table and the Addresses tables where i have written a simple data query to the DB
db.Hospitals.All().Join(DB.Address,out address).
Select(db.Hospitals.name,address.PostCode.As(Address.PostCode));
The Hospital Model class has Address internally
Class HospitalModel
{
public string Name{get;set;}
public HospitalAddress Address{get;set;}
}
public class HospitalAddress
{
public string PostCode{get;set;}
}
I am able to get the Name property but the postcode in HospitalAddress doesn't seem to work. Wondering where this is a problem .
Try:
db.Hospitals.All().WithAddress();
That should eager-load the Address which will make the cast work as expected.
Orgnization{
private String name;
private String uniqueId;
private boolean selfRegEnabled;
private List<Address> addrList;
public void setAddress(Address a){..}
public void setName(String name){..}
}
Addess{
private String type;
private String line1;
private String line2;
private String line3;
private String city;
private String state;
private String zip;
private String country;
}
CSV Header Columns are as below
System.UniqueID,Name,EnableSelf-Registration,Addr1.Type,Addr1.Line1,Addr1.Line2,Addr1.Line3,Addr1.City,Addr1.State,Addr1.Zip,Addr1.Country,Addr2.Type,Addr2.Line1,Addr2.Line2,Addr2.Line3,Addr2.City,Addr2.State,Addr2.Zip,Addr2.Country,Addr3.Type,Addr3.Line1,Addr3.Line2,Addr3.Line3,Addr3.City,Addr3.State,Addr3.Zip,Addr3.Country
My question might be related to below link
OpenCSV CSV to JavaBean
I didn't see that thread has a proper answer (I am not sure if I miss any from that thread)
Can we achieve same thing with any of the existing csv libraries such as supercsv, opencsv?
If I am using supercsv - can I map System.UniqueID column of csv to systemUniqueID property of my bean
You can certainly do this with Super CSV using CsvDozerBeanReader. See this example on the website.
It's also explained in a bit more detail on this SO answer.
You may also be interested in this recent question, as it demonstrates the different ways to achieve deep/indexed mapping with Super CSV (with and without using Dozer).
Following the CsvDozerBeanReader example on the website, to read the CSV from your question you would use a field mapping of:
final String[] fieldMapping = new String[]{
"uniqueId",
"name",
"selfRegEnabled",
"addrList[0].type",
"addrList[0].line1",
"addrList[0].line2",
"addrList[0].line3",
"addrList[0].city",
"addrList[0].state",
"addrList[0].zip",
"addrList[0].country",
"addrList[1].type",
"addrList[1].line1",
"addrList[1].line2",
"addrList[1].line3",
"addrList[1].city",
"addrList[1].state",
"addrList[1].zip",
"addrList[1].country",
"addrList[2].type",
"addrList[2].line1",
"addrList[2].line2",
"addrList[2].line3",
"addrList[2].city",
"addrList[2].state",
"addrList[2].zip",
"addrList[2].country"
};
Also, because the selfRegEnabled field is a boolean, you'll need to use cell processors to transform the String value into a Boolean - to do this you'd use the ParseBool processor.
Ok, I'me getting real dumb with this one....
I have this class:
Public Class whatever
Public id as string
Public name as string
public date as string
end class
Wich I use with this code:
dim personlist as new arraylist
dim person as new whatever
person.id="1"
person.name="bozo"
person.date="6-6-6"
personlist.add(person)
and then i repeat so that i can fill my arraylist with all the information that I want to show in my gridview.
The problem is this:
gridview1.datasource = personlist
gridview1.databind()
When executing, I get an error saying :
The data source for GridView with id 'gdpersonlist' did not have any properties or attributes from which to generate columns. Ensure that your data source has content.
Can anyone help me or perhaps point me in the right direction to do this?!
Try using properties instead of fields. The data binding for the grid view won't work for fields.
Public Class whatever
Public _id as string
Public name as string
public date as string
Public Property Id As String
Get
Return _id
End Get
Set (value as String )
_id = value
End Set
End Property
' repeat for all 3 fields
end class