Использование номера версии веб-приложения из сборки (ASP.NET/C#)


Как получить номер версии вызова веб-приложения в сборке?

Я пробовал с помощью System.Отображение.Собрание.GetCallingAssembly ().GetName () но он просто дает мне динамически скомпилированную сборку (возвращающую номер версии 0.0.0.0).

UPDATE: в моем случае мне нужно было решение, которое не требовало ссылки на класс в сборке веб-приложения. Ответ Джейсона ниже (помечен как принятый) выполняет это требование - многие другие представленные здесь не делают.

11 51

11 ответов:

вот некоторый код, который я использую, который поддерживает получение" основной " сборки приложения из веб-или не-веб-приложений, затем вы можете использовать GetName().Версия версия.

Он сначала пытается GetEntryAssembly () для не-веб-приложений. Это возвращает null под ASP.NET. Затем он смотрит на HttpContext.Тока, чтобы определить, является ли это веб-приложение. Затем он использует тип текущего HttpHandler - но сборка этого типа может быть сгенерирована ASP.NET сборка, если вызов сделан из с помощью страницы ASPX, поэтому он пересекает цепочку базовых типов HttpHandler, пока не найдет тип, который не находится в пространстве имен, которое ASP.NET использует для своих сгенерированных типов ("ASP"). Обычно это будет тип в вашей основной сборке (например. Страница в файле с выделенным кодом). Затем мы можем использовать сборку этого типа. Если все остальное не удается, то вернуться к 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.

Я считаю, что самый простой однострочный способ получить версию вашей "основной" сборки (вместо динамической):

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

используйте свой класс верхнего уровня, который вряд ли когда-либо "изменит свое значение" или будет заменен в рамках рефакторинга, как MyMainClass. Вы знаете, в какой сборке определен этот самый класс, и больше не может быть путаницы относительно того, откуда берется номер версии.

Я предпочитаю интернет.Конфигурация для хранения текущей версии сайта.

вы также можете попробовать создать AssemblyInfo.cs-файл в корне веб-приложения, который имеет следующее:

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

затем получить доступ к значению с помощью кода следующим образом:

System.Reflection.Assembly.GetExecutingAssembly()

здесь информация в классе AssemblyInfo.

чтобы добавить к ответчикам, которые уже размещены. Для того, чтобы получить версию сборки в ASP.Net веб-приложение вам нужно разместить метод в коде позади файла, похожего на:

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

на странице ASPX вы хотите отобразить номер версии просто поместите:

<%= GetApplicationVersion() %>

на всякий случай, если кто - то все еще заинтересован; это должно сделать трюк и должно быть немного безопаснее, чем просто взять BaseType of ApplicationInstance чтобы получить ваши руки на глобальный.реализация asax.

глобальные.asax всегда компилируется в ту же сборку, что и атрибуты сборки из AssemblyInfo.cs, так что это должно работать для всех веб-приложений, которые определяют глобальный.асакс.

для тех, кто не определяет свой собственный глобальный.asax, он вернется к версии генерируется global_asax тип, который всегда 0.0.0.0, и для приложений, которые не являются веб-приложениями, он просто не вернет версию вообще.

бонус; использование 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.Текущий.ApplicationInstance является производным от класса в глобальном.асакс.цезий. Вы можете сделать следующее

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

Он работает как внутри ASP.NET (ASPX) и ASP.NET MVC

я столкнулся с подобной проблемой, и подумал, что вы можете найти решение полезно.

мне нужно было сообщить текущую версию приложения (проекта веб-приложения) из пользовательского серверного элемента управления, где серверный элемент управления содержался в другой библиотеке. Проблема заключалась в том, что" самые простые " геттеры сборки не обеспечивали правильную сборку.

  • Assembly.GetExecutingAssembly() возвращает сборку, содержащую элемент управления; не приложение собрание.
  • Assembly.GetCallingAssembly() возвращает различные сборки в зависимости от того, где я был в дереве вызовов; обычно система.Web, а иногда и сборка, содержащая элемент управления.
  • Assembly.GetEntryAssembly() вернулся null.
  • new StackTrace().GetFrames()[idx].GetMethod().DeclaringType.Assembly извлекает сборку фрейма в трассировке стека по индексу idx; однако, помимо того, что он неэлегантен, дорог и склонен к просчету индекса фрейма, трассировка стека может быть не содержит любой вызовы сборки приложения.
  • Assembly.GetAssembly(Page.GetType()) забил мне App_Web_@#$@#$%@ сборка, содержащая динамически генерируемые страницы. Конечно, динамическая страница наследует класс от моей сборки приложения, так что это привело к окончательному решению:

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

со ссылкой на сборку в руке вы можете перейти к версии через ее имя:

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

сейчас, это решение работает, потому что у меня была ссылка на тип из сборка приложения. Мы не используем никаких страниц, которые делают не наследовать от кода позади, так что это бывает эффективным для нас, но ваш пробег может отличаться, если методы кодирования вашей организации отличаются.

удачи в кодировании!

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

некоторая информация здесь:http://www.velocityreviews.com/forums/showpost.php?p=487050&postcount=8

in asp.net 2.0 каждая страница встроена в нее собственной сборкой, поэтому только dll сборная России.CS-это встроенная в будет верните правильный ответ. просто добавьте статический метод для AssemblyInfo.CS, что возвращает информацию о версии и вызов этот метод с других ваших страниц.

-- Брюс (sqlwork.com)

но я написал a простой способ сделать это:

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

Если вы ищете это из веб-элемента управления, один хак, чтобы найти тип кода за страницей (т. е. класс, который наследует от System.Сеть.ПОЛЬЗОВАТЕЛЬСКИЙ ИНТЕРФЕЙС.Страница.) Обычно это происходит в веб-сборке потребителя.

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

Я надеюсь, что есть лучший путь.

государства-вопрос без ссылки (экземпляры) он не сказал (первоначально) без знания типов веб-приложений.

EDIT OP уточнил, что да, они действительно не требуют знания типов в вызывающей веб-сборке, поэтому ответ подходит. Однако я бы серьезно рассмотрел рефакторинг такого решения, чтобы версия передавалась в другую сборку.

для большинства людей в этом случае если вы знаете пользовательский тип HttpApplication:

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

и если у вас есть только динамически генерируемые типа:

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

прекратите голосовать за этот ответ:)