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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/756031/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 23:58:36  来源:igfitidea点击:

Using the Web Application version number from an assembly (ASP.NET/C#)

c#.netasp.netreflectionassemblies

提问by David Duffett

How do I obtain the version number of the calling web application in a referenced assembly?

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

I've tried using System.Reflection.Assembly.GetCallingAssembly().GetName() but it just gives me the dynamically compiled assembly (returning a version number of 0.0.0.0).

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

UPDATE: In my case I needed a solution that did not require a reference back to a class within the web application assembly. Jason's answer below (marked as accepted) fulfils this requirement - a lot of others submitted here don't.

更新:就我而言,我需要一个不需要引用回 Web 应用程序程序集中的类的解决方案。下面杰森的回答(标记为已接受)满足了这个要求——这里提交的很多其他人都没有。

采纳答案by Jason Duffett

Here is some code I use that supports getting the application's "main" assembly from either Web or non-web apps, you can then use GetName().Version to get the version.

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

It first tries GetEntryAssembly() for non-web apps. This returns null under ASP.NET. It then looks at HttpContext.Current to determine if this is a web application. It then uses the Type of the current HttpHandler - but this type's assembly might be a generated ASP.NET assembly if the call is made from with an ASPX page, so it traverses the HttpHandler's BaseType chain until it finds a type that isn't in the namespace that ASP.NET uses for its generated types ("ASP"). This will usually be a type in your main assembly (eg. The Page in your code-behind file). We can then use the Assembly of that Type. If all else fails then fall back to GetExecutingAssembly().

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

There are still potential problems with this approach but it works in our applications.

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

    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;
    }

UPDATE: I've rolled this code up into a small project on GitHuband NuGet.

更新:我已将此代码汇总到GitHubNuGet上的一个小项目中。

回答by Random Developer

I prefer the Web.Config to store the current version of the site.

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

You can also try create an AssemblyInfo.cs file in the web application root that has the following:

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

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

then access the value via the code like this:

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

System.Reflection.Assembly.GetExecutingAssembly()

Here is more informaiton on the AssemblyInfo class.

这是有关 AssemblyInfo 类的更多信息

回答by Seiti

Some info here: http://www.velocityreviews.com/forums/showpost.php?p=487050&postcount=8

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

in asp.net 2.0 each page is built into it own assembly, so only the dll the AssemblyInfo.cs is built into will return the correct answer. just add a static method to AssemblyInfo.cs that returns the version info, and call this method from your other pages.

-- bruce (sqlwork.com)

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

-- 布鲁斯 (sqlwork.com)

But I wrote a simple method to do that:

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

    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();
    }

回答by Matt Woodard

If you are looking for this from a web control, one hack is to find the type of the code-behind Page (ie. the class that inherits from System.Web.UI.Page). This is normally in the consumer's web assembly.

如果您正在从 Web 控件中查找此内容,一个技巧是找到代码隐藏页面的类型(即从 System.Web.UI.Page 继承的类)。这通常在消费者的网络组件中。

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

I hope there is a better way.

我希望有更好的方法。

回答by Amir Khawaja

To add to the responders that have already posted. In order to get the assembly version in an ASP.Net web application you need to place a method in the code behind file similar to:

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

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

In the ASPX page you want to display the version number simply place:

在要显示版本号的 ASPX 页面中,只需放置:

<%= GetApplicationVersion() %>

回答by noname

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

回答by kbrimington

I encountered a similar problem, and thought you might find the solution useful.

我遇到了类似的问题,并认为您可能会发现该解决方案很有用。

I needed to report the current application version (of a web application project) from a custom server control, where the server control was contained in a different library. The problem was that the "easiest" assembly getters did not provide the right assembly.

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

  • Assembly.GetExecutingAssembly()returned the assembly containing the control; not the application assembly.
  • Assembly.GetCallingAssembly()returned different assemblies depending on where I was at in the call tree; usually System.Web, and sometimes the assembly containing the control.
  • Assembly.GetEntryAssembly()returned null.
  • new StackTrace().GetFrames()[idx].GetMethod().DeclaringType.Assemblyretrieves the assembly of a frame in the stack trace at index idx; however, besides being inelegant, expensive, and prone to miscalculation on the frame index, it is possible for the stack trace to not containany calls to the application assembly.
  • Assembly.GetAssembly(Page.GetType())scored me the App_Web_@#$@#$%@assembly containing the dynamically generated page. Of course, the dynamic page inherits a class from my application assembly, so that led to the final solution:
  • Assembly.GetExecutingAssembly()返回包含控件的程序集;不是应用程序集。
  • Assembly.GetCallingAssembly()根据我在调用树中的位置返回不同的程序集;通常是 System.Web,有时是包含控件的程序集。
  • Assembly.GetEntryAssembly()回来了null
  • new StackTrace().GetFrames()[idx].GetMethod().DeclaringType.Assembly在索引处检索堆栈跟踪中的帧的程序集idx;然而,除了不优雅、昂贵且容易对帧索引进行错误计算之外,堆栈跟踪可能不包含对应用程序程序集的任何调用。
  • Assembly.GetAssembly(Page.GetType())给我打分了App_Web_@#$@#$%@包含动态生成页面的程序集。当然,动态页面从我的应用程序集中继承了一个类,因此导致了最终的解决方案:


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

With the assembly reference in hand, you can drill to the version through its name:

有了程序集参考,您可以通过其名称深入了解版本:

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


Now, this solution works because I had a reference to a type from the application assembly. We don't use any pages that do notinherit from a code behind, so it happens to be effective for us, but your mileage may vary if your organization's coding practices are different.

现在,这个解决方案有效,因为我从应用程序程序集中引用了一个类型。我们不使用任何从背后的代码继承的页面,因此它恰好对我们有效,但是如果您组织的编码实践不同,您的里程可能会有所不同。

Happy coding!

快乐编码!

回答by Yodan Tauber

I find that the simplest one-liner way to get the version of your "main" assembly (instead of the dynamic one) is:

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

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

Use your top-level class, which isn't likely to ever "change its meaning" or to be replaced as part of a refactoring effort, as MyMainClass. You know in which assembly this very class is defined and there can no longer be confusion as to where the version number comes from.

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

回答by Tom Deloford

The question states with no reference(instances) it did not (originally) say with no knowledge of web application types.

这个问题没有参考(实例),它没有(最初)说不知道 Web 应用程序类型。

EDITthe OP clarified to state that yes they do really require no knowledge of types within the calling web assembly, so the answer is appropriate. However I would seriously consider refactoring such a solution such that the version is passed into the other assembly.

编辑OP 澄清说是的,他们确实不需要调用 Web 程序集中的类型知识,因此答案是合适的。但是,我会认真考虑重构这样的解决方案,以便将版本传递到另一个程序集。

For most people in this scenario if you know the custom HttpApplication type:

对于这种情况下的大多数人,如果您知道自定义 HttpApplication 类型:

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

and if you only have a dynamic generated type:

如果您只有动态生成的类型:

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

Stop voting me down for this answer :)

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

回答by Andrei Schneider

HttpContext.Current.ApplicationInstance is derived from the class in the global.asax.cs. You can do the following

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

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

It works both in ASP.NET (ASPX) and ASP.NET MVC

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