I am using this Return list in WCF example but I cannot implemment the client code correctly. The example works. I want the list transfered on the client side.
My code so far:
List<Person> aPerson = new List<Person>()
Person y = new Person()'
aPerson.Add(y.id, y.name, y.adress, y.salary, y.country)
This is the server:
[DataContract]
public class Person
{
public string Id;
public string name;
public string address;
public string salary;
public string country;
public Person()
{ }
public Person(string _id, string _name, string _address, string _salary, string _country)
{
Id = _id;
name = _name;
address = _address;
salary = _salary;
country = _country;
}
[DataMember]
public string Idps
{
get { return Id; }
set { Id = value; }
}
[DataMember]
public string nameps
{
get { return name; }
set { name = value; }
}
[DataMember]
public string addressps
{
get { return address; }
set { address = value; }
}
[DataMember]
public string salaryps
{
get { return salary; }
set { salary = value; }
}
[DataMember]
public string countryps
{
get { return country; }
set { country = value; }
}
}
public List <Person> GetData(string Id)
{
//Create a List of Person objects
List<Person>employeelist =new List<Person>();
employeelist.Add(new Person("10", "name", "myAdress", "1000", "myCountry");
}
//Return the list that contains Person objects
return employeelist;
}
I don't know how to implement the client side using the code above. The server returns the list and I want to store the list local at the client.
I think you are best off walking through a full end-to-end example as found here: http://msdn.microsoft.com/en-us/library/bb386386.aspx which should help you get up to speed with WCF.
However, as a jump start... I assume that in your interface you have decorated your method GetData with the [OperationContract] attribute?
Then on the client you need to reference the WCF Service. When adding the service you should click on the Advanced button in the lower-left corner of the dialog. Change the Collection type drop-down from System.Array to
System.Collections.Generic.List.
Finally, your client should be able to call the service with some code like this:
public void SampleClientCode()
{
using (var client = new ServiceReference1.Service1Client())
{
List<Person> results = client.GetData("12345");
// Now do something with the data... Example
string firstPersonsName = results.First().nameps;
}
}
NOTE: Your property naming convention in your Person class is not very good and should be revised.
Related
I am trying to output the whole list to console, but all I end up getting is the message "Stack overflow 19277 times". Can someone please help me out? I have now added the rest of the code. As you can see, the list wont print to console. I have tried many ways. The ideal solution would be a PrintAllEmployees-method to console under the company class.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Entities
{
public class Person
{
private string name;
private int age;
public string Name
{
get { return name; }
set { name = value; }
}
public int Age
{
get { return age; }
set { age = value; }
}
public Person(string name, int age)
{
name = Name;
age = Age;
}
}
public class Employee : Person
{
public string hireDate;
public Employee(string name, int age, string hireDate) : base(name, age)
{
hireDate = HireDate;
}
public string HireDate
{
get { return hireDate; }
set { hireDate = value; }
}
}
public class Company
{
public List<Person> employeesList = new List<Person>();
public string companyName
{
get { return companyName; }
set { companyName = value; }
}
public int employeeCount
{
get { return employeeCount; }
set { employeeCount = value; }
}
public Company(string CompanyName, int EmployeeCount)
{
EmployeeCount = employeeCount;
CompanyName = companyName;
}
}
}
using Entities;
namespace Checkpoint_2___Console_App
{
public class Program
{
static void Main(string[] args)
{
List<Person> employeesList = new List<Person>();
Person myPerson = new("Kari", 35);
Employee myEmployee = new("Ole", 35, "10.10.2000");
Company myCompany = new("Baker Hansen", 15);
employeesList.Add(myPerson);
employeesList.Add(myEmployee);
}
}
}
Look at this code:
public string companyName
{
get { return companyName; }
...
It says, "If you want to know the company name, you need to know the company name". That leads to stack overflow, because it keeps looping.
I guess what you meant was:
public string CompanyName
{
get { return companyName; }
...
Convention is that property names start with uppercase, private members with lower case.
The same goes for employeeCount.
My team is developing a WCF service to communicate with database tables. Lately, we have been noticing that if we insert a new record to some of the tables, the integer and Boolean values would not be saved to the record, but strings would work just fine.
It appeared that functions in the service that receive a DataContract class as a parameter would have null values for all their non-string properties.
I have set up a new class to test this out:
[DataContract]
public class MyObject
{
private string _Name;
[DataMember]
public string Name
{
get { return _Name; }
set { _Name = value; }
}
private int? _TestInt;
[DataMember]
public int? TestInt
{
get { return _TestInt; }
set { _TestInt = value; }
}
public MyObject()
{
_Name = "";
_TestInt = 0;
}
}
I have added functions to my service to simply return the value of the properties in the above class:
[OperationBehavior]
public string GetMyName(MyObject myObject)
{
return myObject.Name;
}
[OperationBehavior]
public int? GetMyTestInt(MyObject myObject)
{
return myObject.TestInt;
}
I have configured the service reference on my client application to not reuse types in referenced assemblies.
This is the code I use to test on the client:
MyObject record = new MyObject();
record.Name = "This is Me";
record.TestInt = 5;
int? returnValue = _client.GetMyTestInt(record);
string message;
if (returnValue == null)
message = "Integer value is null.";
else
message = "Integer value is " + returnValue.ToString();
MessageBox.Show(message, _client.GetMyName(record));
The code above shows a message that the integer returned by my service is null, instead of the 5 that I assigned it. GetMyName, however, does return the proper value for my string, which displays as the caption of my message box.
Why is it that the service seems to be receiving null values?
You have to add the [DataMember] attribute to the backing field.
Change your contract like this:
[DataContract]
public class MyObject
{
[DataMember] // data contract on backing field
private string _Name;
public string Name
{
get { return _Name; }
set { _Name = value; }
}
[DataMember] // data contract on backing field
private int? _TestInt;
public int? TestInt
{
get { return _TestInt; }
set { _TestInt = value; }
}
public MyObject()
{
_Name = "";
_TestInt = 0;
}
}
In DataContract Add the Property attribute as
[DataMember(IsRequired = true)]
I am trying to add entries in dictionary array list but i don't know which arguments to set in the People Class in the main function.
public class People : DictionaryBase
{
public void Add(Person newPerson)
{
Dictionary.Add(newPerson.Name, newPerson);
}
public void Remove(string name)
{
Dictionary.Remove(name);
}
public Person this[string name]
{
get
{
return (Person)Dictionary[name];
}
set
{
Dictionary[name] = value;
}
}
}
public class Person
{
private string name;
private int age;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public int Age
{
get
{
return age;
}
set
{
age = value;
}
}
}
using this seem to give me error
static void Main(string[] args)
{
People peop = new People();
peop.Add("Josh", new Person("Josh"));
}
Error 2 No overload for method 'Add' takes 2 arguments
This peop.Add("Josh", new Person("Josh"));
should be this
var josh = new Person() // parameterless constructor.
{
Name = "Josh" //Setter for name.
};
peop.Add(josh);//adds person to dictionary.
The class People has the method Add which only takes one argument: a Person object. The Add on the people class method will take care of adding the it to the dictionary for you and supplying both the name (string) argument and the Person argument.
Your Person class only has a parameterless constructor, which means that you need to set your Name in the setter. You can do this when you instantiate the object like above.
For your design this would solve the problem:
public class People : DictionaryBase
{
public void Add(string key, Person newPerson)
{
Dictionary.Add(key , newPerson);
}
public void Remove(string name)
{
Dictionary.Remove(name);
}
public Person this[string name]
{
get
{
return (Person)Dictionary[name];
}
set
{
Dictionary[name] = value;
}
}
}
public class Person
{
private string name;
private int age;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public int Age
{
get
{
return age;
}
set
{
age = value;
}
}
}
And in Main:
People peop = new People();
peop.Add("Josh", new Person() { Name = "Josh" });
Given the two classes below, how can I
convert List<Person> to
List<Person2>?
EDIT: This is a fabricated example. The point I'm trying to make is that I can't modify the Person class, and we'll know arbitraryNumber when we instantiate List<Person2>.
EDIT2: I know that many of you will find this unbelievable, but this code will be deployed to a Windows-Server-2000 machine, which means that it must work with .NET 2.0. [Yes - I find this to be unbelievable as well.]
public class Person
{
private string _lastName;
public string LastName
{
get { return _lastName; }
set { _lastName = value; }
}
private string _firstName;
public string FirstName
{
get { return _firstName; }
set { _firstName = value; }
}
}
public class Person2 : Person
{
private readonly int _arbitraryNumber;
public Person2(int arbitraryNumber)
{
_arbitraryNumber = arbitraryNumber;
}
public string FullName
{
get
{
return String.Format("{0}, {1} - {2}", LastName, FirstName, _arbitraryNumber);
}
}
}
I think Person2 needs to change to be an adapter. Something like this
public class Person2
{
private readonly int _arbitraryNumber;
private readonly Person _person;
public Person2(Person person, int arbitraryNumber)
{
_arbitraryNumber = arbitraryNumber;
_person = person;
}
public string FullName
{
get
{
return String.Format("{0}, {1} - {2}", _person.LastName, _person.FirstName, _arbitraryNumber);
}
}
}
Then the adapter on the collection is easier.
List<Person> persons = new List<Person>();
// put some people in it.
var person2s = persons.Select(p => new Person2(4, p)); // 4 chosen arbitrarily
Or for .NET 2
List<Person2> person2s = new List<Person2>();
foreach (Person p in persons)
{
Person2 person2 = new Person2(p, 11); // 11 arbitrarily chosen by asking a kid for a number
person2s.Add(person2);
}
Just found LinFu - looks very impressive, but I can't quite see how to do what I want to do - which is multiple inheritance by mixin (composition/delegation as I'd say in my VB5/6 days - when I had a tool to generate the tedious repetitive delegation code - it was whilst looking for a C# equivalent that I found LinFu).
FURTHER EDIT: TO clarify what I mean by composition/delegation and mixin.
public class Person : NEOtherBase, IName, IAge
{
public Person()
{
}
public Person(string name, int age)
{
Name = name;
Age = age;
}
//Name "Mixin" - you'd need this code in any object that wanted to
//use the NameObject to implement IName
private NameObject _nameObj = new NameObject();
public string Name
{
get { return _nameObj.Name; }
set { _nameObj.Name = value; }
}
//--------------------
//Age "Mixin" you'd need this code in any object that wanted to
//use the AgeObject to implement IAge
private AgeObject _ageObj = new AgeObject();
public int Age
{
get { return _ageObj.Age; }
set { _ageObj.Age = value; }
}
//------------------
}
public interface IName
{
string Name { get; set; }
}
public class NameObject : IName
{
public NameObject()
{}
public NameObject(string name)
{
_name = name;
}
private string _name;
public string Name { get { return _name; } set { _name = value; } }
}
public interface IAge
{
int Age { get; set; }
}
public class AgeObject : IAge
{
public AgeObject()
{}
public AgeObject(int age)
{
_age = age;
}
private int _age;
public int Age { get { return _age; } set { _age = value; } }
}
Imagine objects with many more properties, used in many more "subclasses" and you start to see the tedium. A code-gernation tool would actually be just fine...
So, LinFu....
The mixin example below is fine but I'd want to have an actual Person class (as above) - what's the LinFu-esque way of doing that? Or have I missed the whole point?
EDIT: I need to be able to do this with classes that are already subclassed.
DynamicObject dynamic = new DynamicObject();
IPerson person = null;
// This will return false
bool isPerson = dynamic.LooksLike<IPerson>();
// Implement IPerson
dynamic.MixWith(new HasAge(18));
dynamic.MixWith(new Nameable("Me"));
// Now that it’s implemented, this
// will be true
isPerson = dynamic.LooksLike<IPerson>();
if (isPerson)
person = dynamic.CreateDuck<IPerson>();
// This will return “Me”
string name = person.Name;
// This will return ‘18’
int age = person.Age;