8

I'm using ObjectForScripting property to interact with web page inside WebBrowser control and everything works fine except I can't figure out how to pass array of strings back to C#

HTML code

<input type="submit" onclick="window.external.save(Array('test', 'test2'))" />

Form

// Returns System.__ComObject
public void Save(object parameters)
{
}

// Throws an exception
public void Save(object[] parameters)
{
}

// Also throws an exception
public void Save(string[] parameters)
{
}
2
  • Did you find a working approach? Commented Mar 22, 2011 at 15:28
  • No. I read many negative responses about passing back arrays back to calling application. In the end I ended up with re-factored program where I have multiple method arguments instead of array. Commented Mar 27, 2011 at 15:56

6 Answers 6

2

Rather than fight it; maybe approach the problem from another angle... could you (instead, either of):

  • delimit the data (with Array.join) and pass a single string, and split it (string.Split) in the C#
  • call Save multiple times, accepting a single string each time (Save(string s)), then call a final method to actually commit the changes
Sign up to request clarification or add additional context in comments.

2 Comments

I could. I suspect you are suggesting that because marshaling objects from JS to .NET is tricky and doesn't worth it if workaround is possible. Are you?
@Sergej pretty much, yes. It doesn't want to work the way you are showing... so don't do that ;p
1

You can use an anonymous object instead of an array on the javascript side:

<input type="submit" onclick="window.external.save({first: 'test', second: 'test2'})" />

On the C# side (you need to use .NET 4.0 or more for the dynamic or use Type.InvokeMember if you are on an older version):

public void Save(dynamic parameters)
{
  MessageBox.Show(parameters.first);
  MessageBox.Show(parameters.second); 
}

Not tested, but I think you can use reflection to discover the members.

Also look at this: http://dotnetacademy.blogspot.fr/2009/11/vbnetcnet-communication-with-javascript.html

1 Comment

It worked and i prefered it instead of serializing and unserializing data.
0
function JS2VBArray( objJSArray )
{
    var dictionary = new ActiveXObject( "Scripting.Dictionary" );
    for ( var i = 0; i < objJSArray.length; i++ )
    {
        dictionary.add( i, objJSArray[ i ] );
    }

    return dictionary.Items();
}

Reference: http://msdn.microsoft.com/en-us/library/zsfww439(v=vs.80).aspx

<input type="submit" onclick="window.external.Save( JS2VBArray( ['test', 'test2'] ) )" />

This should go to the method.

public void Save(object[] parameters)
{
}

Comments

0

The string array is automatically passed as a comma-delimited string. So this call:

window.external.save(Array('test', 'test2'));

Is received like so:

public void save(string fromjs)
{
    string[] result = fromjs.Split(',');
}

Comments

0

It's a bit late for this, but typically when I need to pass objects or, in this case Arrays, I pass them as a JSON string.

var sArr = JSON.stringify(myArr);
window.external(sArr);

Then I have a JavaScriptSerializer on the other side that deserializes it back into an object / array.

Deserialize JSON with C#

Comments

0

To pass an array I found this to not be supported directly. I took the approach recommended by Marc Gravell to call multiple times but structured it in 3 methods instead, that are used in sequence: InitArgs, PushArg (multiple times), FinalArgs.

private System.Collections.Generics.Queue<string> _argsQ;
public void InitArgs()
{
    _argsQ = new System.Collections.Generics.Queue<string>();
}
public void PushArg(string arg)
{
    _argsQ.Enqueue(arg);
}
public void FinalArgs()
{
    string[] parameters = _argsQ.ToArray();
    // Save parameters
}

Now method calls can be used sequentially from html/js:

...onclick="var params = ['test', 'test2']; window.external.InitArgs(); for (var i=0; i<params.length; i++) window.external.PushArg(params[i]); window.external.FinalArgs();"...

Comments

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.