Custom script API method with options class isn't recognised

We've coded up a bunch of script API methods which work great, but we've come across an issue with one that we wanted to use a bunch of options with, just like you do in the core script APIs. An example of one of yours is;

So this accepts a bunch of named parameters via that object, and not all need to be supplied.

When we code up something similar the method never gets called.. here's some example code;

namespace Example.StuffAPI
{
	[Documentation(Category = "Blah")]
	public class UtilsAPI: IApi
	{

		public string GetStuff(StuffOptions options)
        {
			return options.Thingy + options.Foo;
        }
		
	    public class StuffOptions
		{
			public string Thingy { get; set; }
			public string Foo { get; set; }
		}
	}
}

When we call it from Velocity it only re-outputs the method name, indicating it can't find a matching signature for the method + parameters. 

$stuff.GetStuff("%{ Thingy='hello', Foo='world' }")

#set($options = "%{}")
$options.Add("Thingy", "hello")
$options.Add("Foo", "world")
$stuff.GetStuff($options)
 

If we switch out the C# method to use IDictionary instead it is called correctly..

namespace Example.StuffAPI
{
	[Documentation(Category = "Blah")]
	public class UtilsAPI: IApi
	{
		public string GetStuff(IDictionary options)
		{
			return options["Thingy"] + options["Foo"];			
		}
	}
}

The Velocity remains the same & now works.

We can obviously work with IDictionary, but I'm wondering why the first approach doesn't work & if we're missing something?

  • Former Member
    +1 Former Member

    The Velocity has to be called with the same method signature as the C#. $stuff.GetStuff("%{ Thingy='hello', Foo='world' }") is GetStuff(IDictionary) so it will not match up to a c# method that is GetStuff(StuffOptions).  We use IDictionary for all of our options methods and then parse the strings in the velocity method and generate a typed class that our c# APIs expect.

    Here is what a typical velocity API method looks like in our code.

            [Documentation("Gets a blog")]
    		        public Blog Get([
                Documentation(Name = "Id", Type = typeof(int), Description = "Either the Id or the Key + GroupId are required"),
                Documentation(Name = "Key", Type = typeof(string), Description = "Either the Id or the Key + GroupId are required"),
                Documentation(Name = "GroupId", Type = typeof(int), Description = "Either the Id or the Key + GroupId are required")]
                IDictionary options)
            {
                var query = new BlogsGetOptions();
                if (options != null)
                {
                    if (options["Id"] != null)
                        query.Id = Convert.ToInt32(options["Id"]);
                    if (options["Key"] != null)
                        query.Key = options["Key"].ToString();
                    if (options["GroupId"] != null)
                        query.GroupId = Convert.ToInt32(options["GroupId"]);
                }
                return BlogsApi.Get(query);
            }

  • Super; we ended up doing it like that yesterday, so I'm glad our approach lines up with how you're doing it. Thanks for the quick response & sample code Slight smile Much apprecitated.