The ActiveX era pre-dated ASP.NET.

When the web was new, it was so clearly not designed for apps that pretty much everyone agreed it was absurd to use it that way. The UX and DX was just such a horrifically huge downgrade. Instead, HTML was for documents and linking, and apps would be given a rectangle (maybe the entire rectangle) through which they could appear in the browser. Netscape partnered with Sun for Java applets. ActiveX was therefore a response to that.

ActiveX made a lot of sense for Microsoft at the time. Firstly, it let the enormous base of Windows devs put stuff into a web page almost overnight. Secondly, it leveraged existing tech that was already designed for embedding one app's UI inside another app (OLE), and for shipping widget libraries to visual designers (OCX). Thirdly, ActiveX was a lot faster and more efficient than Java applets, being based around tightly written Win32 code. Finally, people weren't so focused on security back then and anyway, Microsoft had recently been investing in adding code signing to Windows. It appeared to them at the time that code signing would be sufficient to stop abuse. We know in retrospect it didn't quite work out that way for them, although it's been pretty successful on Macs.

And in fact ActiveX did see quite wide usage, albeit mostly as IE's answer to Netscape's plugin interface. But it didn't take off in a big way because:

1. ActiveX apps were native code and native code is very low level and thus very large compared to JavaScript and HTML. Performance is great because the CPU eats it directly with no intermediate translation layers, but you pay for it in code size. Back then bandwidth and CPU were both tight, but HTML/JS were light on both at the cost of UI latency and primitive controls. People picked low startup time followed by high latency and primitive controls.

2. The UI they picked for code signing was a (standard at the time) popup modal dialog. It had very poor usability, being filled with tons of complicated words, often asking you to approve software from a company you'd never heard of (i.e. products/websites did not use the same name as the company that produced them) and worse, malicious web pages could put you into an infinite loop where if you clicked cancel they'd just immediately ask you again, forcing you to click yes. Which was equivalent to downloading and running an unsandboxed program. Back then browsers went years between updates so once they shipped that mistake, it was very hard to fix quickly and so the reputation of ActiveX became very poor.

3. They had no way to sandbox native code at this time, the Windows kernel just didn't support it at all and it probably wouldn't have occurred to them anyway.

The first problem was fundamental to the approach. The second problem was an unforced error.

They could have tried to switch over to a sandboxable bytecode; VB used what they called "P-code" on an interpreter already. But they didn't. Java was becoming too popular, too fast, and they lost confidence in their own tech stack. Instead Gates threw the company into a crash effort to clone Java. By the time .NET had the ability to do ActiveX controls they'd already moved on from that approach and were trying to make DHTML work instead.