danikf / tik4net

Manage mikrotik routers with .NET C# code via ADO.NET like API or enjoy O/R mapper like highlevel api.
Apache License 2.0
178 stars 94 forks source link

Can't use .proplist #56

Closed Deantwo closed 5 years ago

Deantwo commented 5 years ago

I am having trouble using the .proplist command parameter.

Allowing it to automatically detect the TikCommandParameterFormat seem, to make it fail and not return anything at all.

Example code:

ITikCommand cmd = conn.CreateCommand("/ip/address/print"
                                    ,conn.CreateParameter(".proplist", "address")
                                    ,conn.CreateParameter("interface", "bridge", TikCommandParameterFormat.Filter)
                                    ,conn.CreateParameter("disabled", "no", TikCommandParameterFormat.Filter)
                                    );
ITikSentence address = cmd.ExecuteSingleRow();

Nothing is returned at all.


I have dug into the source code a little to see why it isn't read correctly, and I think I have to set parameterFormat to TikCommandParameterFormat.Tag. But it doesn't work as I expected.

Example code:

ITikCommand cmd = conn.CreateCommand("/ip/address/print"
                                    ,conn.CreateParameter(".proplist", "address", TikCommandParameterFormat.Tag)
                                    ,conn.CreateParameter("interface", "bridge", TikCommandParameterFormat.Filter)
                                    ,conn.CreateParameter("disabled", "no", TikCommandParameterFormat.Filter)
                                    );
ITikSentence address = cmd.ExecuteSingleRow();

I am expecting only to get the address word, but I am still getting all the other properties from the router.


My old pure API program has it working fine like this:

_mikrotik.Send("/ip/address/print");
_mikrotik.Send("=.proplist=address");
_mikrotik.Send("?interface=bridge");
_mikrotik.Send("?disabled=no", true);
foreach (string h in _mikrotik.Read())
Deantwo commented 5 years ago

Ok, I got it to work! I have to I had to use TikCommandParameterFormat.NameValue. I had missed that it was called "=.proplist=address" in my old project, but tag was ".tag=glanip".

Working example code:

ITikCommand cmd = conn.CreateCommand("/ip/address/print"
                                    ,conn.CreateParameter(".proplist", "address", TikCommandParameterFormat.NameValue)
                                    ,conn.CreateParameter("interface", "bridge", TikCommandParameterFormat.Filter)
                                    ,conn.CreateParameter("disabled", "no", TikCommandParameterFormat.Filter)
                                    );
ITikSentence address = cmd.ExecuteSingleRow();

That is a little confusing though.


Wouldn't it be a nice help to make a conn.CreateProplistParameter("address")? Have it be a params string[] so we can just add as many as we want, and then hide the complicated stuff.

I might make a pull request for this tomorrow.

Deantwo commented 5 years ago

I just learned how to make extension methods, so here are some workarounds for now.

internal static ITikCommandParameter CreateProplistParameter(this ITikConnection conn, params string[] proplist)
{
    return conn.CreateParameter(".proplist", string.Join(",", proplist), TikCommandParameterFormat.NameValue);
}

internal static ITikCommandParameter AddProplistParameter(this ITikCommand cmd, params string[] proplist)
{
    return cmd.AddParameter(".proplist", string.Join(",", proplist), TikCommandParameterFormat.NameValue);
}
Deantwo commented 5 years ago

Don't like the pull request I made with this? #57 I am using my extension methods in my project with great success.