https://github.com/yoshiki-okawa/blazorjsproxy
Dynamic proxy of Microsoft.JSInterop.IJSRuntime which makes defining and invoking JS object much easier
https://github.com/yoshiki-okawa/blazorjsproxy
blazor blazor-wasm blazor-webassembly dispatchproxy jsinterop jsruntime net50 proxy
Last synced: 6 months ago
JSON representation
Dynamic proxy of Microsoft.JSInterop.IJSRuntime which makes defining and invoking JS object much easier
- Host: GitHub
- URL: https://github.com/yoshiki-okawa/blazorjsproxy
- Owner: yoshiki-okawa
- License: mit
- Created: 2021-08-22T03:51:15.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2022-07-11T10:34:51.000Z (over 3 years ago)
- Last Synced: 2025-10-14T22:25:33.432Z (6 months ago)
- Topics: blazor, blazor-wasm, blazor-webassembly, dispatchproxy, jsinterop, jsruntime, net50, proxy
- Language: C#
- Homepage:
- Size: 241 KB
- Stars: 2
- Watchers: 1
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# BlazorJSProxy
Dynamic proxy of Microsoft.JSInterop.IJSRuntime which makes defining and invoking JS object much easier.\
All you need is to define interface for JavaScript class with matching properties and methods.\
[](https://www.nuget.org/packages/BlazorJSProxy/)\
\
See the actual working examples in Class1.cs in ClassLibrary1 project.\
**Example 1 - Existing window variable**
```c#
[JSTarget(ConstructorFunction = "MouseEvent")]
public interface IMouseEvent : IAsyncDisposable
{
ValueTask OffsetX { get; set; }
ValueTask OffsetY { get; set; }
}
[JSTarget(GlobalVariable = "window.location")]
public interface ILocation : IAsyncDisposable
{
ValueTask Href { get; set; }
}
// Use JSTarget with GlobalVariable as window is a global variable in JS.
[JSTarget(GlobalVariable = "window")]
public interface IWindow : IAsyncDisposable
{
ValueTask Location { get; set; }
// Use JSName to use custom propery name instead.
[JSName("onclick")]
Func OnClick { get; set; }
// Use JSName to use custom propery name instead.
[JSName("ondblclick")]
Action OnDoubleClick { set; }
}
private async Task TestWindow()
{
// Create a JS proxy of window.
await using var window = await BlazorJSProxy.CreateAsync(jsRuntime, null);
// Get current URL.
var location = await window.Location;
Console.WriteLine(await location.Href); // https://localhost:5001/counter
// Register a callback function to onclick with Func.
window.OnClick = async evt =>
{
Console.WriteLine("Clicked:" + await evt.OffsetX + "," + await evt.OffsetY); //Clicked:99,18
await Task.CompletedTask;
};
// Register a callback function to ondblclick with Action.
window.OnDoubleClick = async evt =>
{
Console.WriteLine("Double clicked:" + await evt.OffsetX + "," + await evt.OffsetY); //Double clicked:99,18
};
// window object is disposed automatically with await using from both .NET and JS.
}
```
**Example 2 - Custom classes**
```c#
// Use JSTarget with ConstructorFunction as Parent is a custom class defined.
[JSTarget(ConstructorFunction = "Parent")]
public interface IParent : IAsyncDisposable
{
ValueTask Name { get; set; }
ValueTask GetChild();
// IArray is a simple Array JS proxy so that no parsing from JS and .NET vice versa are required until absolutely needed.
ValueTask> GetChildren();
ValueTask Child { get; set; }
// IArray is a simple Array JS proxy so that no parsing from JS and .NET vice versa are required until absolutely needed.
ValueTask> Children { get; set; }
}
[JSTarget(ConstructorFunction = "Child")]
public interface IChild : IAsyncDisposable
{
ValueTask Name { get; set; }
}
private async Task TestCustomParentChildClasses()
{
await DefineCustomParentChildClasses();
await TestProxyReturnType(x => x.GetChild(), x => x.GetChildren());
await TestProxyReturnType(x => x.Child, x => x.Children);
}
private async Task DefineCustomParentChildClasses()
{
await jsRuntime.InvokeVoidAsync("eval", @"
window.Parent = class Parent {
name = 'Parent';
child = this.getChild();
children = this.getChildren();
getChild() {
return new Child('Child1');
}
getChildren() {
return [new Child('Child1'), new Child('Child2')];
}
};
window.Child = class Child {
constructor(name)
{
this.name = name;
}
};");
}
private async Task TestProxyReturnType(Func> getChild, Func>> getChildren)
{
// Create a JS proxy of Parent. Every time this is called, new instance of Parent is created in JS.
await using var parent = await BlazorJSProxy.CreateAsync(jsRuntime, null);
// Get the parent name.
Console.WriteLine(await parent.Name); // Parent
// Get a child.
await using var child1 = await getChild(parent);
// Get the child name.
Console.WriteLine(await child1.Name); // Child1
// Set the child name to Child3
child1.Name = new ValueTask("Child3");
// Get the child's Name again.
Console.WriteLine(await child1.Name); // Child3
// Get children.
await using var children = await getChildren(parent);
// Get a number of children.
Console.WriteLine(await children.Length); // 2
// Get the first child name.
Console.WriteLine(await (await children[0]).Name); // Child1
// Get the second child name.
Console.WriteLine(await (await children[1]).Name); // Child2
// Set the first child name to Child4
(await children[0]).Name = new ValueTask("Child4");
// Get the first child name again.
Console.WriteLine(await (await children[0]).Name); // Child4
// Set the first child = the second child.
children[0] = new ValueTask(await children[1]);
// Get the first child name again.
Console.WriteLine(await (await children[0]).Name); // Child2
// Get the second child name again.
Console.WriteLine(await (await children[1]).Name); // Child2
}
```