使用程序集中的Web应用程序版本号(ASP.NET/C#)

Dav*_*ett 54 .net c# asp.net reflection assemblies

如何在引用的程序集中获取调用Web应用程序的版本号?

我尝试过使用System.Reflection.Assembly.GetCallingAssembly().GetName()但它只是给我动态编译的程序集(返回版本号0.0.0.0).

更新:在我的情况下,我需要一个解决方案,不需要引用回Web应用程序集中的类.Jason在下面的答案(标记为已接受)符合此要求 - 此处提交的许多其他人都没有.

Jas*_*ett 50

以下是我使用的一些代码,它支持从Web或非Web应用程序获取应用程序的"主"程序集,然后您可以使用GetName().Version来获取版本.

它首先为非Web应用程序尝试GetEntryAssembly().这在ASP.NET下返回null.然后它查看HttpContext.Current以确定这是否是Web应用程序.然后它使用当前HttpHandler的Type - 但是如果使用ASPX页面进行调用,则此类型的程序集可能是生成的ASP.NET程序集,因此它遍历HttpHandler的BaseType链,直到找到不在的类型为止. ASP.NET为其生成的类型("ASP")使用的命名空间.这通常是主程序集中的类型(例如代码隐藏文件中的Page).然后我们可以使用该类型的程序集.如果所有其他方法都失败,则返回GetExecutingAssembly().

这种方法仍然存在潜在问题,但它适用于我们的应用程序.

    private const string AspNetNamespace = "ASP";

    private static Assembly getApplicationAssembly()
    {
        // Try the EntryAssembly, this doesn't work for ASP.NET classic pipeline (untested on integrated)
        Assembly ass = Assembly.GetEntryAssembly();

        // Look for web application assembly
        HttpContext ctx = HttpContext.Current;
        if (ctx != null)
            ass = getWebApplicationAssembly(ctx);

        // Fallback to executing assembly
        return ass ?? (Assembly.GetExecutingAssembly());
    }

    private static Assembly getWebApplicationAssembly(HttpContext context)
    {
        Guard.AgainstNullArgument(context);

        object app = context.ApplicationInstance;
        if (app == null) return null;

        Type type = app.GetType();
        while (type != null && type != typeof(object) && type.Namespace == AspNetNamespace)
            type = type.BaseType;

        return type.Assembly;
    }
Run Code Online (Sandbox Code Playgroud)

更新:我已将此代码转换为GitHubNuGet上的一个小项目.

  • `getWebApplicationAssembly`的版本对我没有用'因为'IHttpHandler`.我想出了一个使用`httpContext.ApplicationInstance`而不是`context.CurrentHandler`的版本. (7认同)
  • @toddkitta:Yodan的答案将引入从引用程序集BACK到Web应用程序中的类的依赖关系。我希望可以使用不引用该项目中任何类的解决方案。 (2认同)

Yod*_*ber 40

我发现获得"主"程序集(而不是动态程序集)版本的最简单的单行方式是:

typeof(MyMainClass).Assembly.GetName().Version
Run Code Online (Sandbox Code Playgroud)

使用您的顶级类,它不太可能"改变其含义"或作为重构努力的一部分被替换为MyMainClass.您知道在哪个程序集中定义了这个类,并且不再混淆版本号的来源.


Ran*_*per 27

我更喜欢Web.Config来存储当前版本的站点.

您还可以尝试在Web应用程序根目录中创建具有以下内容的AssemblyInfo.cs文件:

using System.Reflection;
using System.Runtime.CompilerServices;
...
[assembly: AssemblyVersion("1.0.*")]
...
Run Code Online (Sandbox Code Playgroud)

然后通过代码访问该值,如下所示:

System.Reflection.Assembly.GetExecutingAssembly()
Run Code Online (Sandbox Code Playgroud)

这里有关于AssemblyInfo类的更多信息.

  • 从实际的Web应用程序中检索版本相当容易,但只能在后面的代码中完成 - 使用System.Reflection.GetExecutingAssembly().GetName().Version.ToString().我认为会有一些检索方法它来自参考组件但是... (2认同)

Ami*_*aja 14

添加到已发布的响应者.为了在ASP.Net Web应用程序中获取程序集版本,您需要在代码隐藏文件中放置一个方法,类似于:

protected string GetApplicationVersion() {
    return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
}
Run Code Online (Sandbox Code Playgroud)

在ASPX页面中,您只想显示版本号:

<%= GetApplicationVersion() %>
Run Code Online (Sandbox Code Playgroud)


小智 8

以防任何人仍然感兴趣; 这应该做的伎俩,应该是一点点的不仅仅是采取更安全BaseTypeApplicationInstance让你的手在Global.asax中实现.

Global.asax始终与AssemblyInfo.cs中的程序集属性编译到同一程序集中,因此这适用于定义Global.asax的所有Web应用程序.

对于那些没有定义自己的Global.asax中,它会回落到生成的版本global_asax类型,这始终是0.0.0.0,而对于不属于Web应用程序的应用程序,它只是不返回任何版本可言.

奖金; 使用BuildManager类并没有需要有效的HttpContext情况下,这意味着你应该能够和使用该应用程序从启动代码.

public static Version GetHttpApplicationVersion() {
  Type lBase = typeof(HttpApplication);
  Type lType = BuildManager.GetGlobalAsaxType();

  if (lBase.IsAssignableFrom(lType))
  {
    while (lType.BaseType != lBase) { lType = lType.BaseType; }
    return lType.Assembly.GetName().Version;
  }
  else
  {
    return null;
  }
}
Run Code Online (Sandbox Code Playgroud)


And*_*der 6

HttpContext.Current.ApplicationInstance派生自global.asax.cs中的类.您可以执行以下操作

 var instance = HttpContext.Current.ApplicationInstance;
 Assembly asm = instance.GetType().BaseType.Assembly;
 System.Version asmVersion = asm.GetName().Version;
Run Code Online (Sandbox Code Playgroud)

它适用于ASP.NET(ASPX)和ASP.NET MVC