aspnet / AspNetKatana

Microsoft's OWIN implementation, the Katana project
Apache License 2.0
960 stars 331 forks source link

Minimal Console errors out with: Object reference not set to an instance of an object. #468

Closed arturohernandez10 closed 8 months ago

arturohernandez10 commented 2 years ago

Error

System.NullReferenceException
  HResult=0x80004003
  Message=Object reference not set to an instance of an object.
  Source=Microsoft.Owin.Hosting
  StackTrace:
   at Microsoft.Owin.Hosting.Utilities.SettingsLoader.FromConfigImplementation..ctor()
   at Microsoft.Owin.Hosting.Utilities.SettingsLoader.<LoadFromConfig>b__0()
   at System.Threading.LazyInitializer.EnsureInitializedCore[T](T& target, Func`1 valueFactory)
   at Microsoft.Owin.Hosting.Utilities.SettingsLoader.LoadFromConfig(IDictionary`2 settings)
   at Microsoft.Owin.Hosting.Engine.StartContext..ctor(StartOptions options)
   at Microsoft.Owin.Hosting.WebApp.StartImplementation(IServiceProvider services, StartOptions options, Action`1 startup)
   at Program.<Main>$(String[] args) in C:\Projects\personal\Delete\TestServer\Program.cs:line 7

Just run the following code.

using Microsoft.Owin.Hosting;
using Owin;

string BaseUri = @"http://localhost:19000";
List<string> payloads = new();
var builder = WebApp.Start(BaseUri, app =>
{
    app.Run(async context =>
    {
        using StreamReader reader = new(context.Request.Body, System.Text.Encoding.UTF8);
        context.Request.Body.Position = 0;
        payloads.Add(await reader.ReadToEndAsync());
        context.Response.ContentType = "application/json";
        await context.Response.WriteAsync(@"{""Success"":true}");
    });
});

Console.In.ReadLine();
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNet.WebApi.OwinSelfHost" Version="5.2.9" />
  </ItemGroup>

</Project>
Tratcher commented 2 years ago

These libraries are not supported on .NET 6, only .NET Framework 4.x.

CZEMacLeod commented 2 years ago

Not really recommended, but if you are trying to port something already written with OWIN to net6.0, you may get the following to work. As @Tratcher says though, the Katana stack implementation of Owin is only supported on Framework 4.x.

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Owin" Version="6.0.4" />
    <PackageReference Include="Microsoft.AspNet.WebApi.Owin" Version="5.2.9" NoWarn="NU1701" />
    <PackageReference Include="Microsoft.AspNet.WebApi.Core" Version="5.2.9" NoWarn="NU1701" />
    <PackageReference Include="Microsoft.Owin" Version="4.2.2" NoWarn="NU1701" />
    <PackageReference Include="Owin" Version="1.0.0" NoWarn="NU1701" />
    <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
  </ItemGroup>
</Project>
using Microsoft.Owin.Builder;
using Microsoft.Owin.BuilderProperties;
using Owin;

string BaseUri = @"http://localhost:19000";

var corebuilder = WebApplication.CreateBuilder(args);
var coreapp = corebuilder.Build();

List<string> payloads = new();

coreapp.UseOwin(setup => setup(next =>
{
    var appServices = ((IApplicationBuilder)coreapp).ApplicationServices;
    var lifetime = appServices.GetRequiredService<IHostApplicationLifetime>();
    var webHostEnv = appServices.GetRequiredService<IWebHostEnvironment>();

    var owinbuilder = new AppBuilder();
    var properties = new AppProperties(owinbuilder.Properties)
    {
        AppName = webHostEnv.ApplicationName,
        OnAppDisposing = lifetime.ApplicationStopping,
        DefaultApp = next
    };

    owinbuilder.Run(async context =>
    {
        using StreamReader reader = new(context.Request.Body, System.Text.Encoding.UTF8);
        //context.Request.Body.Position = 0;    // Body stream does not support seeking
        payloads.Add(await reader.ReadToEndAsync());
        context.Response.ContentType = "application/json";
        await context.Response.WriteAsync(@"{""Success"":true}");
    });

    return owinbuilder.Build<Func<IDictionary<string, object>, Task>>();
}));

coreapp.Run(BaseUri);
vandanv commented 1 year ago

Is this API also not supported in net5.0/net6.0? private void GetPathAndQuery(HttpListenerRequest request, out string pathBase, out string path, out string query)

Getting "System.NullReferenceException: 'Object reference not set to an instance of an object.'" at Microsoft.Owin.Host.HttpListener.OwinHttpListener.GetPathAndQuery(HttpListenerRequest request, String& pathBase, String& path, String& query)

`

net5.0 net5.0 x64 Exe

`

CZEMacLeod commented 1 year ago

@vandanv Selfhost doesn't work on net5/6. You can host it under kestrel in the asp.net core pipeline as shown in my example. It should also work under IIS.

Tratcher commented 1 year ago

All of these components have been replaced by ASP.NET Core, you should migrate to the new libraries.

CZEMacLeod commented 1 year ago

@Tratcher Absolutely - but if you are cutting over and migrating, then you might want to test your code works under net6 first, then re-write them to ASP.NET Core. Also, if you are using systemweb-adapters, you might have tests running on owin components and you want to test them on net6.

Tratcher commented 1 year ago

For migration you're better off using the OWIN shim in AspNetCore to run on the servers there. That way you don't need to bring in extra libraries like HttpListener which we know aren't compatible.