3

I am making a WPF application use WebView2.

There will be an installer that will installer the WPF application in a folder and will also download and write the website into a subfolder of the installation directory. Such as this:

Installation Directory
├───Website
│   ├───index.css
│   └───index.html
└───WPF Self Contained EXE

The WebView2 will load the website using this (I think): webView.CoreWebView2.Navigate(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Website");

This should load index.html and all the files it references such as index.css.

Now my main concern is that how do I call a JavaScript function from C#. So far after googling I have only found ways for WebView1. And I couldn't find anything about calling a C# method from JavaScript.

So three things:

  1. Is this webView.CoreWebView2.Navigate(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Website"); correct for loading a website from a local folder?
  2. How would I call a JavaScript function and pass an C# object to it from a C# method.
  3. How would I call a C# function from the JavaScript script?

Is this even possible?

Thanks.

3

1 Answer 1

6

Using file URI

I'm not sure if AppDomain.CurrentDomain.BaseDirectory will always get you the correct path. You can use something like the following:

string exePath = System.Reflection.Assembly.GetExecutingAssembly().Location;
string exeFolder = System.IO.Path.GetDirectoryName(exePath);
string websiteFolder = Path.Combine(exeFolder, "website");
string htmlPath = Path.Combine(websiteFolder, "index.html");

webView.CoreWebView2.Navigate(htmlPath);

You must include the path to the index.html itself and not just the folder containing the index.html.

Normally Navigate should take a URI, but if you provide a Windows file path instead it will convert it to a file URI for you and should work.

File URIs have some limitations when trying to incorporate http(s) URIs and other web platform features that require https.

Using a virtual HTTPS URI

If you hit issues using file URIs you can use CoreWebView2.SetVirtualHostNameToFolderMapping to map a Windows file path to a fake HTTPS hostname:

string exePath = System.Reflection.Assembly.GetExecutingAssembly().Location;
string exeFolder = System.IO.Path.GetDirectoryName(exePath);
string websiteFolder = Path.Combine(exeFolder, "website");

webView.CoreWebView2.SetVirtualHostNameToFolderMapping("appassets.example", websiteFolder, CoreWebView2HostResourceAccessKind.DenyCors);
webView.CoreWebView2.Navigate("https://appassets.example/index.html");

This will make a fake hostname 'appassets.example' that will map to your Windows file path. And since its HTTPS URIs you don't hit the same issues as you do with file URIs.

Host objects in script

For your questions 2 & 3 you can use CoreWebView2.AddHostObjectToScript. The current implementation of AddHostObjectToScript requires your C# classes to be specially marked. You can see it in the AddHostObjectToScript documentation.

Sign up to request clarification or add additional context in comments.

6 Comments

Hi. The local website works! Thanks! When I call a c# method inside a class that returns a List<MyOwnClassName>, I get null. This is my js code: const transaction = chrome.webview.hostObjects.transaction; transaction.GetReceiptItems(10).then(TResult1 => {this.amount = TResult1.Count;});
This logs an error to the console: Uncaught (in promise) TypeError: Cannot read property 'Count' of null Note I am using react.js.
Is the type of the result of GetReceiptItems also marked with the appropriate attributes [ClassInterface(ClassInterfaceType.AutoDual)] and [ComVisible(true)]?
The JavaScript code on the MS website is incorrect. const transaction = chrome.webview.hostObjects.transaction; needs to have await. It should be const transaction = await chrome.webview.hostObjects.transaction;
Ok. Thanks! Let me try the new code. The result is a List<T>... Do you mean the <T> class?
|

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.