0

I'm currently working on my final project which contains the use of WCF, WPF and C# and I'm having a hard time transfering an object through wcf. I get an error after a while which says that the server did not provide a meaningful response. The classes that are in use in the method that crashes are:

[DataContract]
    public class Player
    {

        //public static int clientID = 0;
        [DataMember]
        public int Wins { get; set; }
        [DataMember]
        public int Loses { get; set; }
        [DataMember]
        public int realID { get; }
        [DataMember]
        public string nickName { get; set; }


        public Player(int Wins, int Loses, string nickName)
        {
            this.Wins = Wins;
            this.Loses = Loses;
            this.nickName = nickName;
            //clientID++;
            realID = 1; //clientID;
        }
    }
    [DataContract]
    public class Run
    {

       [DataMember]
        public List<Player> Players { get; set; }
        [DataMember]
        public bool isActive { get; set; }

        public Run()
        {
            Players = new List<Player>();
        }

        public void playerJoined(Player player)
        {
            Players.Add(player);
        }

        public void playerLeft(Player player)
        {
            if (Players.Contains(player)) Players.Remove(player);
        }

        public void generateRun()
        {
            //  TODO: get a random map from the DB and pass it to all players


            return;
        }
    }

and the method that crashes the code is:

    public Run getRunDetails(int runNumber)
    {
        runNumber = runNumber - 1;
        return Runs[runNumber];
    }

the code at the client side is:

ListBoxItem tempItem = ((ListBoxItem)allRuns.SelectedItem);
    if(tempItem != null && !tempItem.Content.Equals("There are no runs available, create one now."))
    {
        string numString = ((string)tempItem.Content);
        numString = numString.Substring(4, numString.Length - 4);
        run = Service.getRunDetails(int.Parse(numString));
    }

After some time of debugging I've found out the problem is in the list variable, I've tried to change it only to a Player variable -> getting the same error. Same goes for making my buffer and message sizes bigger. The only way the code wont crash and send my Run object is when the List is not a data member..

//[DataMember]
public List<Player> Players { get; set; }

If I do the above the code works perfectly but I desperately need the List passed to the client side. Sorry for the long post but I don't have a very long time and I need it done, any help will be very appreciated. (Also, sorry for the poor formatting, I did my best)

1 Answers1

0

I'm pretty sure the problem here is that you don't have a parameterless constructor in your Player...

try to add a

public Player() {}

to your class...

Either that or because your 'realId' [DataMember] has no setter, see this link for tips on correctly serializing readonly members. WCF: Exposing readonly DataMember properties without set?

Also, dont forget to 'Update Service Reference' on the WCF Service in the Visual Studio client Project if you have changed members in classes that are passed across the WCF Channel.

Community
  • 1
  • 1
Alan
  • 26
  • 3
  • A property without a setter will definitely cause a problem - I ran into that a while back and took me some digging to find out why the service was blowing up. – Tim Mar 08 '17 at 05:57
  • Added the empty constructor also added public Player(int Wins, int Loses, string nickName, int realID) { this.Wins = Wins; this.Loses = Loses; this.nickName = nickName; this.realID = realID; } Aswell as public int realID { get; set; } And it is working! thank you both very much. – Nitzan Shwartz Mar 08 '17 at 06:50
  • Thats great Nitzan. WCF/Contract Serialization is not exactly the same as XML Serialization but it does follow some of the same principles. Actually one of the problems in your code is that you are serializing what is actually a Business Object whereas really you should only be sending pure data objects down the wire where possible. Rather than a parameterised constructor consider using the constructor initializer syntax instead. `var MyObject=New Object(){Prop1=Value, Prop2=Value}` Please mark my answer if I was helpful! - Thanks – Alan Mar 08 '17 at 09:23
  • @Alan Actually this is how our lecturer wanted us to do it so.. I marked your answer but it won't show becuase I have a small amount of badges or something ~.~ Thanks again. – Nitzan Shwartz Mar 08 '17 at 16:12