komodore
komodore

Reputation: 13

C# s7net problem with reading string by class from s7-1200

In my first C# project I have class:

    internal class DbVisuStart
{
    //      Start                       6.0 -   
    //      Start_Lines                     6.0 -   
    [S7String(S7StringType.S7String, 40)]
    public string Start_Lines_Lines0 { get; set; } = "";    //  6.0 -   
    [S7String(S7StringType.S7String, 40)]
    public string Start_Lines_Lines1 { get; set; } = "";    //  48.0    -   
    [S7String(S7StringType.S7String, 40)]
    public string Start_Lines_Lines2 { get; set; } = "";    //  90.0    -   
    [S7String(S7StringType.S7String, 40)]
    public string Start_Lines_Lines3 { get; set; } = "";    //  132.0   -   
    [S7String(S7StringType.S7String, 40)]
    public string Start_Lines_Lines4 { get; set; } = "";    //  174.0   -   
    [S7String(S7StringType.S7String, 40)]
    public string Start_Lines_Lines5 { get; set; } = "";    //  216.0   -   
    [S7String(S7StringType.S7String, 40)]
    public string Start_Lines_Lines6 { get; set; } = "";    //  258.0   -   
}

I'm using the [S7.Net] 1 library and in the class.cs file on line 101 I get an exception and I don't know what's wrong with my class.

In VS2022 output data is:

Exception thrown: "System.ArgumentException" at S7.Net.dll Exception thrown: "System.ArgumentException" in System.Windows.Forms.dll Unhandled Exception of type "System.ArgumentException" occurred in System.Windows.Forms.dll Please add S7StringAttribute to the string property

I have problem only with string. Help me please.

EDIT: This is a fragment of code from class.cs file S7.Net library (Jason-Jelks/s7netplus from github):

            case "String":
                numBytes = Math.Ceiling(numBytes);
                if ((numBytes / 2 - Math.Floor(numBytes / 2.0)) > 0)
                    numBytes++;
                
                S7StringAttribute? attribute = type.GetCustomAttributes<S7StringAttribute>().SingleOrDefault();
                
                
                if (attribute == default(S7StringAttribute))
                    throw new ArgumentException("Please add S7StringAttribute to the string property"); //Line 101
                
                numBytes += attribute.ReservedLengthInBytes;
                break;

screenshot VS2022 class.cs with breakpoint in line 100

  System.Linq.Enumerable.SingleOrDefault<TSource> (zwrócona)  null    S7.Net.Types.S7StringAttribute
  attribute   null    S7.Net.Types.S7StringAttribute
  type    {Name = "String" FullName = "System.String"}    System.Type {System.RuntimeType}

EDIT2: Sorry for the wrong link to the library I am using. Now it is correct.

Below is the call path in my program:

        DbVisuStart dbVst = new();

    private void Timer1_Tick(object sender, EventArgs e)
    {
        timer1.Interval = 250;
        lblDateTime.Text = System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
        ReadS7(this);//InvUpd(this.Controls);
    }

    private static void ReadS7(FrmMain frm)
    {
        //frm.plc.ReadClass(frm.dbVa, 1, 0); // this is without strings and is ok
        frm.plc.ReadClass(frm.dbVst, 1, 6);
        //frm.plc.ReadClass(frm.dbVAc,1, 718); // this is without strings and is ok
    }

Upvotes: 1

Views: 887

Answers (1)

Johannes Krackowizer
Johannes Krackowizer

Reputation: 660

The S7StringAttribute is not supported on properties, you can use that only on fields. I assume your problem is that the backing fields for your properties are not decorated with an attribute (because they are autogenerated). And the second thing i see there is you use a class, as far as I remember you shuld use struct for the data representations. So your class should be refactored to this:

internal struct DbVisuStart
{
    //      Start                           6.0 -   
    //      Start_Lines                     6.0 -   
    [S7String(S7StringType.S7String, 40)]
    public string Start_Lines_Lines0;    //  6.0 -   
    [S7String(S7StringType.S7String, 40)]
    public string Start_Lines_Lines1;    //  48.0    -   
    [S7String(S7StringType.S7String, 40)]
    public string Start_Lines_Lines2;    //  90.0    -   
    [S7String(S7StringType.S7String, 40)]
    public string Start_Lines_Lines3;    //  132.0   -   
    [S7String(S7StringType.S7String, 40)]
    public string Start_Lines_Lines4;    //  174.0   -   
    [S7String(S7StringType.S7String, 40)]
    public string Start_Lines_Lines5;    //  216.0   -   
    [S7String(S7StringType.S7String, 40)]
    public string Start_Lines_Lines6;    //  258.0   -   
}

I personaly switched to the paid product IP S7 LINK .NET SDK from treager

Upvotes: 2

Related Questions