Great post. I still have a question :
How do you invalidate a token ? How does a user log out ?
@manoj - Firebug is no longer around. Got discontinued... It was a skunkworx side project of FireFox and they eventually stopped supporting it and killed the script. The extended features were integrated into FireFox (long ago), but unfortunately that doesn't help for the scenario here I mention which is IE debugging in the Web Browser control. You can use older versions of Visual Studio (2017 and older) to connect to applications and use script debugging. See post here...
@Rob - yes I've seen this. This is caused by a version mismatch - usually happens if you installed the WebView2 runtime, then uninstall it and some other version (perhaps from a Canary build) is used instead.
This is frustrating - had that issue and then it magically went away when I re-installed the WebView2 runtime explicitly.
Microsoft is working to get the WebView2 runtime installed with Windows updates. Once we have a few rounds of this in I think it'll be pretty safe to pick an older version and just stick with that and according to what they are shooting for that should continue to work (ie. forward compatible). We won't know until we see this in the wild though and it'll probably take a few update cycles before enough machines get these WebView2 runtime updates.
But roughly that is my plan - wait it out until the runtime becomes more integrated and then pick an older version and just stay with that.
Thanks for a great writeup, which saved me a lot of time. Some of our clients installed the pre-release control (Evergreen) and didn't get the upgrade when it went to release, as expected. We saw the standard error and I added the detection code to our app so that they see a nice error panel.
We also had a different error on a dev machine which I think might be do to with the nuget package or the build on that machine:
"Unable to load DLL WebView2Loader.dll. The specified module could not be found."
Anybody else seen that one?
Thanks a lot
Hey, 5KPlayer seems to be good for mirroring iOS device screen on Windows. Additionally, tools like Webex, R-HUB web video conferencing servers, Gomeetnow, Gotomeeting etc. are also widely used for mirroring iOS devices to Windows , MAC etc. and vice versa.
@Witold - you can certainly run Blazor applications with the server. The live reload functionality is limited by Blazor's current state of view recompilation which is very slow and requires a Blazor App reload. I don't see a way around this for the current version.
In .NET 6 the new dotnet watch supposedly will have functioning live reload including hot-swapping assembly code, but we'll see how well this works. The .NET 5 live reload functionality has not worked reliably for me in any way 😦 - hopefully this will work as advertised in 6.
What are the limitations of this with regard to Blazor?
You have written that "The runtimes are backwards compatible so you need a current or newer version of the Runtime relative to the SDK/Controls". Is there any document, preferably from Microsoft, supporting this claim?
This would be of great help as we are moving from CefSharp to WebView2 but the compatibility concerns between the runtime and the SDK are preventing us from using the evergreen bootstrapper.
@Anne - As with anything, trusting the vendor who provides tools is key. I've never heard of InstallSimple but it looks like they have been around for some time. I kind of doubt that they'd plant a trojan on purpose as that would quickly kill their business. I'd suspect something else - like perhaps a component?
My process for dealing with small vendors is to do some due diligence. If a public vendor is doing something nefarious chances are it's been reported and you can find it online.
Also there are more widely used solutions including Inno Setup (which is what I use now), which is open source and actively developed. Very little chance that something out in the open ends up doing something malicious.
Just for info, we had purchased an installer from http://installsimple.com/
and it turned out that it was an unknown trojan. This Trojan later
had damaged 2 of our company computers. It was an unknown trojan at
that time and our AV couldn't detect it, but later ZoneAlarm was able
to detect as it was transmitting some data out to an external command
So we decided that we whipped out our very own installer instead of using a
third party installer such as InstallSimple or Installmate. Our own installer
is now working fine, we learnt how to compressed our files and to retrieve
them from our own installer.
Hence please be aware of installer software such as InstallSimple, we learnt a
great lesson, our company operations were disrupted for 6 months and luckily
none of our customers were affected. Just imagine fighting an unknown malware
which surreptitiously steals and corrupt your data.
@bitbonk - yes you can ship a fixed runtime, but... it's huge. It'll add 70-80mb to your installation package as you are essentially installing a local version of Edge plus the runtime.
I wish they made a package that's just the runtime without the full Edge packaging. I'm OK with requiring users to have the latest Edge installed on their machines, but having a fixed runtime installed is really what's the main problem.
@Tom - I don't know but I assume, yes. WPF on Core is pretty much a straight recompile under core - very few things have been changed so for all intents and purposes things will work identically.
But you have to try it to be 100% sure.
There is also a Fixed Version distribution mode that doesn't require the runtime to be installed. Have you tried that and if so, have you had any success with that?
Do you know if WPF in .NET 5.0 has the same clipboard problems?
Managed Assembly(C#) register as Com Component and it is dependent on another C# dll
then how we can resolve run time reference.
How can you pass credentials to the webview2 control when loading a web page. The idea is to go to the specific page without presenting the login page. Of course we are using valid credentials
Using the following with in the Post method, without any parameters. It works.
Xdocument xDoc = Xdocument(Request.Body);
I think that would be a terrible idea as that would be an invitation for malicious code to execute.
I think that would be a terrible idea as that would be an invitation for malicious code to execute.
With public or unknown/untrusted packages, yes. Its a different story when its a private repo with trusted private packages or where the code is helpful and not malicious.
Very handy tool, thanks a bunch! Slight note, the dotnet command should probably be:
dotnet tool install -g LiveReloadServer
@Sankar - Simplest: Read the raw body stream and stream into an XmlDocument or XLinq structure on an [HttpPost] action that doesn't have explicit parameters.
You can also create a custom filter for XML to parse generically but you'd be replacing the default XML entity parser that ASP.NET provides. Probably not worth it unless you have a lot of requests that share common parse logic.
Thank you very much for the useful information. I wanted to receive a XML file in my POST request then validate the xml for any validations using the XSD and then process the file. What is best way to achieve this? I am testing through postman passing the file in the request body as binary but not working. Any suggestion is greatly accepted.
Really helpful and it saved me a lot of experiments with .NET core! Now I understand also the purpose of the formatters. Thank you very much.
Hi! Thank you so much for this, the only issue is when I use the generic implementation the namespaces appear on the body and not on the Envelope ):
@Jussi - sure that should work. Whatever you do with the DOM happens to the DOM. But there are things that might make it not work:
Thanks, good stuff. Do you know why it is not possible to inject STYLE tags using ExecuteScriptAsync? Tried it via CoreWebView2_DOMContentLoaded and WebView2_NavigationCompleted and neither worked. The below JS works great if I inspect the WebView2 control and execute it in Console.
Popped back here looking for a link to part 3. Any time scales when this will go live?
PS: Well written series with good technical detail, thanks.
Thanks for this article, it helped me a lot. Now my vsix appears for VS 2017 as well as VS 2019. I can also install the vsix, but when i use it in VS, i get a failure message, my TemplateWizard dll cannot be loaded somehow.
It's a custom class that I have in my AspNet utility library in Westwind.AspNetCore Nuget package. Source code here:
Is the JwtHelper class part of a NuGet package or is it custom code?
I installed Microsoft.AspNetCore.Authentication.JwtBearer (which is required for AddJwtBearer), but it doesn't contain the JwtHelper class.
What tripped me up: there's a group policy setting which causes browser-emulation settings in HKCU to be ignored:
HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\Internet Settings\Security_HKLM_only = 1
'This is a Group Policy setting at Computer Configuration/Administrative Templates/Windows Components/Internet Explorer/"Security Zones: Use only machine settings"'
@Nicholas - if I understand JWT Tokens correctly the hash is what makes this work. You can read the data, but you can't change it because you'd need the signing key.
If that wasn't the case, JWT Tokens would be pointless and we might as well pass a JSON string around 😃. The point is good though - you definitely don't want to pass information that can compromise the application in a token as it is readable if the token is captured - either by cookies or bearer tokens.
It might be splitting hairs, but consider a scenario where the token key for the mechanism is compromised.
In this scenario, someone could fabricate any claim/role they want.
If you wanted an added layer of security, would it be preferable to fetch the roles given the user ID?
Even if the signing token is compromised, attackers would still have to find a valid user with the appropriate roles to gain the desired access.
Great and concise article, nicely written!
Yep, I have done the auth Ground Hog Day shuffle.
How would expiration of the token be handled by the calling client and the api controller?
@Osin - It's possible this has changed in recent versions. I had an open issue for this a while back but AFAIK that never was fully addressed. At the time the order of UseAuthentication() and UseAuthorization() was also important.
Ever since I've just made sure not to do it any differently because the behavior was subtly different.
Great write up, Rick -- I went through similar hell recently with azure AD app registrations, scopes, audiences, issuers and application vs delegated permissions. One thing I might point out that will probably drive you nuts is that it's only the UseAuthorization() call that has to appear after UseRouting() and before MapEndpoints(). The UseAuthentication() call can appear before UseRouting() (though grouping authz/authn together makes perfect sense to me from an organizational standpoint!)
Great article as always. Good timing too for my uses 😃
That's a great article. Thanks for sharing that.
Have a question. How we could prevent WebView2 from caching (CSS & js)?
@Scott - if you deleted files, they are deleted and gone and you can't get them restored as you're doing it at the command line - they're not going to the recycle bin.
You can try tools like Recuva which can restore deleted files if they haven't been overwritten otherwise. This doesn't always work though especially if you don't do it immediately.
I tried using this command to get rid of an errant file (it worked) and it ended up deleting (or making everything disappear) on my desktop...I'm getting some things back here and there by using Windows Recovery...I see some things I can't get to at the path \?\C:...any suggestions how to get the folders back that were obliterated by using this command? Gladly will donate if I can solve this problem...
@Daniel - the new instance does have focus, but the problem is the old one does not and that one is the one that should get activated. The new one is discarded because it's a singleton app and only one window - the original one - is used to host documents.
I am already sending signal to the old instance and that all works but the activation requires the code mentioned here.
Assuming the new instance of MM has focus (because it was started from the shell by the user) you should simply be able to have it call AllowSetForegroundWindow with the process id of the singleton instance (or ASFW_ANY to let anybody else set foreground) and then use some kind of signal through your named pipe to tell the singleton to focus itself.
Or am I misunderstanding the situation?
Hello Rick, great work on Let's encrypt ... I use it on my 4 domains with auto-update and it work really well . I think for non-commercial , startup and even for small businesses this is the way to go ... sometime small business owner who want a site dont understand very well that a domain name is not all what is needed, but on top developping the site come hosting fee , now SSL if you want any chances to be showing in a Search Engine .. so to be able to get a low cost/free certificate is obviously welcome ... cheer.
Hello, I tried using this for deleting a problematic file, and it ended up deleting all files on my desktop (and they're not in the recycle bin). Is there any way I can recover them?
Nice trick 😃
@Rob - If you're only running .NET 5.0, just replace all instances of IHostingEnvironment with IWebHostingEnvironment. It's a built-in class.
If you multi-host for mutliple environments (for a component or middleware library most likely) then you may need the code I describe in this post. For Web applications, just replace and move on.
In aspnet Core 5 MVC web app, it too complains that IHostingEnvironment is deprecated, so I just want to use IWebHostingEnvironment in it's place. I try to, but it says CS0051 in inconsistent access error when trying to pass it to a controller contructor.. I didn't write IWebHostingEnvironment... So what's the proper implementation of this interface in a AspNet 5 Core MVC controller to access a file in the hosted environment?
FYI Rick the code snipped showing files and folders syntax has some typos.
Excellent resource dude, thanks.