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

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

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

更新:在我的情况下,我需要一个解决scheme,不需要引用回到Web应用程序程序集中的类。 杰森的答案在下面(标记为接受)符合这个要求 – 很多其他人在这里提交没有。

这里是我使用的一些代码,它支持从Web或非Web应用程序获取应用程序的“主”程序集,然后可以使用GetName()。Version来获取版本。

它首先为非Web应用程序尝试GetEntryAssembly()。 这在ASP.NET下返回null。 然后查看HttpContext.Current来确定这是否是一个Web应用程序。 然后它使用当前HttpHandler的types – 但是如果该调用是使用ASPX页面创build的,则此types的程序集可能是生成的ASP.NET程序集,所以它将遍历HttpHandler的BaseType链,直到find一个不在ASP.NET用于其生成的types(“ASP”)的名称空间。 这通常是你的主程序集中的一个types(例如你的代码隐藏文件中的页面)。 然后我们可以使用该types的程序集。 如果一切都失败,则返回到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; } 

更新:我已经把这个代码上传到GitHub和NuGet上的一个小项目。

我发现最简单的一种方法来获得你的“主要”程序集(而不是dynamic程序集)的版本是:

 typeof(MyMainClass).Assembly.GetName().Version 

使用您的顶级类,它不可能像“ MyMainClass ”那样“改变它的含义”,或者作为重构工作的一部分被replaceMyMainClass 。 你知道在哪个程序集中定义了这个类,并且不能再混淆版本号的来源。

我更喜欢使用Web.Config来存储网站的当前版本。

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

 using System.Reflection; using System.Runtime.CompilerServices; ... [assembly: AssemblyVersion("1.0.*")] ... 

然后通过这样的代码访问值:

 System.Reflection.Assembly.GetExecutingAssembly() 

这是AssemblyInfo类的更多信息 。

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

 protected string GetApplicationVersion() { return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString(); } 

在ASPX页面你想显示的版本号只需放置:

 <%= GetApplicationVersion() %> 

以防万一谁还有兴趣 这应该做的伎俩,应该是比只是采用ApplicationInstanceBaseType来获得你的手Global.asax实施更安全。

Global.asax总是与AssemblyInfo.cs中的程序集属性一样编译成相同的程序集,所以这应该适用于所有定义Global.asax的Web应用程序。

对于那些没有定义自己的Global.asax的人来说,它将回退到生成的global_asaxtypes的版本,而这个版本始终是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; } } 

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

  var instance = HttpContext.Current.ApplicationInstance; Assembly asm = instance.GetType().BaseType.Assembly; System.Version asmVersion = asm.GetName().Version; 

它可以在ASP.NET(ASPX)和ASP.NET MVC中使用

我遇到了类似的问题,并认为你可能会发现解决scheme有用。

我需要从自定义服务器控件(其中服务器控件包含在不同的库中)报告当前的应用程序版本(Web应用程序项目)。 问题在于“最简单的”组装吸气剂没有提供正确的组装。

  • Assembly.GetExecutingAssembly()返回包含该控件的程序集; 不是应用程序集合。
  • Assembly.GetCallingAssembly()根据我在调用树中的位置返回不同的程序集; 通常是System.Web,有时是包含该控件的程序集。
  • Assembly.GetEntryAssembly()返回null
  • new StackTrace().GetFrames()[idx].GetMethod().DeclaringType.Assembly检索堆栈跟踪在索引idx ; 然而,除了不雅,昂贵且容易在帧索引上计算错误之外,堆栈跟踪可能不包含任何对应用程序组件的调用。
  • Assembly.GetAssembly(Page.GetType())为我带来了包含dynamic生成页面的App_Web_@#$@#$%@程序集。 当然,dynamic页面从我的应用程序组件inheritance了一个类,所以导致了最终的解决scheme:

 Assembly.GetAssembly(Page.GetType().BaseType) 

通过汇编参考,您可以通过名称钻取到该版本:

 var version = Assembly.GetAssembly(Page.GetType().BaseType) .GetName() .Version; 

现在,这个解决scheme可以工作,因为我有一个来自应用程序程序集的types的引用。 我们没有使用任何不是从后面的代码inheritance的页面,所以这对我们来说是有效的,但是如果你的组织的编码实践不同,你的里程可能会有所不同。

快乐的编码!

 Version version = new Version(Application.ProductVersion); string message = version.ToString(); 

这里有一些信息: http : //www.velocityreviews.com/forums/showpost.php? p=487050& postcount=8

在asp.net 2.0中,每个页面都内置到自己的程序集中,因此只有AssemblyInfo.cs内置的dll才会返回正确的答案。 只需将一个静态方法添加到AssemblyInfo.cs中,该方法返回版本信息,并从其他页面调用此方法。

– bruce(sqlwork.com)

但我写了一个简单的方法来做到这一点:

  public static string GetSystemVersion(HttpServerUtility server) { System.Xml.XmlDocument doc = new System.Xml.XmlDocument(); doc.Load(server.MapPath("~/web.config")); System.Xml.XmlNamespaceManager ns = new System.Xml.XmlNamespaceManager(doc.NameTable); ns.AddNamespace("bla", "http://schemas.microsoft.com/.NetConfiguration/v2.0"); System.Xml.XmlNode node = doc.SelectSingleNode("/bla:configuration/bla:system.web/bla:authentication/bla:forms[@name]", ns); string projectName = ""; if (node != null && node.Attributes != null && node.Attributes.GetNamedItem("name") != null) projectName = node.Attributes.GetNamedItem("name").Value; //in my case, that value is identical to the project name (projetname.dll) else return ""; Assembly assembly = Assembly.Load(projectName); return assembly.GetName().Version.ToString(); } 

如果你正在从一个Web控件寻找这个,一个黑客就是find代码隐藏页面的types(即从System.Web.UI.Pageinheritance的类)。 这通常在消费者的网页程序集中。

 Type current, last; current = Page.GetType(); do { last = current; current = current.BaseType; } while (current != null && current != typeof(System.Web.UI.Page)); return last; 

我希望有更好的办法。

这个问题没有提及 (实例),它没有(最初)没有知识的Web应用程序types说。

编辑 OP澄清说,是的,他们确实不需要在调用Web程序集的types的知识,所以答案是适当的。 不过,我会认真考虑重构这样的解决scheme,使版本被传递到其他程序集。

对于这种情况下的大多数人来说,如果你知道自定义的HttpApplicationtypes:

  typeof(MyHttpApplication).Assembly.GetName().Version 

如果你只有一个dynamic的生成types:

  typeof(DynamiclyGeneratedTypeFromWebApp).BaseType.Assembly.GetName().Version 

停止投票给我这个答案:)