Pass Array to a WCF function - c#

So, I have a C# project in which, I am loading a XML document (contains name of students and Id) using Linq to xml and I have to get the associated data (their due date, amount and stuff ) from a WCF service. I added the service with just right click and add service reference and now need to pass arrays to the GetData function, which I initialized but its null obviously. I cant able to convert my array to service type and the function returns array too. How do I assign the array to studentArray ?
ServiceReference1.ServiceClient client = new ServiceReference1.RycorServiceClient();
Application.ServiceReference1.Student[] studentArray = new ServiceReference1.Student[9];
Student[] array = studentList.ToArray();
//for (int i = 0; i <= array.Count(); i++)
// studentArray[i] = (RycorApplication.ServiceReference1.Student)array[i];
//this gives me an error says Cannot convert type 'Application.Student' to 'Application.ServiceReference1.Student'.
var data = client.GetData(studentArray);
After getting this data, how do I save this data to my XML file ?

You are getting this error because Application.Student is a different type, you can try to use Application.ServiceReference.Student to save the list of students instead of the "studentList" type.
I suppose that "studentList is an "Application.Student" list and you have to use the same model or make a copy between them using something like this (in the first answer):
Copy values from one object to another

You pretty much have to do this:
List<ServiceReference1.Student> wcfStudentList = new System.Collections.Generic.List<ServiceReference1.Student>();
foreach (var student in studentList)
{
wcfStudentList.Add(new ServiceReference1.Student()
{
ID = student.ID,
Name = student.Name,
..etc..
});
}
var data = client.GetStudentData(wcfStudentList.ToArray());
I do have to question why you don't just change the WCF call if you can to take a List of the student IDs instead of passing the entire object though?

Related

RavenDB does not store my new documents

This is my code of storing a new list of my data to documents:
using (var session = DocumentStoreHolder.Store.OpenSession())
{
//This list is used to put in the database -- Careful!!!
List<classA> List_01 = new List<classA>();
//This list is from database, used to compare with the new coming data.
//We will check with the list got from data.
List<ClassA> List_02 = session.Query<classA>().ToList();
//This uses the method Except to remove the duplicates between the new data
//and the current list of matches in database.Return data is the new match
//that is not existing in DB
List_01 = List_02.Except(List_00, new IdComparer()).ToList();
foreach (classA data in List_01)
{
//Why does it not store data in DB?!?!?!?!?
session.Store(data);
}
session.SaveChanges();
}
After I compare two lists together. The problem is that the session seems not store my data after all. I don't know what is wrong in my code. Any idea?
In your code, you're calling .Store(_match). Did you mean to call .Store(data)?
Also, note that your objects will be in the database after you call .SaveChanges. Calling .Store assigns the ID and tells Raven you want to store them, but it won't take affect until .SaveChanges is called.

Inserting elements to a multi dimensional List throwing index out of range exception

I am working on a C# list which is multi dimensional of type that I have created myself and I am trying to insert elements to that list from another list which for some reasons throwing Index was out of range exception when I trying to insert value into 0th row using the following code
List<StructuresDS> listStructures = new List<StructuresDS>();
listStructures[0].time =Convert.ToDateTime(AxiomSubSet[0].time.ToString("HH:mm:ss"));
listStructures[0].CC = AxiomSubSet[0].CC;
listStructures[0].term = listCodedTerms[0];
listStructures[0].strike = (Convert.ToDouble(AxiomSubSet[0].strike) * 100).ToString();
listStructures[0].strategy = AxiomSubSet[0].strategy;
listStructures[0].premium = Convert.ToDouble(AxiomSubSet[0].price);
listStructures[0].volume = Convert.ToInt32(AxiomSubSet[0].quantity);
May I know a reason for this behaviour and where I am making a mistake?
You're trying to set listStructures[0], but it hasn't been added yet. You should just need to do something like:
List<StructuresDS> listStructures = new List<StructuresDS>();
listStructures.Add(new StructureDS
{
time = Convert.ToDateTime(AxiomSubSet[0].time.ToString("HH:mm:ss")),
CC = AxiomSubSet[0].CC,
// etc.
});
I had to stub in values for both AxiomSubSet and listCodedTerms and assumed that AxiomSubset.time was a date but was a string in StructuresDS. I also assumed that premium and volume were double and int respectively & everything else was a string, but the code below compiles and functions as expected for me. I believe that your problem is that you're assuming there's a 0th element after the list has been instantiated but you've not added anything to it. A listStructures.Add(new StructuresDS {...}) would also address the issue.
List<StructuresDS> listStructures = new List<StructuresDS> {
new StructuresDS {
time = Convert.ToDateTime(AxiomSubSet[0].time.ToString("HH:mm:ss")),
CC = AxiomSubSet[0].CC,
term = listCodedTerms[0],
strike = (Convert.ToDouble(AxiomSubSet[0].strike) * 100).ToString(),
strategy = AxiomSubSet[0].strategy,
premium = Convert.ToDouble(AxiomSubSet[0].price),
volume =Convert.ToInt32(AxiomSubSet[0].quantity)
}
};
To test that the object was created as expected and the 0th element of the list contains the expected values, I wrote each property of the object to the console using the form below:
Console.WriteLine(listStructures[0].time.ToString());
Does that work for you when you apply it to your environment?

Arrays/Array Lists

I am fairly new to C#
I am trying to retrieve some information from an external data source and store it in array, once it is in an array I wish to sort it by time.
I know how to do this for just one column in a row, however the information I require has multiple columns.
For example:
foreach (Appointment Appoint in fapts)
{
// Store Appoint.Subject, Appoint.Start, Appoint.Organiser.Name.ToString(), Appoint.Location in an array
}
// Sort my array by Appoint.Start
foreach ( item in myNewArray )
{
//print out Appoint.Subject - Appoint.Start, Appoint.Organiser.Name.ToString() and Appoint.location
}
Many thanks for your help.
EDIT:
I have multiple data sources which pull in this:
foreach (Appointment Appoint in fapts)
{
// Store Appoint.Subject, Appoint.Start, Appoint.Organiser.Name.ToString(), Appoint.Location in an array
}
Hence the need to sort the items in a new array, I know this isn't very efficent but there is no way of getting the information I need in any other way.
You can sort a list using the LINQ sorting operators OrderBy and ThenBy, as shown below.
using System.Linq;
and then...
var appointments = new List<Appointment>();
var sortedAppointments = list.OrderBy(l => l.Subject).ThenBy(l => l.Name).ToList();
This will create a new list of appointments, sorted by subject and then by name.
It's unclear what your final aim is but:
Use a generic List instead of an array:
See this SO question for more information as to why using a List is prefered.
List<Appointment> appointments = new List<Appointment>();
foreach (Appointment Appoint in fapts)
{
appointments.Add(Appoint);
}
foreach (var item in appointments)
{
Console.WriteLine(item.Subject);
Console.WriteLine(item.Foo);
// Here you could override ToString() on Appointment to print eveything in one Console.WriteLine
}
If the aim of your code is to order by time, try the following:
var sortedAppointments = fapts.OrderBy(a => a.Start); // assuming Start is a DateTime property of `Appointment`.
Consider a Dictionary Object instead of an array if the data is conceptually one row multiple columns.
foreach(KeyValuePair<string, string> entry in MyDic)
{
// do something with entry.Value or entry.Key
}
You already have a list of objects in fpts, sort that list itself:
fpts.OrderBy(x => x.Subject).ThenBy(x => x.Location).ToList();
LINQ is your friend here.
fapts appears to already be a collection so you could just operate on it.
var myNewArray = fapts.OrderBy(Appoint => Appoint.Start).ToArray()
I've used the ToArray() call to force immediate evaluation and means that myNewArray is already sorted so that if you use it more than once you don't have to re-evaluate the sort.
Alternatively if you are only using this once you can just as easily miss the ToArray() portion out and then execution of the sort will be deferred until you try and enumerate through myNewArray.
This solution puts the source objects into the array, but if you are just wanting to store the specific fields you mention then you will need to use a select. You have two choices for the array item type, you can either use an anonymous class which provides difficulties if you are returning this array from a function or define a class.
For anonymous:
var myNewArray = fapts.OrderBy(Appoint => Appoint.Start)
.Select(Appoint => new {
Start = Appoint.Start,
Organiser = Appoint.Organiser.Name.ToString(),
Location = Appoint.Location
}).ToArray();
For named class assuming class is MyClass:
var myNewArray = fapts.OrderBy(Appoint => Appoint.Start)
.Select(Appoint => new MyClass {
Start = Appoint.Start,
Organiser = Appoint.Organiser.Name.ToString(),
Location = Appoint.Location
}).ToArray();
You have a wide range of options. The 2 most common are:
1) Create a class, then define an array or list of that class, and populate that
2) Create a structure that matches the data format and create an array or list of that
Of course, you could put the data into an XML format or dataset, but that's probably more work than you need.
public List<foo> appointments = new List<foo>();
public struct foo
{
public string subject ;
public DateTime start ;
public string name ;
public string location ;
}
public void foo1()
{
// parse the file
while (!File.eof())
{
// Read the next line...
var myRecord = new foo() ;
myRecord.subject = data.subject ;
myRecord.start = data.Start ;
myRecord.name = data.Name ;
//...
appointments.Add(myRecord);
}
}
Enjoy
(Since I can't comment and reply to the comment - it wasn't clear if he had a class, etc. or was just showing us what he wanted to do. I assumed it was just for demonstration purposes since there wasn't any info as to how the data was being read. If he could already put it into a class, than the first answer applied anyway. I just tossed the last 2 in there because they were options for getting the data first.)

list.add seems to be adding a reference to the original object?

I have created a couple custom classes (NTDropDown and NTBaseFreight) which I use to store data that I retrieve from a DB. I initialize a List of NTBaseFreight and 2 lists for NTDropDown.
I can successfully use List.Add to add freights to the freights list, but as I debug the code, my 2 dropdown lists contain only 1 NTDropDown, which always has the same values as NTDropDown (I'm assuming this is a referencing problem, but what am I doing wrong)?
To give an example, on the second row, if the carrier and carrier_label were "001", "MyTruckingCompany" and I put a break on the if statement for frt_carriers, both frt_carriers and frt_modes would contain only 1 item in their list, with the values "001", "MyTruckingCompany"...the same values in NTDropDown.
Code:
List<NTDropDown> frt_carriers = new List<NTDropDown>();
List<NTDropDown> frt_modes = new List<NTDropDown>();
List<NTBaseFreight> freights = new List<NTBaseFreight>();
NTDropDown tempDropDown = new NTDropDown();
NTBaseFreight tempFreight = new NTBaseFreight();
//....Code to grab data from the DB...removed
while (myReader.Read())
{
tempFreight = readBaseFreight((IDataRecord)myReader);
//check if the carrier and mode are in the dropdown list (add them if not)
tempDropDown.value = tempFreight.carrier;
tempDropDown.label = tempFreight.carrier_label;
if (!frt_carriers.Contains(tempDropDown)) frt_carriers.Add(tempDropDown);
tempDropDown.value = tempFreight.mode;
tempDropDown.label = tempFreight.mode_label;
if (!frt_modes.Contains(tempDropDown)) frt_modes.Add(tempDropDown);
//Add the freight to the list
freights.Add(tempFreight);
}
Yes, a list of reference types is actually just a list of references.
You have to create a new instance for each object that you want to store in the list.
Also, the Contains method compares references, so two objects containing the same data are not considered to be equal. Look for a value in the properties of the objects in the list.
if (!frt_carriers.Any(c => c.label == tempFreight.carrier_label)) {
NTDropDown tempDropDown = new NTDropDown {
value = tempFreight.carrier,
label = tempFreight.carrier_label
};
frt_carriers.Add(tempDropDown);
}
tempDropDown is the same object throughout the whole loop. You will need to create a new instance of it if you want to add more than one.
I'm having a hard time trying to figure out what exactly your'e trying to do with adding that tempDropDown the the list.

Trying to create a WebService to return a 3D Array to populate table with javascript

I am trying to create a dynamic table that is being built based on the value of a search text box. The Table will have probably 6 columns of 20(max) rows.
My problem is I can't figure out how to return the data from the web-service to the JS function in a way that will allow me to extract the data that I need.
Here is the web-service method I have currently:
[WebMethod]
public v_EMU_AIR_AIR[] GetCompletionList(string prefixText)
{
NeoDataContext dataContext = new NeoDataContext();
var results = from a in dataContext.GetTable<v_EMU_AIR_AIR>()
where a.Report_Date_ID.StartsWith(prefixText) ||
a.Item_Description.Contains(prefixText) ||
a.Drw_Nbr.StartsWith(prefixText)
select a;
return results.ToArray<v_EMU_AIR_AIR>();
}
This will return an Array my objects, but in my javascript:
populateTable:function(returnList) {
var length = returnList.childNodes[0].childNodes.length
for(var i=0; i<length; i++) {
var textValue = returnList.childNodes[0].childNodes[i].textContent
$("<tr><td>" + textValue + "</td></tr>").insertAfter(this.tblResults[0].childNodes[1]);
}
}
All I can produce is a dump of the entire Object and can't pull out the specific fields that I need.
I would serialize your object using Javascript Object Notation (JSON).
Unfortunately, this feature isn't built in to the .NET framework, so you'll need to write the code yourself.
Fortunately, most of it is already done for you. Check out this link or this link for more information.
In your javascript, you can retreive the JSON object with jquery (documentation) and access the values of your properties like you would in C#
$(document).ready(function() {
$.getJSON("http://url.to.webservice.com/", function(jsonObj) {
alert(jsonObj.property);
});
});

Categories