There is no conversion between HelloWorldComponent and System.Func`2 [System.Collections.Generic.IDictionary`2 // Parameter name: signature

I'm working through Scott Allen's MVC 5 Course Fundamentals on Pluralsight

I am getting an error when using (WebApp.Start (uri)) "in the code below.

Mistake

An unhandled exception of type 'System.ArgumentException' occurred in Microsoft.Owin.dll
  System.ArgumentException was unhandled
  HResult=-2147024809
  Message=No conversion available between ConsoleApplication1.HelloWorldComponent and System.Func`2[System.Collections.Generic.IDictionary`2[System.String,System.Object],System.Threading.Tasks.Task].
Parameter name: signature
  Source=Microsoft.Owin
  ParamName=signature
  StackTrace:
       at Microsoft.Owin.Builder.AppBuilder.Convert(Type signature, Object app)
       at Microsoft.Owin.Builder.AppBuilder.BuildInternal(Type signature)
       at Microsoft.Owin.Builder.AppBuilder.Build(Type returnType)
       at Microsoft.Owin.Hosting.ServerFactory.ServerFactoryAdapter.Create(IAppBuilder builder)
       at Microsoft.Owin.Hosting.Engine.HostingEngine.StartServer(StartContext context)
       at Microsoft.Owin.Hosting.Engine.HostingEngine.Start(StartContext context)
       at Microsoft.Owin.Hosting.Starter.DirectHostingStarter.Start(StartOptions options)
       at Microsoft.Owin.Hosting.Starter.HostingStarter.Start(StartOptions options)
       at Microsoft.Owin.Hosting.WebApp.StartImplementation(IServiceProvider services, StartOptions options)
       at Microsoft.Owin.Hosting.WebApp.Start(StartOptions options)
       at Microsoft.Owin.Hosting.WebApp.Start[TStartup](StartOptions options)
       at Microsoft.Owin.Hosting.WebApp.Start[TStartup](String url)
       at ConsoleApplication1.Program.Main(String[] args) in e:\EShared\Dev2015\WebAppScottAllen\ConsoleApplication1\ConsoleApplication1\Program.cs:line 16
       at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
       at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       at System.Threading.ThreadHelper.ThreadStart()
  InnerException: 

      

Code

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using Microsoft.Owin.Hosting;
using Owin;
namespace ConsoleApplication1
{
    using AppFunc = Func<IDictionary<string, object>, Task>;
    class Program
    {
        static void Main(string[] args)
        {
            string uri = "http://localhost:8080";
            using (WebApp.Start<Startup>(uri))   // Katana Please start, using the configuration from the Startup class and listening on the port given by the uri
            {
                Console.WriteLine("Started!");
                Console.ReadKey();
                Console.WriteLine("Stopping!");
            }
        }
    }

    public class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            app.Use<HelloWorldComponent>();
        }
    }

    public class HelloWorldComponent
    {
        AppFunc _next;
        public HelloWorldComponent(AppFunc next)
        {
            _next = next;
        }

        // Katana uses reflection to find this Invoke function that matches the AppFunc signature
        public Task Invoke(IDictionary<string, object> environment)
        { 
            var response = environment["owin.ResponseBody"] as Stream;

            using (var writer = new StreamWriter(response))
            {
                return writer.WriteAsync("Hello");
            }
        }
    }
}

      

packages.config

<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="Microsoft.Owin" version="3.0.1" targetFramework="net451" />
  <package id="Microsoft.Owin.Diagnostics" version="3.0.1" targetFramework="net451" />
  <package id="Microsoft.Owin.Host.HttpListener" version="3.0.1" targetFramework="net451" />
  <package id="Microsoft.Owin.Host.SystemWeb" version="3.0.1" targetFramework="net451" />
  <package id="Microsoft.Owin.Hosting" version="3.0.1" targetFramework="net451" />
  <package id="Owin" version="1.0" targetFramework="net451" />
</packages>

      

I wonder not to use to get this message, so I wonder what could have changed

+3


source to share


1 answer


There is a new way to write our middleware components that looks like this:

public class HelloWorldComponent : OwinMiddleware
{
    public HelloWorldComponent(OwinMiddleware next) : base(next) { }

    public override Task Invoke(IOwinContext context)
    {
        return context.Response.WriteAsync("Hello, World!");
    }
}

      

In particular, the constructor must accept a referenceOwinMiddleware

as its first parameter, otherwise you will get an error because the ctor signature does not match the one expected by the current Owin implementation.

Next, consider the following parameterized usage :



    var param1 = "Hello, World!";
    appBuilder.Use<HelloWorldComponent>(param1)

      

To properly support this, you'll need a modified constructor signature:

public class HelloWorldComponent : OwinMiddleware
{
    public HelloWorldComponent(OwinMiddleware next) : base(next) { }

    public override Task Invoke(IOwinContext context, string param1)
    {
        return context.Response.WriteAsync(param1);
    }
}

      

This way we can parameterize our middleware through the Use()

params array .

+2


source







All Articles