При использовании WebBrowser
управление я хотел бы передать объект от кода JavaScript до C#.
Решение известно - использование ObjectForScripting
свойство WebBrowser
и вызов методов от использования кода JavaScript window.external
.
Я знаю, как сделать это, но я хотел бы создать объект с данным типом в JavaScript и передать его C# без использования object
или dynamic
. Пример:
Я хотел бы назвать от JS этот метод в C#:
public void Test(Foo foo)
{
//do something
}
Где Foo
:
[ComVisible(true)]
public class Foo
{
public string Bar;
}
Я знаю, как назвать те методы:
public void Test2(object foo)
{
//do something
}
public void Test3(dynamic foo)
{
//do something
}
но я хотел бы использовать первый - Test(Foo foo)
Что я должен сделать, чтобы позволить передать объект класса Foo
от JS до C# или как бросить JS, возражают на лету против C# Foo
объект?
Я нашел по крайней мере два решения.
Первое, довольно очевидное, это то, что предложил Sheng Jiang. Вам нужно создать отдельную библиотеку классов с этими типами:
[ComVisible(true)]
public interface IFoo
{
string Bar { get; set; }
}
[ComVisible(true)]
public class Foo : IFoo
{
public string Bar { get; set; }
}
Эта библиотека типов должна быть зарегистрирована (Project/Properties/Build/Register for COM interop). Эти типы, особенно интерфейсы, должны использоваться в методах в exe, который имеет управление WebBrowser
. Например:
public string Bar(IFoo foo)
{
return foo.Bar;
}
public IFoo Bar2()
{
return new Foo() { Bar = "asdf" };
}
Теперь мы можем использовать эти типы в javascript:
var foo = new ActiveXObject("ClassLibrary1.Foo");
foo.Bar = "qwer";
alert(external.Bar(x));
var fooFromExternal = external.Bar2();
alert(fooFromExternal);
alert(external.Bar(fooFromExternal));
К сожалению, библиотека классов должна быть зарегистрирована и вы получите предупреждение ActiveX от IE.
Второе решение - не создавать библиотеку классов, а оставить эти типы в app exe. Нам все еще нужен интерфейс IFoo
, если мы хотим передавать объекты из javascript в C#. И нам нужны методы для создания объектов на стороне C# для javascript:
public IFoo CreateFoo()
{
return new Foo() { Bar = "asdf" };
}
public string Bar(IFoo foo)
{
return foo.Bar;
}
Использование Javascript:
var foo = external.CreateFoo();
alert(foo.Bar);
foo.Bar = "qwer";
alert(external.Bar(foo));
Нам не нужно ничего регистрировать для COM interop и не будет предупреждения ActiveX от IE.
Система типов в jscript слабее, поэтому вы не можете иметь классы с ранним связыванием. Я предлагаю вам сделать ваш класс автоматизируемым и зарегистрировать библиотеку типов вашего проекта для позднего связывания, чтобы его можно было вызвать в jscript через new ActiveXObject.