0

What I'm looking for:
I'm looking for a way to show a local located webpage containing CSS and JS in a WPF application. But the tricky part, it should also be possible to CATCH AND PROCESS outgoing requests.
So I need to catch GetRequest, process them myself, and return the answer myself.

https://1drv.ms/u/s!ArLDiUd-U5dtg01y_jvotFDEZNKE

Why:
I have a pretty extensive UI for a server based application. (HTML/CSS/JS) So I have the choice between completely remake the whole UI in WPF or I need to find a way to use this HTML based UI in a WPF application. While showing the UI works fine with most components I found so far, catching request and then providing my own answer as JSON on the other hand seems to be a tricky thing.

The two I tried so far:

  • WebView control for Windows Forms and WPF WebView Windows Community Toolkit
    but this doesn't support catching outgoing request as far as I have seen.
  • CefSharp (Chromium): Does support catching and redirecting, but I can't answer the request my self it seems? CefSharp

Does any of you know of any component/framework that could do that?

EDIT
CefSharp project: https://1drv.ms/u/s!ArLDiUd-U5dtg06kzBSMOqDZLWxJ?e=Mdkchd

Hans Vader
  • 183
  • 10
  • 1
    Have you tried to use some library to be a webproxy? Like [TitaniumWebProxy](https://github.com/justcoding121/Titanium-Web-Proxy) to "monitor" specific Url/path and do wherever you want like reply a redirect to any local address or event apply another Respose. – Mateus Avelar Nov 28 '19 at 10:04
  • 1
    In CefSharp you can intercept a request and provide your own response, http://cefsharp.github.io/api/75.1.x/html/M_CefSharp_IResourceRequestHandler_GetResourceHandler.htm See https://stackoverflow.com/a/31367169/4583726 for an example ResourceRequestHandler implementation. See also http://cefsharp.github.io/api/75.1.x/html/T_CefSharp_ResourceHandler.htm I'd need to know more details before I could say anything specific about your use case. – amaitland Nov 28 '19 at 10:27
  • @amaitland I tried to do it with cefsharp. I got it to redirect a request and even to change a response to some degree. But how do I fake a response when the get request goes to an address that doesn't exist? The application has to work offline. I uploaded a C# project with the CefSharp Code I got in case you want to take a look. – Hans Vader Nov 29 '19 at 08:34
  • @aimaitland I maybe need to add: The reason for that, the application gets some data for populating UI elements through a get request. But since it has to be offline, I need to catch the request and just answer with my own JSON. – Hans Vader Nov 29 '19 at 08:37
  • 1
    Website doesn't need to exist, sounds like a scheme handler might be the go for you. https://github.com/cefsharp/CefSharp/wiki/General-Usage#scheme-handler – amaitland Nov 29 '19 at 09:33
  • @amaitland thanks, I'll give it a try and report back as soon as I know more – Hans Vader Nov 29 '19 at 09:59

1 Answers1

0

As promised the solution I got at the end:

The javascript calls a webpage that doesn't exist. The Request & Resource Handler catch this call and return their own anwser. When you implement your own Request/Resource handler, you have to replace the NotImplementedException in some cases even if you don't need the functionality. Just visit the offical documentation for the default behaviour in this case: http://cefsharp.github.io/api/75.1.x/html/T_CefSharp_IRequestHandler.htm

XAML:

<Window x:Class="Chromium.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        ...
        xmlns:cefSharp="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <cefSharp:ChromiumWebBrowser
            x:Name="ChromiumWebBrowser"
            />    
    </Grid>
</Window>

MainWindow.Xaml.cs

public MainWindow()
{
    InitializeComponent();

    ChromiumWebBrowser.BrowserSettings.WebSecurity = CefState.Disabled;
    ChromiumWebBrowser.RequestHandler = new RequestHandler();
    ChromiumWebBrowser.Address = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "TestHtml", "index.html");
}

index.html

<!doctype html>
<html>
<head>
    <link href="css/style.css" rel="stylesheet" type="text/css">
    <script src="js/script.js" type="text/javascript"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
    <h1>Title</h1>
    <p id="result"></p>
    <button onclick="call()">Call</button>
</body>

JS Script

function call() {
    axios.get('http://doesnt_exist')
        .then((response) => {
            console.log(response);
            document.getElementById("result").innerHTML = JSON.stringify(response.data);
        });
}

Request Handler

public class RequestHandler : IRequestHandler
{
    public IResourceRequestHandler GetResourceRequestHandler(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request, bool isNavigation, bool isDownload, string requestInitiator, ref bool disableDefaultHandling)
    {
        Console.WriteLine("GetResourceRequestHandler " + request.Url);
        return new ResourceRequestHandler();
    }
...
}

ResourceRequestHandler

class ResourceRequestHandler : IResourceRequestHandler
{
    public IResourceHandler GetResourceHandler(IWebBrowser chromiumWebBrowser, IBrowser browser, IFrame frame, IRequest request)
    {
        Console.WriteLine("GetResourceHandler " + request.Url);
        if (request.Url.Contains("doesnt_exist"))
            return ResourceHandler.FromString("Hello");
        return null;
    }
...
}
Hans Vader
  • 183
  • 10
  • If you don't need to implement every interface method then there are default implementations for IRequestHandler and IResourceRequestHandler, https://stackoverflow.com/questions/31250797/chromium-send-custom-header-info-on-initial-page-load-c-sharp/31367169#31367169 has an example. – amaitland Dec 11 '19 at 10:46
  • If you wish to serve local files from disk then there is http://cefsharp.github.io/api/75.1.x/html/T_CefSharp_SchemeHandler_FolderSchemeHandlerFactory.htm See https://github.com/cefsharp/CefSharp/wiki/General-Usage#scheme-handler for details on that option – amaitland Dec 11 '19 at 10:51