I want to pass Javascipt object to c# method without serialization in Mono or Blazor

Viewed 615

I want to pass the javascript object directly to c# method in Blazor. if i call the GetModel method it is returning the same object which i passed but not the updated object. I have followed the below process.

JavaScript Object 

export interface ITestItem {
  data: string;
  moreData: string;
}

C# Object 

public class ITestItem
{
  public string data { get; set; }
  public string moreData { get; set; }
}

Method in C#:

public static ITestItem GetModel(ITestItem item)
{
  item.moreData = "Get Model Working Fine";
  return item;
}

Calling C# method from JavaScript

public getModel() {
 const getModelFunc = Module.mono_bind_static_method(" 
 [Report]Epicor.MetaFx.Wasm.Dynamic.RunClass:GetModel");
  const item: ITestItem = { data: 'Test', moreData: 'checking Get Model' };
  const output = getModelFunc(item);
  console.log(output);
 }
1 Answers

Looks like this is a TypeScript project in Blazor.

I try the solution with ASP.NET Core 3.1 and it works.

Assume your project (Assembly) name is CICalc

1. Add the exampleJsInterop.ts file in wwwroot folder

namespace JSInteropWithTypeScript {

    export interface ITestItem {
        data: string;
        moreData: string;
    }
      
    class ExampleJsFunctions {
        public getModel(): void {
            const item: ITestItem = { data: 'Test', moreData: 'checking Get Model' };
            (window as any).DotNet.invokeMethodAsync('CICalc', 'GetModel', item)
            .then(data => {
                console.log(data);
            });
        }
    }

    export function Load(): void {
        window['exampleJsFunctions'] = new ExampleJsFunctions();
    }
}

JSInteropWithTypeScript.Load();

2. Add build Microsoft.TypeScript.MSBuild package reference and compile condition in .csproj

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>netstandard2.1</TargetFramework>
    <RazorLangVersion>3.0</RazorLangVersion>
    <TypeScriptToolsVersion>3.2</TypeScriptToolsVersion>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="3.2.1" />
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Build" Version="3.2.1" PrivateAssets="all" />
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="3.2.1" PrivateAssets="all" />
    <PackageReference Include="Microsoft.TypeScript.MSBuild" Version="3.9.7">
      <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
      <PrivateAssets>all</PrivateAssets>
    </PackageReference>
    <PackageReference Include="System.Net.Http.Json" Version="3.2.0" />
  </ItemGroup>
  <ItemGroup>
    <TypeScriptCompile Include="wwwroot/exampleJsInterop.ts" />
  </ItemGroup>

</Project>

3. Import the exampleJsInterop.js in index.html. It's important that it's .js not .ts because dotnet will compile ts to js.

    <script src="exampleJsInterop.js"></script>

4. In your page, add the button to trigger getModel function and add a static GetModel C# function

<button type="button" class="btn btn-primary"
        onclick="exampleJsFunctions.getModel()">
    Trigger .NET static method
</button>

@code {
    [JSInvokable]
    public static Task<ITestItem> GetModel(ITestItem item)
    {
        item.moreData = "Get Model Working Fine";
        return Task.FromResult(item);
    }

    public class ITestItem
    {
        public string data { get; set; }
        public string moreData { get; set; }
    }
}

5. Finally, js get the result from C# when you click the button.

Reference:Getting Started with TypeScript for JSInterop in Blazor

Related