本文介绍了HelloWorldComponent和System.Func`2 [System.Collections.Generic.IDictionary`2//参数名称:签名之间没有可用的转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在完成Scott Allen关于Pluralsight的MVC 5基础课程

I am working through Scott Allen's MVC 5 Fundamentals course on Pluralsight

在下面的代码中使用(WebApp.Start(uri))"时出现错误.

I get an error at "using (WebApp.Start(uri)) " in the code below.

错误是

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: 

代码是

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是

packages.config is

<?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 did not use to get this message, so I wonder what could have changed

推荐答案

有一种编写中间件组件的新方法,如下所示:

There is a new way to write our middlewares components, which 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!");
    }
}

具体来说,构造函数必须接受OwinMiddleware引用作为其第一个参数,否则会出现错误,因为ctor签名与当前Owin实现所期望的不匹配.

Specifically, the constructor must accept an OwinMiddleware reference as its first parameter, otherwise you get an error because the ctor signature does not match what is expected by the current Owin implementation.

此外,请考虑以下参数化用法:

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

要正确地支持这一点,您将需要修改后的构造函数签名:

To properly support this you will want 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);
    }
}

因此,允许我们通过Use()的params数组对中间件进行参数化.

Thus, allowing us to parameterize our middleware via Use()'s params array.

这篇关于HelloWorldComponent和System.Func`2 [System.Collections.Generic.IDictionary`2//参数名称:签名之间没有可用的转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-21 03:06