0

I'm quite new with C#. I have a function which gives me the results in an array like this

[0] => value
[1] => value
[2] => value 
[3] => value 
[4] => value 

But in my case, [0] [1] [2] need to be together, and I show them in a table in PHP. This is my function:

public List<string> ReadOpenCalls(int relation)
        {
            IQAssemblyResolver.Initialize(@"C:\Program Files\.....");
            IQSDK IQSDK = new IQSDK();
            string loginTekst = IQSDK.Login("Administrator", "..", "..").GetResult();

            SDKRecordset inboundSet = IQSDK.CreateRecordset("R_ACTIONSCOPE", "CODE, DESCRIPTION, DATECREATED", "FK_RELATION = " + relation, "");
            var messages = new List<string>();
            if (inboundSet != null && inboundSet.RecordCount > 0)
            {
                inboundSet.MoveFirst();

                 do
                 {
                    string code = inboundSet.Fields["CODE"].Value.ToString();
                    string desc = inboundSet.Fields["DESCRIPTION"].Value.ToString();
                    string date = inboundSet.Fields["DATECREATED"].Value.ToString();

                    messages.Add( code);
                    messages.Add( desc);
                    messages.Add( date);


                    inboundSet.MoveNext();
                 }
             while (!inboundSet.EOF);
                return messages;
            } 

            messages.Add("Error niet gelukt");
            return messages;// null;
        }

I want the output to be something like this:

[0] => [0] => "desc"
       [1] => "code"
       [2] => "date"

So that I can output this in a nice way in my table in PHP.

5 Answers 5

4

A very quick fix:

var messages = new List<string[]>();

...

     messages.Add( new string[] { code, desc, date});

But it also depends on what is easy to work with in PHP.

A better solution, probably, is to write a small class:

class MyMessage
{
    public string Code { get; set; }
    public string Desc { get; set; }
    public string Date { get; set; }
}

And of course you'd have to change the method into one of:

public List<string[]> ReadOpenCalls(int relation) ...
public List<MyClass> ReadOpenCalls(int relation) ...

and that change also needs to be made in the ServiceContract etc.

Sign up to request clarification or add additional context in comments.

8 Comments

Thanks for your answer, when I try the first fix I get an error: overloaded method match and invalid arguments. The second example, how do I use this exactly? I have 1 big class at the moment.
The messages.Add() should work this way. Please post the error line etc.
Re 2nd scenario: just add the class to your project. In a separate or the same file. And the change messages to List<MyMessage> and the return type as well.
I still get something like this result when I do a print_r in my php file: stdClass Object ( [string] => Array ( [0] => C0000000003 [1] => Test13:29:53 [2] => 24-5-2013 13:30:13 [3] => C0000000004 [4] => Test13:41:53 [5] => 24-5-2013 13:42:01 return messages: Error 1 'WcfWebService.Service1' does not implement interface member 'WcfWebService.ServiceContract.ReadOpenCalls(int)'. 'WcfWebService.Service1.ReadOpenCalls(int)' cannot implement 'WcfWebService.ServiceContract.ReadOpenCalls(int)' because it does not have the matching return type of 'System.Collections.Generic.List<string[]>'.
The change in return type cascades through the entire WCF stack... Again, I can't estimate what's practical in PHP.
|
2

PHP induces bad practices and a horrible understanding of data structures. Please do not try to pattern anything after whatever you saw or did in PHP. In particular, using array indices as a substitute for proper members.

Have you considered writing a class that has three fields to describe a message?

2 Comments

Haha well I'm actually only experienced in PHP so I got used to all of it ;) What do you mean with a class that has 3 fields?
See Henk's answer, he was less lazy than me.
1

Ideally you want to change the existing function, however using System.Linq you could alter your results after you've generated them.

var messages = ReadOpenCalls(relation);
var new messages = messages.Select((a,i) => new {index = i / 3, value = a})
                          .GroupBy (y => y.index, y => y.value)
                          .Select(g => g.ToList())
                          .ToList();

However you would be far better altering your function

either add the list directly

public List<List<string>> ReadOpenCalls(int relation)
    {
        IQAssemblyResolver.Initialize(@"C:\Program Files\.....");
        IQSDK IQSDK = new IQSDK();
        string loginTekst = IQSDK.Login("Administrator", "..", "..").GetResult();

        SDKRecordset inboundSet = IQSDK.CreateRecordset("R_ACTIONSCOPE", "CODE, DESCRIPTION, DATECREATED", "FK_RELATION = " + relation, "");
        var messages = new List<List<string>>();
        if (inboundSet != null && inboundSet.RecordCount > 0)
        {
            inboundSet.MoveFirst();

             do
             {
                string code = inboundSet.Fields["CODE"].Value.ToString();
                string desc = inboundSet.Fields["DESCRIPTION"].Value.ToString();
                string date = inboundSet.Fields["DATECREATED"].Value.ToString();

                messages.Add(new List<string> { code, desc, date});

                inboundSet.MoveNext();
             }
         while (!inboundSet.EOF);
            return messages;
        } 

        messages.Add("Error niet gelukt");
        return messages;// null;
    }

or make a class to hold the values and return a list of the class

UPDATE - OP has stated this is in a webservice so I've added the DataContract and DataMember attributes. You will need to make sure the project references System.Runtime.Serialization

using System.Runtime.Serialization;

[DataContract]
public class Class {

   public Class(string code, string desc, string date) { 
      this.code = code;
      this.desc = desc;
      this.date = date;
   }

   [DataMember]
   public string Code { get;set; }

   [DataMember]
   public string Desc { get;set; }

   [DataMember]
   public string Date { get;set; }
}

And then your altered function

public List<Call> ReadOpenCalls(int relation)
    {
        IQAssemblyResolver.Initialize(@"C:\Program Files\.....");
        IQSDK IQSDK = new IQSDK();
        string loginTekst = IQSDK.Login("Administrator", "..", "..").GetResult();

        SDKRecordset inboundSet = IQSDK.CreateRecordset("R_ACTIONSCOPE", "CODE, DESCRIPTION, DATECREATED", "FK_RELATION = " + relation, "");
        var messages = new List<Call>();
        if (inboundSet != null && inboundSet.RecordCount > 0)
        {
            inboundSet.MoveFirst();

             do
             {
                string code = inboundSet.Fields["CODE"].Value.ToString();
                string desc = inboundSet.Fields["DESCRIPTION"].Value.ToString();
                string date = inboundSet.Fields["DATECREATED"].Value.ToString();

                messages.Add( new Call(code,desc, date));

                inboundSet.MoveNext();
             }
         while (!inboundSet.EOF);
            return messages;
        } 

        messages.Add("Error niet gelukt");
        return messages;// null;
    }

5 Comments

Strange, it can't find "Call". I made a new class called Call like in your example. but I think I'm making a mistake in the ServiceContract. I'm adding the new Class like this: [OperationContract] public Class(string code, string desc, string date);
@Marijke Where did operationContract come from? I've given you the code to create the class.
In my webservice (ServiceContract.cs) I need to specify the functions etc. Like this: [OperationContract] List<List<string>> ReadOpenCalls(int relation);
@Marijke - If you go down the class route, you want to add Call as a new class to to your project, use my included code. I've updated the answer to include the DataContract and DataMember attributes that you are going to want to use.
@Marijke, in that case you will probably want to use the non class solution as it should give you the data in the format your PHP is expecting. Otherwise you will need to modify your PHP code to understand the class data arriving from the service.
1

Try this,

Change

public List<string> ReadOpenCalls(int relation)

to

public List<List<string>> ReadOpenCalls(int relation)

Change

var messages = new List<string>();  

to

var messages = new List<List<string>>();

And change

messages.Add( code);
messages.Add( desc);
messages.Add( date);

to

List<string> list = new List<string>();
list.Add( code);
list.Add(desc);
list.Add(date);
messages.Add(list); 

4 Comments

I still get it the same way: stdClass Object ( [string] => Array ( [0] => C0000000003 [1] => Test13:29:53 [2] => 24-5-2013 13:30:13 [3] => C0000000004 [4] => Test13:41:53 [5] => 24-5-2013 13:42:01 [6] => C0000000005 [7] => Test13:42:25 [8] => 24-5-2013 13:42:32 [9] => C0000000006 [10] => Test13:43:12 [11] => 24-5-2013 13:43:20 [12] => C0000000007 [13] => Test11:59:16 [14] => 31-5-2013 11:59:34 [15] => C0000000008 [16] => hh [17] => 31-5-2013 12:04:00 [18] => C0000000009
Thanks, I figured it out with your example! :D
@Marijke, I was not able to help you more. I was really stuck with some critical issue of mine.
No prob, I found it out myself with some little changes here and there ;)
0

Change function return value to string[][] and return the jagged array however you like.

4 Comments

Can you please explain this? How can I determine the value of it?
The value of a jagged array can be exracted by two indexers: var s = array[3][2];. Like this.
I get an error: Cannot implicitly covert type "char" to Systems.Collections.Generic.List<string>
Then you are not doing what you have to. Read about jagged arrays first.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.