Recent Comments


re: Back to Basics: Await a Task with a Timeout

Came to point out WaitAsync() but I guess someone got there first 😄 it was actually introduced in .net 6, so more widely available😊 I wrote a post about it and how it's implemented here: https://andrewlock.net/a-deep-dive-into-the-new-task-waitasync-api-in-dotnet-6/

Maybe also worth pointing out that just because you stopped waiting for the task, doesn't mean it stops running on the background: https://andrewlock.net/just-because-you-stopped-waiting-for-it-doesnt-mean-the-task-stopped-running/


Rick Strahl
Yesterday

re: Work around the WebView2 NavigateToString() 2mb Size Limit

@Byron - well, you can kinda do that with ExecuteScriptAsync() but it's definitely more cumbersome as you have to encode any string data you send and you can't pass object references back to .NET - everything has to happen in the DOM itself.

The big difference is that the control doesn't expose the DOM in the same way the WebBrowser control did - there's no direct connection between the control and the DOM. The only way to interact with the DOM is via script code. Once you know how this works you can do this relatively easily, but you end up doing most of the work with JavaScript either in the original document and calling into it (preferred if possible) or scripting via ExecuteScriptAsync().


Byron Adams
Wednesday

re: Work around the WebView2 NavigateToString() 2mb Size Limit

I wish they would at least allow element.innerHTML=someHtmlString. I used it all the time in old IE Browser component, still waiting for it.


Rick Strahl
Tuesday

re: Working around the WPF ImageSource Blues

Thanks @Majkimester - totally missed that this is available and it would probably work. According to the docs though, preferrable way is to let the data source manage the async load, so the workarounds are a good choice regardless.


Majkimester
July 20, 2024

Rafael Bodill
July 14, 2024

re: Fix that damn Git Unsafe Repository

.gitinfo is a mistake, it should be .gitconfig


Paul Austin
July 12, 2024

re: Fix that damn Git Unsafe Repository

Is it .gitconfig or .gitinfo. In some sections you switch between both of them


Rick Strahl
June 24, 2024

re: C# Version String Formatting

@Richard - But... it's great to discuss. I know I have to really work at reminding myself to look and see if I can utilize Span<T> or Memory<T> to optimize memory usage in a lot of places. In fact, in this very library I should probably go through all of my string functions - I'm sure there are lots of opportunities because that code mostly dates back to .NET 2.0 😄


Rick Strahl
June 24, 2024

re: C# Version String Formatting

@Richard - I am aware, but I try to avoid pulling in any extra dependencies as this code lives in a (trying to be) small utility library. It's not an issue for Core, but for NETFX I'm on the lookout to avoid if possible to keep the footprint down.

That said all of this is premature optimization: That code a) isn't ever going to be called in any critical path, b) isn't using any significant amount of memory, and c) allocates on the stack anyway. So it's hardly necessary to optimize. If I recall correctly, the compiler may actually automatically elevate that code to a span (I seem to remember Stephen Toub mention that recently, but can't recall if that only applied to the new collection initializers or also plain typed arrays) in later compiler versions compiling for the net80 target.


Richard Deeming
June 23, 2024

re: C# Version String Formatting

Unfortunately the library compiles to netstandard2.0 and net472 and so I can't use that.

If you can take a reference on the System.Memory NuGet package, you can still do that. You'll just need to manually change the <LangVersion> in the project file. 😃

<PropertyGroup>
    <LangVersion>12.0</LangVersion>

NB: Some language features will just work; some will require polyfills; and some require runtime support, and won't work at all. I tend to use PolySharp for the polyfills.


Rick Strahl
June 19, 2024

re: Using plUpload to upload Files with ASP.NET

@maruthi - No as that's a security concern. You'd have to manually capture that information and pass it in the extra variables that send up with the files.


maruthi
June 19, 2024

re: Using plUpload to upload Files with ASP.NET

Is is possible to get the files path when uploading files. I need to show the file path on where it is located with in the internal shared network.


Rick Strahl
June 18, 2024

re: C# Version String Formatting

@Richard - Yup - I think the code in the repo actually has a comment to that effect.

Unfortunately the library compiles to netstandard2.0 and net472 and so I can't use that. You don't need the type declaration - it's automatic, and the JIT auto-fixes that up.

I actually wonder if the compiler optimizes even a straight local int[] assignment to RO span if it's local and on the the stack and not modified (on .NET8.0)...


Richard Deeming
June 17, 2024

re: C# Version String Formatting

If you're using a recent version of C#, you could even avoid the array allocation:

ReadOnlySpan<int> items = [version.Major, version.Minor, version.Build, version.Revision];

That will allocate the span on the stack rather than the heap.


Rick Strahl
June 17, 2024

re: C# Version String Formatting

@Richard - Clever! I like it. Didn't think of reusing ToString() once I had dismissed it. I think I would make that even simpler like this mixing my code and your's:

public static string FormatVersion(this Version version, int minTokens = 2, int maxTokens = 2)
{
    if (minTokens < 1)
        minTokens = 1;
    if (minTokens > 4)
        minTokens = 4;
    if (maxTokens < minTokens)
        maxTokens = minTokens;
    if (maxTokens > 4)
        maxTokens = 4;

    var items = new int[] { version.Major, version.Minor, version.Build, version.Revision };
            
    int tokens = maxTokens;
    while (tokens > minTokens && items[tokens - 1] == 0)
    {
        tokens--;
    }
    return version.ToString(tokens);
}

Richard Deeming
June 16, 2024

re: C# Version String Formatting

Surely it would be simpler and more efficient to do something like this:

private static int Field(Version version, int token) => token switch
{
    0 => version.Major,
    1 => version.Minor,
    2 => version.Build,
    3 => version.Revision,
    _ => throw new ArgumentOutOfRangeException(nameof(token)),
};

public static string FormatVersion(this Version version, int minTokens = 2, int maxTokens = 2)
{
    if (minTokens < 1)
        minTokens = 1;
    if (minTokens > 4)
        minTokens = 4;
    if (maxTokens < minTokens)
        maxTokens = minTokens;
    if (maxTokens > 4)
        maxTokens = 4;
		
    int tokens = maxTokens;
    while (tokens > minTokens && Field(version, tokens - 1) == 0)
    {
        tokens--;
    }
    
    return version.ToString(tokens);
}

Rick Strahl
June 14, 2024

re: C# Version String Formatting

@Paulo - I mention that in the post. Doesn't quite do what I'm after which is optionally stripping zero values at the end.


Rick Strahl
June 13, 2024

re: ASP.NET Core Hosting Module with Shadow Copy Not Starting: Separate your Shadow Copy Folders!

@Steven - For me straight deploy fails too often to just go direct. On Azure you can use Git deploy via whatever that tool is they use which does an A/B deploy and that always works because they are not copying ontop of an existing installation. If you self-host your server though that's not an option unless you hack together a solution yourself (which sounds trivial but isn't).

Once ShadowCopy is configured correctly it works well, so the pain is a one time missed expectations issue more than anything.


rick Strahl
June 13, 2024

re: Windows Authentication with HttpClient

@Michael - You can get the current user credentials with CredentialCache.DefaultNetworkCredentials, otherwise you'd prompt for credentials. Or you can build a new NetworkCredential() and pass in a SecureString from a login dialog.


Ken
June 10, 2024

re: Runtime C# Code Compilation Revisited for Roslyn

Excellent information! I learned more through reading this post than hours of wandering through the morass of information from Microsoft or other sources. I have one general question through: Obviously, there are several methods available to generate and execute dynamic code, each with their own benefits and drawbacks. Can you give me any insight into where garbage collection fits in? I have a case where I need to generate dynamic code, call it numerous times and then discard it (and hopefully garbage collect the memory after discarding). Are there any pitfalls with regard to GC that I should be aware of? Thank you in advance.


Vlad
June 04, 2024

re: Windows Authentication with HttpClient

Rick, thank you, excellent post. I had an issue with HttpClient sending requests to the the same base URL with different Basic credentials. The was some authorization logic at the server connected to the business logic. The first request from Client1 authorized, the second Client2 request probably used the same connection group and authorized as Client1. I tried to change Keep-Alive CloseConnection settings, but that didn't help so I finally had to create a factory using username specific HttpClient. Do you think there a better implementation for it? Thanks


Rob
June 01, 2024

Rick Strahl
May 28, 2024

re: Mime Base64 is a Thing?

@Andrew - thanks for these links. I had no idea - looks like WebEncoders.Base64UrlEncode(bytes) (and decode) provide this very functionality I describe in this post.

Updated the post with more info. Thanks!


Andrew
May 27, 2024

re: Mime Base64 is a Thing?

It would seem .NET is set to receive first class support for Base64 URL encode / decode.

https://github.com/dotnet/runtime/issues/1658

https://github.com/dotnet/runtime/pull/102364


Steven Quick
May 19, 2024

re: ASP.NET Core Hosting Module with Shadow Copy Not Starting: Separate your Shadow Copy Folders!

It does seem like there are good reasons they decided to not include it originally (or enable it by default .net 6+).

If you could solve your locked files during web deploy problem another way you wouldn't need the extra complexity/fragility of shadow copy?

I'm curious what the web deploy command syntax produced by right click deploy looks like, ours (from azure pipelines iis deploy) tends to look like this:

msdeploy.exe -verb:sync 
-source:package='C:\dev\somesite\somesite.zip'
-dest:contentPath='somesite.somedomain.org' 
-enableRule:AppOffline 
-skip:Directory=App_Data

Haven't yet seen it fail for locked files, across about 30 sites being updated semi regularly and a few monthly (to self hosted vms) via azure pipelines.


Michał Kubiak
May 14, 2024

re: Windows Authentication with HttpClient

That's nice and all , but how do we do it without putting password in the code for example if user logged in using windows authentication?


Panache
May 10, 2024

re: Fighting WebView2 Visibility on Initialization

I just locate the form below the primary screen. The WebView2 loads, but is invisible to the user unless they check the task bar.


Darrell
May 07, 2024

re: Speed up your Start Menu by disabling Web Search

Great tip! It's annoying it's a setting that requires a registry change which is often a locked down for business laptops. oh well.


Jon Sagara
May 04, 2024

re: Speed up your Start Menu by disabling Web Search

Hi Rick,

I saw this little tool making the rounds this week, too:

https://github.com/xM4ddy/OFGB

Best,

Jon


Alexandre Jobin
May 01, 2024

re: ASP.NET Core Hosting Module with Shadow Copy Not Starting: Separate your Shadow Copy Folders!

I had the same kind of problem but with a little difference in the error description:

Application '/LM/W3SVC/1444810858/ROOT/mywebsite' with physical root 'D:\APPLS\WebApps\mywebapp' failed to load coreclr. Exception message: Unexpected exception: directory_iterator::directory_iterator: unknown error: "D:\APPLS\WebApps\MW5\MW5.DemandeRemboursement.Web\wwwroot\Composants"

The "Composants" folder is an actual folder, not a deleted one.

  • Each web sites use their own ShadowCopy folder
  • I can deploy many times without problem but one of them will cause the error where the site won't load
  • The only way I've found to fix it is to manually delete the ShadowCopy sub-folders and recyle the AppPool
  • I tried to enable cleanShadowCopyDirectory and since that day, the problem never came back
  • I then disabled cleanShadowCopyDirectory and the problem never came back for now... go figure
  • I enabled ASP.NET Core Module logs to have more info. I'm waiting for the error to come back.
    https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/iis/logging-and-diagnostics?view=aspnetcore-8.0#enhanced-diagnostic-logs

Dalibor Čarapić
April 30, 2024

Rick Strahl
April 29, 2024

re: Programmatic Html to PDF Generation using the WebView2 Control with .NET

@Mohamed

... yeah, and net8.0-windows😄 - that's required in order to use the WebView component!


Manuel Frog
April 25, 2024

re: Connection Failures with Microsoft.Data.SqlClient 4 and later

Year 2023: I upgraded a project from ".NET Core 3.1" to ".NET 6". Some nuget packages had to be updated too; one of them was "Microsoft.Data.SqlClient". I got the above error, another gray hair, and gladly found your solution.

Year 2024: I am upgrading a project from ".NET Core 3.1" to ".NET 8". Some nuget packages had to be updated too; one of them was "Microsoft.Data.SqlClient". I get the above error, another gray hair, and gladly found your solution, again.

Thank you for your blog post! And see you next year in 2025. xD


Mohamed Elnakib
April 24, 2024

re: Programmatic Html to PDF Generation using the WebView2 Control with .NET

Hello, well Applicationpool with on default type network service - the only solution was changing my asp.net core project targetframework to net8.0-windows instead of net8.0


Rick Strahl
April 22, 2024

re: Programmatic Html to PDF Generation using the WebView2 Control with .NET

Make sure you're not using ApplicationPoolIdentity for the App Pool identity. That pseudo account will not be able to create an instance. You have to use a real Windows account for this to work - it works with Network Service, System or any custom Windows account.


Mohamed Elnakib
April 22, 2024

re: Programmatic Html to PDF Generation using the WebView2 Control with .NET

Hello, using this library inside ASP.Net core generated Error 'Could not load file or assembly 'System.Windows.Forms, Version=4.0.0.0


Anandastoon
April 15, 2024

re: Fixing Adsense Injecting 'height: auto !important' into scrolled Containers

Finally, Mutation Observer is the answer. I do not care if the ads were cut horribly, my visitor is more important. I've turned off autoads, the optimization size in global settings, etc. etc. Fixing the inline styling also did not work, days of my productivity wasted. I could not believed Google destroy the UX so much while they are promoting material design rules. Thank you for this article, too bad this page is not on the first page of Google Search. Those Community solutions on the top of the page, none of them worked.


Parker Too
April 07, 2024

re: Async Event Methods and preventDefault() in JavaScript

Ha - I have just spent hours on exactly this problem, then came across your post. Thanks for posting - I thought I was going mad!


Rick Strahl
April 02, 2024

re: Programmatic Html to PDF Generation using the WebView2 Control with .NET

@martin - I looked at select-pdf and decided against it. The community edition only prints a few pages, and the paid versions are expensive for distribution. It too uses Chromium - I think at this point they all do including the commercial ones from big vendors. They all wrap Chromium and then add some additional functionality on top, which is what I plan on doing here as well.


Martin K
April 02, 2024

re: Programmatic Html to PDF Generation using the WebView2 Control with .NET

Sorry, your post was TLDR...

I had to implement HTML 2 PDF as a service for a website i worked on recently and had the same troubles.

The Chromium solution wasn't an option since it requires full access to the server (AFAIK) and the website is hosted on a webhotel.. so i had to find something else.

My other problem was that the solution was written in Framework 4.8 (MVC5) and i didn't have time to upgrade.

I found SelectPDF : https://selectpdf.com/community-edition/ which is also available for "Core"

The community edition allows me to print 5 pages, which is more than enough for my project.

But yeah, it's a struggle finding a PDF "file printer" around and many require payment because their solution runs on Azure or AWS as an API. The freeware are usually outdated or rubbish (DinkToPdf).


Rick Strahl
April 01, 2024

re: Publishing and Running ASP.NET Core Applications with IIS

@timmy, there are a lot of choices available but none are quite as simple as publishing from Windows mainly because WebDeploy provides support for many different mechanisms all in one toolchain and it integrates with the CLI.

On the Mac you can use Visual Studio for Mac which has publish support that supports Azure. The new Visual Studio Code tooling might also have similar support by now. But I'm not sure whether there is plain FTP server transfer if you're not running an Azure hosted site or container. Finally there are various publish pipelines that you can use with your GitHub repo to publish from certain branches or new tags using GitHub Actions.

There's an FTP Publish GitHub action:

https://github.com/marketplace/actions/ftp-deploy

I haven't used this because I'm stuck with Windows Servers for my apps and use WebDeploy, and hosted or containerized apps with most customers but that looks like it would work for FTP publish.


timmy
March 31, 2024

re: Publishing and Running ASP.NET Core Applications with IIS

Thanks for the blog. Quite useful.

I'm trying to publish a ASP.NET application to IIS hosted on an Azure VM. There are a lot of guides on how to do this from a Windows development machine.

I'm developing on a Mac. Right now I can do a:

dotnet publish

And manually FTP it over. Are there commands that can allow this to be done in an automated fashion?


Rick Strahl
March 20, 2024

re: Runtime C# Code Compilation Revisited for Roslyn

The point is that CodeDom is legacy code that's part of .NET framework. It's still available on Core via library import, but it's basically wrapper interface on top of Roslyn to mimic the old functionality. There's no reason you should be using the CodeDom for code compilation at this point other than compatibility with existing code that is already using it.


Andrew
March 20, 2024

re: Runtime C# Code Compilation Revisited for Roslyn

Let me try again. The post states that the codedom is the old API, but on the documentation site it is listed under .net 8 extensions section. If you mentioned using of the codedom api anywhere in the context of .net 8, please let me know where. Before posting my question I read your entire post, examined the contents of Westwind.Scripting GitHub repo, and on top of that searched for every occurrence of codedom term on the page, and read again around each one. Only after that I posted my questions. I'm not sure how you arrived at your conclusion 😭


Rick Strahl
March 20, 2024

re: Runtime C# Code Compilation Revisited for Roslyn

@Andrew - apparently you didn't bother to read the post. 😄


andrew
March 09, 2024

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

Thanks so much for this article! I found it after days of trying to wrangle a similar setup with current ASP.NET/Identity .NET 8, and with it I was able to get 90% of the way there.

And thanks to @Jovica I was able to fix the last remaining piece to get the auth+authz portion (roles) working by adding that last options.DefaultAuthenticateScheme


Edward Lawrence Williams
March 06, 2024

re: ASP.NET Core IIS InProcess Hosting Issue in .NET Core 3.1

Thank you for mentioning the logs! Hours later Im up and running.


Johnny
February 28, 2024

re: ISAPI Module Crashing on Application Pool Shutdown

@Richard Algeni Jr And what was it you did up to this point to solve it?