MicrosoftEdge / WebView2Feedback

Feedback and discussions about Microsoft Edge WebView2
https://aka.ms/webview2
441 stars 53 forks source link

Custom Popup window window.chrome.webview undefined issue #2967

Closed mukeshmishra996 closed 1 year ago

mukeshmishra996 commented 1 year ago

Description

I am creating a custom browser using webview2 dll. During development I am trying to surpress default child window and show customized child popup with the help of CoreWebView2_NewWindowRequested method. But, Now I am facing a challenge. When I am trying to communicate from java script code to C# code using window.chrome.webview.postMessage() method the window.chrome.webview object is undefined. Can any one help me to fix this issue.

Version SDK: 1.0.1370.28 Runtime: 107.0.1418.42 Framework: WPF OS: WIN11

Screenshots

image

Sample code

public class PopupView
{
public PopupView(){
_ = InitializeBrowser();
}

public async Task InitializeBrowser()
        {
            CoreWebView2EnvironmentOptions options = new CoreWebView2EnvironmentOptions()
            {
                AdditionalBrowserArguments = @"enable-media-stream -ignore-urlfetcher-cert-requests -ignore-certificate-errors 
                                            disable-gpu disable-gpu-compositing enable-begin-frame-scheduling",
                AllowSingleSignOnUsingOSPrimaryAccount = true
            };
            CoreWebView2Environment environment = await CoreWebView2Environment.CreateAsync("", userDataFolder: WebConstants.RootCachePath, options);
            await WebView2Child.EnsureCoreWebView2Async(environment);
        }
  }
  public class PopupViewModel 
  {
        public CoreWebView2Deferral Deferral { get; set; }
        public CoreWebView2NewWindowRequestedEventArgs EventArgs { get; set; }

          public async void WebView2_CoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
        {
            try
            {
                if (WebView2Child != null && WebView2Child.CoreWebView2 != null)
                {
                    if (EventArgs != null)
                    {
                        WebView2Child.CoreWebView2.Navigate(EventArgs.Uri);
                        EventArgs.NewWindow = WebView2Child.CoreWebView2;
                        Deferral.Complete();
                    }

                    WebView2Child.CoreWebView2.WebMessageReceived += CoreWebView2_WebMessageReceived;
                }
            }
            catch (Exception ex)
            {
            }
        }
public void CoreWebView2_WebMessageReceived(object sender, CoreWebView2WebMessageReceivedEventArgs e)
        {
            try
            {
                var json = e.TryGetWebMessageAsString();  // always a JSON string
                if (string.IsNullOrEmpty(json))
                    return;

                var message = JObject.Parse(json);
                if (message == null)
                    return;

                var action = message["action"]?.ToString();
                var data = message["data"]?.ToString();
                if (!string.IsNullOrEmpty(action))
                {
                    switch (action)
                    {
                    }
                }
              }
          }

  }
  public class MainClass
  {      
public async void CoreWebView2_NewWindowRequested(object sender, CoreWebView2NewWindowRequestedEventArgs e) {
CoreWebView2 webView2 = (CoreWebView2)sender;
                    PopupViewModel popupViewModel = new PopupViewModel();
                    popupViewModel.EventArgs = e;
                    popupViewModel.Deferral = deferral;
                    e.Handled = true;
                    await _webBrowserViewModel.CurrentTabVM.WindowManager.ShowWindowAsync(popupViewModel);
}
}
victorthoang commented 1 year ago

Hello @mukeshmishra996,

Thanks for your bug report. I've assigned this to a dev that can best try to replicate the issue and follow up on this.

ElyssaJyu commented 1 year ago

Hi @mukeshmishra996, Basically, window.chrome.webview.postMessage is using on the web side andWebView2.CoreWebView2.WebMessageReceived on the WPF side. It seems the sample code you provided is not enough to show how you communicate from java script code to C# code to locate the issue specifically. For the WebView2 control to send and respond to the web message, after CoreWebView2 initialization and event handler registration to respond to WebMessageReceived, the host needs inject a script to the web content. Please consider to use AddScriptToExecuteOnDocumentCreatedAsync

mukeshmishra996 commented 1 year ago

@ElyssaJyu but in my case window.chrome.webview it self is undefined on child window. How we can able to send the message from web side to wpf side. Whatever you mentioned I have followed same thing. but still webview is undefined. Can you please share any sample code which can help me to implement popup window within webview2 solution.

ElyssaJyu commented 1 year ago

I simple create two windows, then call PopupView from MainWindow. image Something like this: private void button1_Click(object sender, RoutedEventArgs e) { new PopupView().Show(); } There is a button on MainWindow, then click, PopupWindow shows up. But I'm not sure what your expected workaround is. Also not sure what _webBrowserViewModel.CurrentTabVM.WindowManager.ShowWindowAsync represents and what deferral refers (popupViewModel.Deferral = deferral;) from your code

mukeshmishra996 commented 1 year ago

@ElyssaJyu Let me create a sample project for you

mukeshmishra996 commented 1 year ago

WebView2.zip @ElyssaJyu Please find above sample code to re-produce this issue. Steps to re-produce above issue: Step 1: Open Outlook(webmail) Step 2: Login Step 3: double click and open a mail from inbox in child window or expand any mail on child window. Step 4: Click on Test Child window button to verify web to wpf communication.

ElyssaJyu commented 1 year ago

@mukeshmishra996, is it what you expected? image The child window loads the web content, and have a message box to verify "message received". But in case, I use netcoreapp3.1, not net6.0. window.chrome.webview on Console in DevTools also works.

mukeshmishra996 commented 1 year ago

@ElyssaJyu - Yes, Then what is the solution with .net framework? Because we are migrating from CefSharp to WebView2 and my all the existing code on .net framework.

ElyssaJyu commented 1 year ago

If you would like to convert .net Core/.net to .net framework, you can change in project "properties" or edit project file (.csproj).

mukeshmishra996 commented 1 year ago

@ElyssaJyu - there is any plan to fix this issue in upcoming release.

ElyssaJyu commented 1 year ago

what is the issue you refer to?

window.chrome.webview object is undefined

Your sample project works without undefined issue. There might be some improper coding you have before.

.net framework or .net/.net Core choice

you can choose which target framework you would like to use when you create a new project. image

mukeshmishra996 commented 1 year ago

@ElyssaJyu - but with sample code also not working. I have already verified. And currently we don't have any plan to migrate from .netframework to .net core. Because this project is existing project and we are using same code base for browser migration.

ElyssaJyu commented 1 year ago

Applications created for .NET Framework use a desktop technology such as WinForms and WPF, which both have been ported to .NET, but these remain Windows-only technologies. Consider the following dependencies:

This document covers some guides to Migrate WPF apps to .NET Core. Hope it will give you some help.

mukeshmishra996 commented 1 year ago

@ElyssaJyu then how same code is working on main window? Main window also developed using .NET framework.

ElyssaJyu commented 1 year ago

Do you mean that you would like to maintain all codes, but only change Project property to migrate .NET Framework to .NET Core? image Under project solution, the dependencies net472(.NetFramework 4.7.2) and netcoreapp3.1 have separate assemblies. On my understanding, you might change the code if not available in .NET but working on main window in .NET Framework I thought migrating a WPF app from .NET Framework to .NET Core means a migration of the whole project (includes main window and popup window). You need to modify project files which have different format between .NET and .NET Framework uses (code change possibly).

ElyssaJyu commented 1 year ago

@mukeshmishra996 Any update for your issue? I can help if there are remaining issues.

mukeshmishra996 commented 1 year ago

@ElyssaJyu - We have customized the code to achieve our requirement. But still webiew2 object is undefined issue not fixed.

ElyssaJyu commented 1 year ago

what's your current workaround? Could you describe some details for your modification compared to your previous sample?

ElyssaJyu commented 1 year ago

I'm closing this issue. If this issue still blocks you, please reopen the issue and update the description. Thanks.