tags:

views:

73

answers:

4

Any help here as I'm a C# noob. The following code works fine and returns 1 string ViewState2. I'd like it to return an array of ViewState2 and EventValidation2 so I can manipulate it later on. How would I convert the code below to return an array?

    public string get_status(string local_fname)
    {
        var dts_doc = new HtmlAgilityPack.HtmlDocument();
        dts_doc.Load(local_fname);

        //Pull the values
        var ViewState = dts_doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[1]/input[4]/@value[1]");
        var EventValidation = dts_doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[2]/input[1]/@value[1]");

        string ViewState2 = ViewState.Attributes[3].Value;
        string EventValidation2 = EventValidation.Attributes[3].Value;


        //Display the values

        //System.Console.WriteLine(ViewState.Attributes[3].Value);
        //System.Console.WriteLine(EventValidation.Attributes[3].Value);
        //System.Console.ReadKey();
        return ViewState2;
    }
+4  A: 

Don't use an array, but a class. Doing this, you don't have to remember what each element means.

public class Status
{
  public string ViewState {get; set;}
  public string EventValidation {get; set;}
}

using System;
using HtmlAgilityPack;

[...]

public Status GetStatus(string localFileName)
{
    var dtsDoc = new HtmlDocument();
    dtsDoc.Load(localFileName);

    //Pull the values
    var viewStateNode = dtsDoc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[1]/input[4]/@value[1]");
    var eventValidationNode = dtsDoc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[2]/input[1]/@value[1]");

    string viewState = viewStateNode.Attributes[3].Value;
    string eventValidation = eventValidationNode.Attributes[3].Value;


    //Display the values

    //Console.WriteLine(viewState);
    //Console.WriteLine(eventValidation);
    //Console.ReadKey();
    return new Status
    {
      ViewState = viewState,
      EventValidation = eventValidation
    }
}

Also, you should read up on coding guidelines and naming conventions in the C# language, also the using statement might be interesting. I have corrected some "mistakes", but probably didn't catch all. Also, I have renamed a couple of variables, to make their content clearer. You also might want to look into using the var keyword only in a loop, while using LINQ (or anomynous types in general) or with really long class names. Written out type names can increase readability quite a lot.

Femaref
Your answer is the correct way to do it, but due to my lack of C# experience, the quick and dirty is what works now. Thank you!
shaiss
A: 

Assuming you answer yes to this question (although I'd recommend a different approach, see below) this will do what you're asking:

public String[] get_status(string local_fname) 
{ 
    var dts_doc = new HtmlAgilityPack.HtmlDocument(); 
    dts_doc.Load(local_fname); 

    //Pull the values 
    var ViewState = dts_doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[1]/input[4]/@value[1]"); 
    var EventValidation = dts_doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[2]/input[1]/@value[1]"); 

    string ViewState2 = ViewState.Attributes[3].Value; 
    string EventValidation2 = EventValidation.Attributes[3].Value; 

    String[] retValues = new String[2];
    retValues[0] = ViewState2;
    retValues[1] = EventValidation2;

    return retValues;

    //Display the values 

    //System.Console.WriteLine(ViewState.Attributes[3].Value); 
    //System.Console.WriteLine(EventValidation.Attributes[3].Value); 
    //System.Console.ReadKey(); 
    return ViewState2; 
} 

That said, I would follow the approach afte the line.


I'd write a class that has the data members you want:

public class DataClass
{
    public string ViewState { get; set; }
    public string EventValidation { get; set; }
}

Then I'd modify the method to return an instance of your data class.

public DataClass get_status(string local_fname) 
{ 
    var dts_doc = new HtmlAgilityPack.HtmlDocument(); 
    dts_doc.Load(local_fname); 

    //Pull the values 
    var ViewState = dts_doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[1]/input[4]/@value[1]"); 
    var EventValidation = dts_doc.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[2]/input[1]/@value[1]"); 

    var dc = new DataClass();

    dc.ViewState = ViewState.Attributes[3].Value;
    dc.EventValidation = EventValidation.Attributes[3].Value;

    return dc;
} 
Nate Bross
+2  A: 

If you really want an array with ViewState2 and EventValidation2 in it, you can make the following changes:

// Notice: return value of string[] instead of string
public string[] get_status(string local_frame);

And:

// Notice: returning an array
return new string[] { ViewState2, EventValidation2 };

That said, this is really the "quick and dirty" approach, and is not really appropriate if you're going to want this code to be maintainable (when's the last time you read documentation on a function that "returns an array of length 2, with a string representing X as the first element and another string representing Y as the second"?).

Femaref's right; the correct thing to do would be to encapsulate the information you want returned in its own type.

Dan Tao
This is what I was looking for as I only need the quick and dirty. Thank you!
shaiss
A: 
string[] array = new string[2];

array[0] = ViewState2;
array[1] = EventValidation2;

return array;

But it seems to trivial as answer. Please Does it solve your problem? If no, can you specify better the question please?

robob