Recent Comments



dr vlad
November 21, 2023

re: WPF Window Closing Errors

Thanks; this error is giving me a neck pain since yesterday - just trying to close a child window from its parent control and override the default close with the "x" button.


Michael
November 18, 2023

re: Role based JWT Tokens in ASP.NET Core APIs

Thank you for this article. I have been reading a lot of pages regarding this topic. But this is the best so far, the actualy made my understand every part of the flow. Good work.


Daniel
November 16, 2023

mark
November 15, 2023

re: Updating Assembly Redirects with NuGet

Running this gave me this error:

Add-BindingRedirect : Loading this assembly would produce a different grant set from other instances. (Exception from HRESULT: 0x80131401) At line:1 char:20

Get-Project -all | Add-BindingRedirect
CategoryInfo : NotSpecified: (:) [Add-BindingRedirect], FileLoadException
FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.AddBindingRedirectCommand

To solve this:

I was facing the same issue when attempting to run this command, but managed to run it by creating the DWORD variable LoaderOptimization with 1 for value under the key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework, then restarting Visual Studio and running the command in the Package Manager Console again.

source: https://stackoverflow.com/questions/76049195/add-bindingredirect-loading-this-assembly-would-produce-a-different-grant-set

viswa
November 04, 2023

re: Fix that damn Git Unsafe Repository

Hi All,

I have already added following safe with * but still I'm not able to clone the repo using groovy script, error remains same

[safe]
        directory = *
stdout: 
stderr: fatal: not in a git directory

Dalibor Čarapić
October 31, 2023

re: Caching your WebView Environment to manage multiple WebView2 Controls

I hate these kinds of errors. WebView2 is probably spinning its own threads and one of them probably fails. Hopefully your solution solves the problem.
You probably tried everything but I have a few recommendation that might help:

  1. Check if the users where the application is failing are having different culture/regional settings (this used to cause issues with Word/Excel COM automation ... it might be the same there)
  2. Use procmon from systernals and capture which files/registry entries the application is 'touching'. If you get one of your customers which reported the issue to run the tool as well it might provide more insight.

Donald Adams
October 31, 2023

re: Caching your WebView Environment to manage multiple WebView2 Controls

This is a big problem for me when I either have multiple controls or the user opens up a second instance of the app. When the error occurs, my app disappears without warning. I agree with all that you wrote above.


Rick Strahl
October 31, 2023

re: Locked Files When Publishing .NET Core Apps to IIS with WebDeploy

@Martin - the issue is that the app is not reliably unloading or not unloading quickly enough perhaps. Yes it should work with just appoffline.html, but the reality is that it doesn't and so files are locked in the folder and can't be updated. Shadow copy works around that by putting things in a new folder and also managing the staggered execution letting the existing IIS AppDomain run out requests that might still be running, while getting the new AppDomain with the updated files to start up.


Martin Kirk
October 31, 2023

re: Locked Files When Publishing .NET Core Apps to IIS with WebDeploy

I wonder why this doesn't work with Filesystem deploy... it should be faily simple mechanic to add the app_offline and then proceed to copy files after waiting for x milliseconds.


Enrico
October 21, 2023

re: Fix that damn Git Unsafe Repository

How can I find the .gitconfig file in a linux distro? I am using openSUSE for a work from an undergraduate course and git config --global --add safe.directory <Git folder> just doesn't work...

thank you!


Øystein Amundsen
October 16, 2023

re: Preventing iOS Textbox Auto Zooming and ViewPort Sizing

Just putting this here: https://gist.github.com/OysteinAmundsen/9e6b2ebdf8264ec0e25a0540661949bc

It is made for angular, but the point is:

  1. Select input element
  2. On pointerover and focus, add maximum-scale=1 to the viewport meta tag.
  3. On pointerout (if input element is not focussed) and blur, remove the maximum-scale=1 from the viewport meta tag.

This works if you do not want to or cannot change font-size, and do not want to or should not prevent users from zooming in the application. Zoom is only disabled when input field is in focus.


Rick Strahl
October 04, 2023

re: Rolling Forward to Major Versions in .NET

Hmmm... I think the sdk key is used for picking the SDK version used for executing dotnet CLI commands, not for the runtime used to execute the application.

Should be easy to test - allowPreRelease plus rollforward should also allow using the preview release. I think I tried that at the time. I'll take another look when I get back to my machine.


Muhammad Rehan Saeed
October 03, 2023

re: Rolling Forward to Major Versions in .NET

You can set allowPrerelease in global.json like so:

{
  "sdk": {
    "allowPrerelease": false,
    "rollForward": "latestMajor",
    "version": "7.0.401"
  }
}

I personally also use the above settings and have found them to provide less friction.


MV10
September 15, 2023

re: Async and Async Void Event Handling in WPF

@Sam (does @ work here?) calls to await Task.Delay(0) will generally be more responsive. You pay the overhead of creating a system timer, but Task.Yield indefinitely surrenders control to the scheduler. I was recently benchmarking a background-thread audio-capture loop in a program rendering OpenGL frames on the main thread, and Delay reliably returned about 10% faster than Yield (3600 FPS vs 3250 FPS). Non-Task options were even better, but obviously have no applicability here.

As for ConfigureAwait most of what you read about .NET (Core) is really about ASP.NET, because Microsoft has gone almost completely web-blind. ASP.NET Core doesn't need it, but whether it is required elsewhere is still a question of the framework you're using.


Martin Kirk
September 10, 2023

re: Map Physical Paths with an HttpContext.MapPath() Extension Method in ASP.NET

Have you checked out the new alternative ?

Directory.GetCurrentDirectory()


Jeff
August 22, 2023

re: WPF Rendering DUCE.Channel Crashes due to Image Loading

.NET Framework has built-in PNG compression, but (for speed) uses the video driver for PNG decompression.

PNG compression (whether done by .NET or other libraries) correctly uses unsigned bytes for some of the measurements.

Some video drivers incorrectly parse the value as a signed byte, which causes out-of-memory errors.

Example:

  • PNG compression adds a byte-run of 130 bytes, storing the 0x82 as an unsigned byte.
  • PNG decompression misreads the 0x82 as the signed byte value -126.
  • PNG decompression attempts to allocate -126 bytes of memory to store the byte-run.
  • The value -126 is first sign-extended to a 32-bit value: 0xFFFFFF82.
  • Finally the memory manager attempts to allocate unsigned 0xFFFFFF82 (4,294,967,170) bytes of memory.

Eduardo
August 17, 2023

re: HTML Table Cell Overflow Handling

Here's how I dead with unexpected long text. I cap the height, but let the user override and see all the text. Warning: Little JS to make it work.

https://codepen.io/edddy/pen/GRPRJmE

In my app it's styled better, but you'll get the idea


Rick Strahl
August 08, 2023

re: Fighting WebView2 Visibility on Initialization

@Mikhail - You don't really need a callback, you can implement it yourself once you've made it past the EnsureCore2WebViewAsync() call. You can set an initialization flag and fire an event/action to allow notification.

In fact, I created a wrapper component called WebViewHandler that deals with this in a Westwind.WebView component. It wraps a lot of this non-sense with some additional flags and events. That can help, but ultimately you still have to wait for the control to be ready.


Tim Sinnott
August 07, 2023

re: Thoughts on Async/Await Conversion in a Desktop App

We software developers are herd animals.

The mad rush to "Async Everywhere" reminds me of the Y2K problem. Y2K arose from the faulty notion taught for years that responsible programmers should cleverly use just 2 digits to represent a year instead of 4, thereby saving 2 precious bytes. The herd failed to comprehend that in the future (today), bytes would abundant and free.

Today, the herd is saying "Async Everywhere" to make everything more responsive. But processing power is becoming cheaper and faster anyway. The motto should be "Async Where It's Needed".

The decision by the WebView2 creators to go "Async Everywhere" was shortsighted. The cost in unnecessary complexity far outweighs any benefits.

Rich Strahl you said it well: I can't help but think that a lot of this pain could have been avoided if the developers of the WebView2 would have just provided the ability to call into the DOM synchronously. There's nothing inherently async about DOM access. There's no IO you're waiting on and DOM interactions calling into code tend to be universally fast. What's slow is not the DOM code calls, but DOM UI updates, which happen in the background, separately anyway. In short, there's no realistic reason that DOM access should have to be async.


Rick Strahl
August 02, 2023

re: Debouncing and Throttling Dispatcher Events

You need to add <UseWpf>true</UseWpf> and target net70-windows I believe since these are features out of the WPF namespaces.


Rick Wolff
August 02, 2023

re: Debouncing and Throttling Dispatcher Events

Hey, Rick. It's Rick here too. 😃

Thanks for the code, I've been using it for a while. But now I'm writing a .NET 7 project and System.Windows.Threading is not available. Do you know if someone wrote a version of this to .NET (Core)?

Thank you!


Evan
July 28, 2023

re: ASP.NET Core MVC Views not Resolving Partial Views outside of the default ControllerContext

This post helped me, thanks. I have a partial view that resolves fine in one place in my controller. The action name does not match the view name. It works just fine, it resolves the partial view. However, a few lines down in another action method, it is unable to resolve the exact same view. I can't figure out any difference. However in the 2nd case I resorted to using the FULL path, plus the extension, and the view is resolved. Very odd.

Thanks! Evan


Joshua H
July 25, 2023

re: No more Meta Refresh Tags

@Rick 17 yrs later this page was still helpfull.


Houdini Sutherland
July 20, 2023

re: Ambiguous References in DefaultWsdlHelpGenerator.aspx

Listen, as old as this article wants to be, it has been a huge help in sorting out some modern issues. Thanks, Rick - super post. Although for some reason the remove namespace wouldn't solve the issue. I had take a different approach - don't add the namespace to the general web.config file but instead add it to the web.config file for the local folder where the modules that needed it lived.


George Helmke
July 17, 2023

re: Keeping Content Out of the Publish Folder for WebDeploy

Thanks much. This is the only thing I have found that consistently works.


Jim
July 14, 2023

re: Combining Bearer Token and Cookie Authentication in ASP.NET

Thank you very much for this article. I am working on an IdentityServer solution where the IS will call an endpoint in my MVC application to ensure the client. So, I had to combine OpenId/Cookie and Bearer. Your solution helped me out. I had to set the DefaultChallengeScheme to OpenId.

builder.Services.AddAuthentication(
        options =>
        {
            options.DefaultScheme = customAuthenticationSchemeName;
            options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
        })
    .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme)
    .AddOpenIdConnect(OpenIdConnectDefaults.AuthenticationScheme,

Ryan Obray
July 10, 2023

re: Content Injection with Response Rewriting in ASP.NET Core 3.x

This article was SO helpful. Thank you so much for putting this together. I used a slight variation of your method to inject global JavaScript variables into static pages that are uploaded to a file share by content creators which are then served up through my app via a NAS mount. The content creators just have to add my marker comment where they want my script block injected and then I provide token data that their accompanying JavaScript leverages to authenticate to REST APIs. The session data is captured via another middleware that enforces OAuth OIDC code flow authentication when requesting static "index.html" files. It's actually a really beautiful combination, but not quite as complex as your need.

I always seem find great gems of yours when I'm trying to solve my most difficult coding problems so thank you again.


Franz Seidl
June 21, 2023

re: Thoughts on Async/Await Conversion in a Desktop App

Have you ever tried using the Await() extensions provided by Prism.Core throught Brian Lagunas some time ago. Seems a good solution for me, to run async code inside of synchronous code, but with the little disadvantage that you have a callback chain if you want to run multiple calls after each other.


Rick Strahl
June 17, 2023

re: Using Application Insights in .NET Desktop Applications

@Jason - This is a desktop app, so it's not using global DI and I don't see a need to set that up.

I wanted to be able to log both to Application Insights but also keep a local log for users to be able to share their logs if they report issues - otherwise it's really difficult to correlate.


Jason Wilson
June 17, 2023

re: Using Application Insights in .NET Desktop Applications

Rick - thank you for your blog -- I always find it well thought out and informative.

I'm curious why you chose to use a telemetry client rather than Application Insights provider for ILogger?

I ask because we have .Net 6 application that runs as Windows Service on roughly 1000 clients and growing and we log to Application Insight using the ILogging provider. Recently we noticed that some clients stop logging mysteriously even though the Event Log provider continues to function. Researching this issue led me to your blog post.

Any thoughts about the issue are greatly appreciated.

Jason


dan
June 05, 2023

re: Preventing iOS Textbox Auto Zooming and ViewPort Sizing

not sure if it's an update but the maximum scale trick doesn't work on iphone. The only thing that works is setting the font-size to anything greater than 16px (16px doesn't work either it has to be greater).


nick
June 02, 2023

re: Fix that damn Git Unsafe Repository

Interestingly, when I initialise a local git repo using vscode built-in tooling, and then try and use gitextensions to view or check-in I get the same problem. It's down to a number of files in the .git folder having some strange owner that's not even an accessible user on my local machine (windows 11 pro, no domain, local account only). Fix is the same, and I prefer to own my files - allthough executables, hooks and anything else I didn't create myself get deleted!


John Klug
May 31, 2023

re: Fix that damn Git Unsafe Repository

This problem seems to appear on some machines and not others for unknown reasons. We do all our builds with Linux, but it seems to fail more often when using WSL2 (windows subsystem for Linux).

We have this code (Yocto/Openembedded): def define_iv(d): import subprocess source_dir = d.getVar('OEROOT',True) cmd = "git describe" proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True, cwd=source_dir) out, err = proc.communicate() return out.decode("utf-8").rstrip()

And it sometimes will return "" instead of the hash if we don't do the "git config --global --add safe.directory ...".

"git describe" for a git repository source will be done many many times during a build. But it will only fail once in a blue moon, which makes me think that git must have bugs.


Jovica
May 30, 2023

re: Combining Bearer Token and Cookie Authentication in ASP.NET

Started working for me only after I've added the DefaultAuthenticateScheme

.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = "JWT_OR_COOKIE";
        options.DefaultScheme = "JWT_OR_COOKIE";
        options.DefaultChallengeScheme = "JWT_OR_COOKIE";
    })

Rick Strahl
May 23, 2023

re: Implementing Two-Factor Auth using an Authenticator App in ASP.NET

@Dieter - doesn't that kind of defeat the purpose of a short lived  'one time code'?


Dieter
May 23, 2023

re: Implementing Two-Factor Auth using an Authenticator App in ASP.NET

Is it possible to also generate some backup codes? A lot of sites also offer this feature if the user is unable to use the Auth app right now.


Alex
May 22, 2023

re: Locked Files When Publishing .NET Core Apps to IIS with WebDeploy

hi, sometimes I even find this problem after creating the app_offline.html file at the root of the web app, is there a way to programmatically know that the app has been unloaded from the app domain?

I am currently doing a Thread.Sleep for about 20 seconds to make sure the app is unloaded, but this seems like a bad hack!

thanks!


Rick Strahl
May 19, 2023

re: Implementing Two-Factor Auth using an Authenticator App in ASP.NET

@James - Also in regards of Passkeys I don't like the idea of centralizing everything in the hands of big tech companies. Keys go through Apple, Google, Microsoft and it looks like there's no easy way to interop. If you're using Windows I don't think you can use the Apple tech because there's no way to validate Apple biometrics on Windows.

Spent a bit of time this morning looking around about how this works and it looks the technologies are all open (Fido2 and WebAuthn) but there are few examples that actually go into implementation detail or even on how the auth flow is supposed to work. I suspect the process is very similar to what's use with Authenticators at the end of the day.

But that day is a ways away I'd say. I have not run into any site that uses passkeys yet. And if I do I likely wouldn't think of using because I'd have no idea what it is or how it works - it'll take time even once it becomes regular thing.


Rick Strahl
May 19, 2023

re: Implementing Two-Factor Auth using an Authenticator App in ASP.NET

@David - Yeah, I know what you mean. I actually thought that it was yet another technology that required some sort of service to provide and validate the validation keys until recently. I ran into a side discussion of how the tech works though to realize that that's not the case - you only need to use a provider for storing the passkeys so they can be shared across devices. In theory you don't even need those as keys can be generated by algorithm - as long as you can keep the key present.

@James - and that leads right into your point, which is that Passkeys are very similar in the way they work to the way Authenticators work. I think they actually use the same protocols. The difference is that instead of using a service to host your public keys your device becomes the key store. I suspect you're right in the future that will be the better choice but right now that tech is not widely supported, and it ties the keys to the provider (ie. right now Apple, Google, Microsoft).

Functionally though the technology is similar - both use single use passkeys that are only good for short time intervals.


Csandi
May 19, 2023

re: Using the ng-BootStrap TypeAhead Control with Dynamic Data

Thank you, awesome guide, just save my life 19/05/2023 Maybe not my life but my mental health 😉


James Westgate
May 18, 2023

re: Implementing Two-Factor Auth using an Authenticator App in ASP.NET

I do and have for many years appreciate Ricks amazing contributions to the .net community and have often been a beneficiary of his advice.

I would however recommend skipping implementation of authenticators now and moving straight on to passkeys for anyone reading this.

There is an also somewhat technical implementation issue in Brandon’s code which although shouldn’t present a security risk to the average user does lower the entropy of the random number used to create the shared secret.


David
May 18, 2023

re: Implementing Two-Factor Auth using an Authenticator App in ASP.NET

This is one of my favorite reasons to read your blog: super-thorough research! I really never understood how 2FA could be implemented with an Authenticator app by a "regular developer", but now I'm really hoping to get a project where I can try this out.


JC
May 18, 2023

re: HSTS: Fix automatic re-routing of http:// to https:// on localhost in Web Browsers

Thanks for this guide. It helped me resolve the exact same issue in my development environment.


Jim R.
May 10, 2023

re: Windows Authentication with HttpClient

This really helped me. In my situation, I was trying to call a URL on the same server as the calling (the httpClient) code. At first, authentication failed -- actually, it was never attempted. IIS logs showed that the credentials were never passed at all, and I could not figure out why. I believe it was ultimately caused by loop back protection on the server running the endpoint I was trying to reach with httpClient. This can be disabled with a registry key, but since I didn't want to modify my endpoint server's registry, so I ran my httpClient code on another machine in the same network and it worked perfectly. I can confirm that using CredentialCache.DefaultNetworkCredentials worked fine for me, since my calling code was running in a user context that was authorized to access the endpoint server I'm running the calling code in a scheduled job with a certain user credential configured for the scheduled job. Good luck and thanks Rick!


Rick Strahl
May 09, 2023

re: Removing the IIS Server Request Header from ASP.NET Core Apps (any version)

@James - good catch, I didn't notice. I took a look and it appears that recent versions of ASP.NET have changed when the headers are injected by the ASP.NET Core framework. It appears the headers are now injected after all the processing is completed. I took a look and set it breakpoint inside of the 1) the MVC request handler, and 2) inside of the middleware and neither one of them shows the ASP.NET generated headers in Response.Headers - only those that the application is adding. Can't remove headers that aren't already present.

So the remove functionality is somewhat broken in the middleware handler - that may no longer be possible to do.

I've removed the remove operations from the sample.


Also James
May 09, 2023

re: Removing the IIS Server Request Header from ASP.NET Core Apps (any version)

In the post you have '''opt.HeadersToRemove.Add("X-Powered-By");'''

but the screenshot shows the X-Powered-By header. Assuming that's a mistake?


Rick Strahl
May 09, 2023

re: Removing the IIS Server Request Header from ASP.NET Core Apps (any version)

@James - thanks for the reminder - I've added a note into the post.


James
May 09, 2023

re: Removing the IIS Server Request Header from ASP.NET Core Apps (any version)

The web.config removal works as long as the app is running on IIS 10+.


Rafał
May 06, 2023

re: Role based JWT Tokens in ASP.NET Core APIs

Thanks for great article (and another even better about combining cookie and jwt)! I wanted though to implement additional 'Secondary layer' for fwt tokens - when user account is disabled by admin, check its state in database and forbid access. For cookie authentication there is article how to inject such procedure https://learn.microsoft.com/en-us/aspnet/core/security/authentication/cookie?view=aspnetcore-3.1#react-to-back-end-changes-1 but I can't find similar way for fwt tokens. Can you give a hint on implementation (a link maybe)?