共享程序集中的Attribute上的TypeLoadException

时间:2017-11-06 02:55:07

标签: c# .net asp.net-web-api attributes

更新10:29 MST 11/7

奇怪的是,如果我将属性从ComponentModel文件夹移回Common项目的根目录,则代码可以正常工作。在为InflowHealth.Common.ComponentModel命名空间重构所有引用之后,我无法想象可能引用旧命名空间的内容。

这几乎就像有些引用隐藏在某个地方,而不是基于代码而是运行时和动态,但在查看{{的所有查找结果时,我肯定不会看到它。 1}}。

更新19:33 MST 11/6

新的兴趣,当我注释掉使用自定义属性继承路由的行,并使用默认路由时,它仍然爆炸了。更令人感兴趣的是,在重构它并将其移动到文件夹(和名称空间)InflowHealthErrorContext之前,它正在寻找InflowHealth.Common.InflowHealthErrorContextAttribute 的命名空间实际上是旧的FQN。

更新07:42 MST 11/6

我相信我已经确定该问题与我用来继承操作的其他自定义属性有关。此属性已添加到ComponentModel,如下所示:

HttpConfiguration

该属性的实现非常简单:

public static void MapInheritedAttributeRoutes(this HttpConfiguration config)
{
    config.MapHttpAttributeRoutes(new InheritanceDirectRouteProvider());
}

似乎继承此public class InheritanceDirectRouteProvider : DefaultDirectRouteProvider { protected override IReadOnlyList<IDirectRouteFactory> GetActionRouteFactories(HttpActionDescriptor actionDescriptor) { return actionDescriptor.GetCustomAttributes<IDirectRouteFactory>(true); } } 属性会导致问题,但我不确定问题究竟是什么。我试过了:

  • 删除InflowHealthErrorContext以使其 可继承。
  • 仅因为配置错误而删除Inherited = false

那些没有改变错误。

ORIGINAL POST

我在一些Web API应用程序共享的AllowMultiple = true程序集中有一个非常简单的属性。这很简单,我只是无法弄清楚会导致这种异常的原因。

  

我试图在此收集Fusion日志,但它没有记录它们。

这是Common

Attribute

这将用于稍后为过滤器内部自动错误记录提供一些额外上下文的路径:

using System;

namespace InflowHealth.Common.ComponentModel
{
    [AttributeUsage(AttributeTargets.Method, Inherited = false, AllowMultiple = true)]
    public sealed class InflowHealthErrorContextAttribute : Attribute
    {
        // This is a positional argument
        public InflowHealthErrorContextAttribute(string errorContext)
        {
            ErrorContext = errorContext;
        }

        public string ErrorContext { get; }
    }
}

加载应用程序后,当注册Web API路由时,它将失败。以下是它突破的界限:

[Authorize(Roles = Roles.ALL_ADMINS)]
[Route("api/ControlPanelApi/PayerClassifications")]
[InflowHealthErrorContext("Error getting payer classifications.")]
public IHttpActionResult GetPayerClassifications(int clientId, bool showAllRows)
{
    return Ok(GetData(payerClassificationManager, clientId, showAllRows));
}

它抛出了这个例外:

  

无法加载类型&#39; InflowHealth.Common.InflowHealthErrorContextAttribute&#39;来自assembly&#39; InflowHealth.Common,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null&#39;。

这是堆栈跟踪:

GlobalConfiguration.Configure(WebApiConfig.Register);

3 个答案:

答案 0 :(得分:1)

InflowHealthErrorContextAttribute属于InflowHealth.Common.ComponentModel命名空间,但错误

  

无法加载类型   汇编中的“InflowHealth.Common.InflowHealthErrorContextAttribute”   'InflowHealth.Common,Version = 1.0.0.0,Culture = neutral,   公钥=空”。

显示它在InflowHealth.Common命名空间中搜索。这不是一个问题吗?

可能在您引用的Common程序集的某些过时版本中,属性位于InflowHealth.Common命名空间中,代码编译时没有错误,但在汇编中,获取输出文件夹属性实际上在{{1}命名空间和InflowHealth.Common.ComponentModel类型的搜索失败。

答案 1 :(得分:1)

我建议您删除binobj文件夹并重建项目。

这个问题有时会发生在有一个流浪的dll闲逛时,在编译项目时没有被覆盖。通常在重命名输出文件时。

过去,当涉及不反映对代码和重新编译所做的更改的引用时,执行上述操作对我有用。

Nuget软件包有时会发生同样的情况,这会导致必须删除软件包并重新安装它才能引用正确的dll。

答案 2 :(得分:0)

有两种可能的原因:

Web.Config指向错误的程序集或程序集编译错误。 首先,你指的是错误的程序集:

'InflowHealth.Common.InflowHealthErrorContextAttribute' from assembly 'InflowHealth.Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

应指向:

InflowHealth.Common.InflowHealthErrorContextAttribute' from assembly 'InflowHealth.Common.ComponentModel

请尝试检查网站的这一部分.Config:

 <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin.Security.OAuth" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin.Security.Cookies" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-3.0.1.0" newVersion="3.0.1.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" culture="neutral" publicKeyToken="30ad4fe6b2a6aeed" />
        <bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
        <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
      </dependentAssembly>

或在项目中搜索装配位置的设置位置。

如果这不能派上用场,请反汇编代码,看看代码的来源。