Recent Comments



Emilio
Thursday

re: Configuring ASP.NET and IIS Request Length for POST Data

5 years later, this blog post is still saving the day. Thanks, Rick!


Ron Clabo
Wednesday

re: ASP.NET Core In Process Hosting on IIS with ASP.NET Core

This is a really great article Rick. I've admired and appreciated many of your articles over the years and just came across this one anew when thinking of switching from OutOfProcess hosting to InProcess. I really appreciate your thoroughness and especially the benchmarks provided here. Thanks!


Ralph
November 29, 2021

re: Windows Authentication with HttpClient

The documentation:

The NetworkCredential class is a base class that supplies credentials in password-based authentication schemes such as basic, digest, NTLM, and Kerberos. Classes that implement the ICredentials interface, such as the CredentialCache class, return NetworkCredential objects.


Rick Strahl
November 28, 2021

re: Taking the new Chromium WebView2 Control for a Spin in .NET - Part 1

@alex - not sure what you mean. This works:

async Task InitializeAsync()
{
    // must create a data folder if running out of a secured folder that can't write like Program Files
    var browserFolder = Path.Combine(wsApp.Configuration.CommonFolder, 
                                     wsApp.Constants.WebViewEnvironmentFolderName);
    var options = new CoreWebView2EnvironmentOptions("--disable-web-security");
    var env = await CoreWebView2Environment.CreateAsync(
        userDataFolder: browserFolder, options: options
    );
    await WebBrowser.EnsureCoreWebView2Async(env);

The environment error means you're probably not setting up a custom folder for your environment and it's going to some existing environment that's not compatible. IOW, make sure you explicitly create an environment folder for your app.


alex
November 23, 2021

re: Taking the new Chromium WebView2 Control for a Spin in .NET - Part 1

This stuff dont work. I mean i was able to load content froms static file. But issue is changing environment throw error

System.ArgumentException: 'WebView2 was already initialized with a different CoreWebView2Environment. Check to see if the Source property was already set or EnsureCoreWebView2Async was previously called with different values.'

Only option is null. await webView.EnsureCoreWebView2Async(null);

i want to change environment options var op = new CoreWebView2EnvironmentOptions("--disable-web-security");

Basically try to do testing locally without running separate server.


Chuck Dee
November 23, 2021

re: Accepting Raw Request Body Content with ASP.NET Web API

I added the following:

        if (type == typeof(Stream))
        {
            return actionContext.Request.Content
            .ReadAsStreamAsync()
            .ContinueWith((task) =>
            {
                SetValue(actionContext, task.Result);
            });
        }

This works, but there's an annoying instance where sometimes it does not- the stream is zero bytes when I get here. It seems to be based on web server configuration, but I can't figure out what it could be. Any ideas on what I might be missing?


Rick Strahl
November 17, 2021

re: Creating a generic Markdown Page Handler using ASP.NET Core Middleware

@Ben - no I perfectly understood what you asked. The NetFX version and Core versions are different.

Similar functionality, different implementation for obvious reasons in that NetFX doesn't have middleware or default DI to inject with. You can use the Westwind.Web.Markdown package perfectly fine with classic MVC on NetFX, but it's a different library from the .NET Core Westwind.AspnetCore.Markdown package. IOW, you have to choose depending on your platform.


Ben McIntyre
November 17, 2021

re: Creating a generic Markdown Page Handler using ASP.NET Core Middleware

Sorry, we're going around in circles - I should have been more specific at the outset. To serve .md files in Asp Net Core/Std MVC, I believe I need to do

      services.AddMarkdown(config =>
        {
            config.AddMarkdownProcessingFolder("/posts/", "~/Views/Shared/_MarkdownTemplate.cshtml");
        });

and

       app.UseMarkdown();

This does not appear to be supported in the .Web package, but the .DotNetCore package doesn't appear to support Full Fwk 4, so I presume my only option is to change to an updated Net Core framework and then use the .DotNetCore version.
Or, of course, just use the static methods as a workaround and not serve .md files.


Rick Strahl
November 16, 2021

re: Creating a generic Markdown Page Handler using ASP.NET Core Middleware

@Ben - uh, and that matters how? This extension uses statics and controls, neither of which makes sense for DI and either of which can be used from anywhere.

If you're a stickler for everything has to go through DI, then you have to go elsewhere - namely write your own.


Ben McIntyre
November 15, 2021

re: Creating a generic Markdown Page Handler using ASP.NET Core Middleware

@Rick sure, there's no requirement for DI, but I am using DI, and the .Web versions seems not to support it...


Rick Strahl
November 15, 2021

re: Creating a generic Markdown Page Handler using ASP.NET Core Middleware

@Ben - not sure what you mean. WestWind.Web.Markdown has a net40 target for full framework. There is no DI requirement, nor does it need .NET Standard.


Ben McIntyre
November 15, 2021

re: Creating a generic Markdown Page Handler using ASP.NET Core Middleware

Hi Rick!
Long time fan and owner of Markdown Monster, just one question. I'm stuck in a project running .NET 4.6.2 as NetCore Standard 2, so it's got to use WestWind.Web.Markdown (rather than AspNetCore.Markdown), but because it's Net Standard it still uses the service injection model of Net Core.
I don't think this case is covered in either package for serving markdown directly - I'll just have to upgrade to NetCore 3 or Net(core)5. Just checking there's no workaround.


James White
November 09, 2021

re: Back to Basics: Add an ASP.NET Runtime Information Startup Banner

I really like this idea and have incorporated it into my applications as an extension method for IWebHostBuilder/IHostBuilder. Adding the product/file version is also helpful when you’re tracking bug fixes and such. Thanks!


Randy Burden
November 09, 2021

re: Back to Basics: Rewriting a URL in ASP.NET Core

Thanks. I used your redirect example to come up with the following:

private void HandleRedirects(IApplicationBuilder app)
{
    // Old Url, New Url
    var redirects = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
    {
        {"/Reports/BatchReport", "/Reports/BatchDetailReport" }
    };

    app.Use(async (context, next) =>
    {
        if (redirects.TryGetValue(context.Request.Path, out var redirectUrl))
        {
            context.Response.Redirect(redirectUrl);
            return;
        }

        await next();
    });
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    HandleRedirects(app);

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    // ...
}

Jörg
November 08, 2021

re: Discovering new C# String Pattern Matching Features

sol, I even like to write it as
`csharp "New".Equals(parameter) `
pretty close to spoken langauge


sol
November 05, 2021

re: Discovering new C# String Pattern Matching Features

This oldie but goodie works without type casting: Equals(parameter, "New"). However, doesn't expand so nice into comparing with multiple values as the type casting syntax.


Rick Strahl
November 05, 2021

re: Taking the new Chromium WebView2 Control for a Spin in .NET - Part 1

@Andre - Internet Explorer is getting retired, but not the MSHTML hostable engine. That will continue to work indefinitely.

There are lots and lots of applications that depend on the MSHTML engine including Office apps (both old and new!). If they pulled this a very large swath of Windows applications would no longer work, so that's not going to happen. But... it'll never get updated again, so you have to make do with the capabilities of the somewhat limited IE 11 HTML5 support.


Rick Strahl
November 05, 2021

re: Discovering new C# String Pattern Matching Features

@hahn-kev - parameter is of type object so you can't compare to string without a cast. Once you cast you have to first check for null (or with is or as). The point of this pattern is that it flattens the type casting and comparison into one statement.


hahn-kev
November 05, 2021

re: Discovering new C# String Pattern Matching Features

How is any of that code different from

parameter == "New" 

If parameter is null then then null is not equal to a string, no need to type check.


Andre
November 04, 2021

re: Taking the new Chromium WebView2 Control for a Spin in .NET - Part 1

Question about the old WebBrowser control... Since it is based on IE11, will it stop working when IE11 reaches end of life, on June 15, 2022?

In other words, are we forced upgrading our apps to the new WebView2 control before June 2022?

Thanks in advance.


Brian Wells
October 25, 2021

re: ASP.NET MVC Postbacks and HtmlHelper Controls ignoring Model Changes

On nearly the tenth anniversary of this post, I returned to it for nearly the fifth time, and probably not for the first time I note a typo which (this post proving to have some serious longevity) you may want to correct.

"..reflects the value in the mode." That should be "...reflects the value in the model."

Thanks again, Rick. Hopefully I won't need to refresh my mind on this topic again. But if I do, I know where to find this post, and I hope it will still be here. 😃


Stephen Wileman
October 15, 2021

re: String Extraction

I was looking for the equivalent of the VFP STREXTRACT() function and stumbled across this blog so thank you very much for saving me some time!

A great enhancement would be to add a parameter to look for the 'th occurrence of a match.


Rick Strahl
October 14, 2021

re: Chromium WebView2 Control and .NET to JavaScript Interop - Part 2

@Goran - yeah the WebView is not very flexible when it comes to interop, but it's not too difficult to build a reusable interop layer that works and is in the end more reliable than anything that's just 'there'. CEFSharp and WebView2 both use messaging so they're not directly using interop to execute and pass data around.

CEFSharp was just too slow in WPF - it was unusable and also fairly unstable to me, plus you had to distribute the huge runtime. I think the WinForms control is better but for WPF I had nothing but problems with it. CEFSharp also had similar UI quirks that I see with WebView2, so the issue here is partially the Windows control hosting which understandibly is difficult to implement for the controls.

At this point I've got the WebView2 to behave, but it's definitely been a long journey.


Goran
October 13, 2021

re: Chromium WebView2 Control and .NET to JavaScript Interop - Part 2

Hi Rick

First of all, your articles are awesome. 😃

I am currently working (company's project) on the proof of concept for mixing desktop (WPF) and web. We decided to go with CEFSharp and as far as I can conclude comparing with webview2, CEFSharp is far more flexible when it comes to Interop. There is an object binding that allows you to bind simple C# objects to the CEF Browser so they are visible as native JS objects. Same way, C# methods are visible from JS. From the other side (C# → JS), mechanism is the same as webview2 - executing the scripts.

The examples/samples on webview2 are mostly the imitation of web browser which is probably the least useful scenario in real life 😃

Regards Goran


Jim Foye
October 12, 2021

re: Wrestling with Clipboard Images in WPF

Rick, you have a typo: Windows.System.Clipboard.GetImage()

This is a great blog post, thank you. It's so sad that after all these years we still have to deal with crap like this in WPF.


Rodd
October 12, 2021

re: JavaScript JSON Date Parsing and real Dates

Thanks Rick. I'm just getting into a situation that requires me to work with times as well as dates. I'm curious how you deal with archived data when locale time may have changed. A client may be running in EST when a record is created and then be running in EDT when they later view an archived record. In my mind, storing the value in UTC would give the wrong time when viewing the record at a later time. IOW, if I started my meeting with a client at 8:00am EST, I want to reflect that the meeting started at 8:00am not 9:00am even though I'm now operating in EDT. Have you ever had to deal with something like this? Do you still store everything in UTC or is this an exception where it is necessary to store the time offset of the original date/time?


Evgenii Koksharov
October 12, 2021

Rick Strahl
October 08, 2021

re: Handling SPA Fallback Paths in a Generic ASP.NET Core Server

@Prince - You redirect to whatever URL serves your root page for the application.


Prince Owusu
October 08, 2021

re: Handling SPA Fallback Paths in a Generic ASP.NET Core Server

How do you handle such cases were there is not index.html like Next.js for asp core 6


Rick Strahl
October 06, 2021

re: WebView2 Flashing when changing TabControl Tabs

@Dallibor... yes I think I still would. I've looked into Electron a bit but it's just too bloody difficult to build a solid looking desktop UI with just HTML. There are no decent libraries that provide good UI that is suitable for desktop apps for controls, menus, window UI etc. so all that stuff has to be built by hand. It's possible but frankly too much to take on in a one-man project like MM is for me.


Rick Strahl
October 06, 2021

re: Taking the new Chromium WebView2 Control for a Spin in .NET - Part 1

@Howzilla, you can provide the userData when you create the environment. I think you have to make sure the location you provide (I would use %appdata% or %temp% for this) has full access to read and write the contents of this folder.


Howzilla
October 05, 2021

re: Taking the new Chromium WebView2 Control for a Spin in .NET - Part 1

I can see the control is trying to write to files inside my install directory ( E:\Development...\x86\Release\MyApp.exe.WebView2\EBWebView ). This won't work in production. I have tried the code you supplied to get the code to use a userDataFolder outside the application ( CoreWebView2Environment.CreateAsync() ) but it doesn't work. No matter what I do it still uses the directory inside the install directory. This is the only thing holding up this project. Very frustrating.


Dalibor Čarapić
October 04, 2021

re: WebView2 Flashing when changing TabControl Tabs

Quick question:
If you were to build the MM application today would you still use WPF or would you go full web application (electron)?


Rick Strahl
October 04, 2021

re: Publish Individual Files to your Server in Visual Studio 2012.2

@Jacob - in Visual Studio you have to pick the profile that is active. If you publish by command line you need to specify the profile explicitly if you have more than one.


Jacob
October 04, 2021

re: Publish Individual Files to your Server in Visual Studio 2012.2

If you have multiple publish profiles which one does it use??


Howzilla
October 02, 2021

re: Taking the new Chromium WebView2 Control for a Spin in .NET - Part 1

I have the webbrowser2 implemented in my VS2019 c# winform app, FW 4.7.2.

Everything works fine on the development machine.

When I install my app to a user machine the form with the webbrowser2 control opens but will not display the web page. I have installed the runtime on the user machine but it just won't work.

The form is very simple. I call the form passing arguments then assemble a uri and use that uri to set the Source for the webbrowser2 control.

Any ideas ??


Rick Strahl
September 29, 2021

re: Taking the new Chromium WebView2 Control for a Spin in .NET - Part 1

@David - No creating the folder is not enough since the permissions for the new files and folders are also required. Unless your installer sets the permissions of the folder preemptively created that will still fail. I recommend pushing the data into the app related %appdata% folder or if you create and wipe, maybe the %temp% folder.


David Elgstuen
September 29, 2021

re: Taking the new Chromium WebView2 Control for a Spin in .NET - Part 1

If the application was installed in \Program File(x86)\myapp but the application also preemptively creates the .WebView2 folder, would that guarantee write access and eliminate the need to relocate/manage UserDataFolder location?


Rene
September 29, 2021

re: Chromium WebView2 Control and .NET to JavaScript Interop - Part 2

Hi Rick,

nice article!

Do you know if there is a way to detect a mousedown anywhere in the browser?

For example, if I have a movie playing in WebView2 and you click on it, it shows the play/stop/back/forward icons etc., but I like to receive a mousedown event in my code. In fact same applies for any element in the page.

Rene


Robert
September 29, 2021

re: Creating Angular Synchronous and Asynchronous Validators for Template Validation

Realise it was a while ago but to answer Raphael's question I would suggest using something like "updateOn: 'blur'" so it sends one request when the user leaves the field.


Richard Külling
September 28, 2021

re: Capturing Performance Counter Data for a Process by Process Id

@Matt I thought that too at first, but 'PerformanceCounter.NextValue' gives back whatever value you have defined for it: look closer at the second argument "counterName" of the instantiation of the counter. If you pass it "ID Process", then the NextValue method will always return the ID of the Process. If you pass it "% Processor Time", then the NextValue method will always return the percentage of CPU usage by the process. In my opinion, this parameter should have been named "counterType", for there would have been less confusion.


Ana Helena
September 20, 2021

re: Programmatically Opening Windows Terminal in a Specific Folder

Hi Rick. Thanks for the post!

What if I wanted to open a new tab using a path? Can you help me with this? For instance, I have a folder D:/dev and I'd like to open this open using a profile to open in a new tab.

Thanks in advance. Ana


jamal kaksouri
September 20, 2021

re: Strongly Typed Configuration Settings in ASP.NET Core

In startup class using strongly type

usage:

services.Configure<MySettings>(a => Configuration.GetSection(nameof(ConnectionStrings)).Bind(a));

instead of...

services.Configure<MySettings>(Configuration.GetSection("MySettings"));

Rick Strahl
September 15, 2021

re: Taking the new Chromium WebView2 Control for a Spin in .NET - Part 1

@Rajesh - don't think there's UI activation available for that. You can use window.find() in JavaScript, but it looks like the showDialog parameter is not supported by Edge.


Rajesh Kumar
September 13, 2021

re: Taking the new Chromium WebView2 Control for a Spin in .NET - Part 1

Is there a way to show the Edge Find window. I have a WPF tree on left and Edge control on right, when we search we filter the tree based on search phrase. When we display the corresponding HTML page based on Tree View Node selected, I want to show the html page on Edge with phrase tokens highlighted.

Since I did not find APIs for this, simplest thought was to do SendKeys and that also did not work. Any thougts?


Rick Strahl
September 05, 2021

re: Variable Scoping in Anonymous Delegates in C#

@David - probably not a big concern. But from a pure code gen perspective using the static variable removes one dependency on the generated wrapper class, so results in slightly less code and one less assignment in executing code (although it's entirely possible that the optimizer might figure that out on its own during compilation - you'd have to look of the compiled Release IL to know for sure).


David Clarke
September 02, 2021

re: Variable Scoping in Anonymous Delegates in C#

So a question re coding style. I have an Action delegate that references a static variable. The method where the delegate is called assigns that static variable to a local variable:

var appContext = AppContext.Current;

InvokeSomeAction(() =>
{
    if (AppContext.Current.SessionInfo.IsSomeFlag ||
        appContext.SessionInfo.IsSomeFlag)
    {
        // which condition is better?
    }
});

Is there a reason to use one over the other or is it just a matter of preference?


Aravind S
August 31, 2021

re: Hosting SignalR under SSL/https

Hi Rick

Myself Aravind from India. I have created certificate using Opc.Ua.Generator and did port binding for my application certificate. Initially I was getting certificate issues on the client side hub saying "The underline connection was closed.Could not establish true relationship for SSL/TLS secure channel." I got this issue fixed by changing the Certificate name to Host name of the system which is running SignalR service. After this i was able to setup chat and communicate successfully with 3 systems in the same domain but this didn't work out when I took the setup to a different domain. I ended up in the former error and applying of the Host name didn't work out for the other network. Is there any problem in the fix I have applied or any alternate solution is there, Please let me know.


b.pell
August 28, 2021

re: Chromium WebView2 Control and .NET to JavaScript Interop - Part 2

First thing, thanks for your articles. They're always a good read.

I thought I'd share in case it's useful to anyone. This is probably hackery but for personal projects, whatever duct tape works in a reasonable time and doesn't crash is thumbs up for me. I'm using a WebView2 and then I have a code editor (AvalonEdit ❤️) which runs either Lua (via NLua) or JavaScript (via Jint). I pass some C# interop objects to scripting environments to allow them to interact with the WebView2 or whatever C# I want them to get to (their calls from those scripts to WebView2 are sync). What I ended up doing was creating a thread safe script result list (script result has an id, the result and if it's still running or not), so WPF would call ExecuteScriptAsync, immediately return an id that represents the script result and then the Jint/Lua can wait for that id to complete. If you do anything beyond trivial the Jint can be weird to read because it's JS executed in Jint then calling JS executed in WebView2 (a few times I forgot context I was in).

C#

public int ExecuteScript(string javaScript)
{
    var result = new ScriptResult()
    {
        Id = GetNextId(),
        IsRunning = true
    };

    ScriptResults.Add(result);

    Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(async () =>
    {
        try
        {
             result.Result = await _mainWindow.Edge.ExecuteScriptAsync(javaScript);
        }
        catch
        {
            // TODO: Pass exception info back
            result.IsRunning = false;
        }
        finally
        {
            result.IsRunning = false;
        }
    }));

    return result.Id;
}

Jint

// Call to WebView2
var id = edge.ExecuteScript("Math.abs(-5)");

// These script.LogInfo's are interop calls that write to a WPF control
// via the Dispatcher to the UI.
script.LogInfo("Waiting for id " + id);

var isRunning = true;

while (isRunning) {
        var result = edge.GetResult(id)
        isRunning = result.IsRunning;
	
        if (isRunning == false) {
            script.LogInfo("Result found!");
            buf = result.Result;
        }
	
        script.Pause(10)
}

script.LogInfo("Result is => " + buf);

My result is (noting I ate 10ms with the pause):

8/28/2021 2:12:36 PM: [Jint] [Info] Waiting for id 2
8/28/2021 2:12:36 PM: [Jint] [Info] Result found!
8/28/2021 2:12:36 PM: [Jint] [Info] Result is => 5
8/28/2021 2:12:36 PM: [MainWindow] [Info] Script complete in 34ms

Caveat, I'm by no means a WPF expert, so far I've had no dead locks with this approach (this is what I came up with after an hour of trying to wrangle the WebView2 to make sync calls).


Frank
August 27, 2021

re: Strongly Typed Configuration Settings in ASP.NET Core

Searching again on the web for an answer to a question, just as I have been doing for decades, and once again I run into that same old smiley face, Rick Strahl, who now seems so familiar to me it's like meeting an old friend. I might have to take the family on holiday from Europe to Hawaii just to go and see you in person.