Using the Web Application version number from an assembly (ASP.NET/C#)
Solution 1
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.
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().
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 GitHub and NuGet.
Solution 2
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.
Solution 3
I prefer the Web.Config to store the current version of the site.
You can also try create an AssemblyInfo.cs file in the web application root that has the following:
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.
Solution 4
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:
protected string GetApplicationVersion() {
return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
}
In the ASPX page you want to display the version number simply place:
<%= GetApplicationVersion() %>
Solution 5
Just in case anyone is still interested; this should do the trick and should be a tad safer than just taking the BaseType
of ApplicationInstance
to get your hands on the Global.asax implementation.
Global.asax is always compiled into the same assembly as the assembly attributes from AssemblyInfo.cs, so this should work for all web applications that define a Global.asax.
For those that don't define their own Global.asax, it will fall back to the version of the generated global_asax
type, which is always 0.0.0.0, and for applications that aren't web applications, it will just return no version at all.
Bonus; using the BuildManager
class does not require an active HttpContext
instance, which means you should be able to use this from application startup code as well.
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;
}
}
David Duffett
.NET Architect mainly focused on e-commerce at present...
Updated on August 28, 2020Comments
-
David Duffett over 3 years
How do I obtain the version number of the calling web application in a referenced assembly?
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).
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.
-
Joe over 12 years"... I needed a solution that did not require a reference back to a class within the web application assembly" - I'd be curious to know why you require this. I must say I think Yodan Tauber's solution looks a lot cleaner to me than the accepted answer - though I'd use
typeof(Global)
rather than an application-specific class name. -
David Duffett over 12 years@Joe - The method is in a shared assembly used in various solutions. Those applications may or may not be web applications. Either way, I need to be able to obtain the version number of the application, without actually referencing a class within the application.
-
CheapReference over 12 years@David I find this a confusing and poorly phrased question even with your update. If the answer you selected is what youre really looking for then the question needs amending to avoid confusion. You should include the requirement that you could be being called by a non web app AND you have no knowledge of the HttpApplication (global.cs) type or any type within the assembly. If this is the case I would consider refactoring this interface.
-
-
David Duffett about 15 yearsRetrieving the version from the actual web application is fairly easy, but can only be done in code behind - using System.Reflection.GetExecutingAssembly().GetName().Version.ToString().I would think there would be some way of retrieving it from a referenced assembly though...
-
David Duffett over 13 yearsThis is the answer I was looking for - it seems to be the only answer that actually retrieves the version of the "Web Application" (rather than the version of the assembly you are in) without relying on recording the version in a config file. Nice.
-
Cristi Potlog almost 13 yearsThe version of
getWebApplicationAssembly
didn't worked for me 'cause of an nullIHttpHandler
. I came up with a version usinghttpContext.ApplicationInstance
instead ofcontext.CurrentHandler
. -
Jason Duffett almost 13 yearsThanks for the tip Cristi. I guess context.CurrentHandler will only work for threads directly servicing asp.net requests, and only after the IHttpHandler has been created.
-
quentin-starin almost 13 years@Cristi: should have made that an answer
-
toddkitta over 12 yearsDuffman, I'm curious as to why @yodan 's answer didn't quite hit the mark for you.
-
David Duffett over 12 years@toddkitta: Yodan's answer would introduce a dependency from the referenced assembly BACK to a class in the web application. I would rather a solution that I can use that does not reference any classes within that project.
-
abatishchev over 12 years@David: Probably you mean
System.Reflection.Assembly.GetExecutingAssembly()...
:) -
David Duffett over 12 years@TomDeloford - Looks like your answer requires a reference back to a class within the web assembly. Jason's answer doesn't require that.
-
Joe over 12 years+1, this seems to me to be the obvious and cleanest solution, despite the OP's update stating that he wants a solution that does not require a reference to a class within the web application assembly (it would help if he said why). If it's an ASP.NET Web Application project, the obvious class to use would be
Global
, the code-behind base class for Global.asax. -
Jason Duffett over 11 years@CristiPotlog I've updated the project on GitHub to include your change to use httpContext.ApplicationInstance as CurrentHandler only works in WebForms, not MVC, applications.
-
Carra about 11 yearsThe only problem with this is that my dll with the getversion code can't access the top level dll that contains the mainclass.
-
Carra about 11 yearsFinally, something that works! Tried by using the entryassembly which is null, using the httpcontext which is null and iterating my stacktrace which didn't work either.
-
mack almost 11 yearsThanks, this is exactly what I was after.
-
Simon Tewsi about 10 yearsDoes this apply to web applications or just Windows Forms applications?
-
Alex about 9 yearsStoring application version in web.config makes it easy to retrieve from scripts outside of executing code. I'll be switching to web.config from AssemblyVersion attribute
-
YipYip almost 9 yearsYou have hard-coded types in that code, so you'll need a reference. The solution should be something that can be put into a NuGet package and installed into any web application (and therefore, you can't use a hard-coded "MyHttpApplication"). My purpose is to create a reusable splash screen that shows app version and title (from AssemblyTitleAttribute).
-
CheapReference almost 9 yearsAs I stated in my answer the question states 'with no reference'. A type name is not a reference, therefore for a lot of people (and as the question is phrased) this is the easiest solution. No where does it mention being installed in any web application or a NuGet package.
-
YipYip almost 9 yearsI think the reason the question asks for "no reference" is because the code must exist in a separate library that must have no compile-time knowledge of the web applications it will be used in (today "MyHttpApplication", tomorrow "AnotherHttpApplication"). If you copy & paste the code directly into the web application (and hard code the type), then of course you have access to the types and you wouldn't need a reference.
-
CarlR over 8 yearsWhich assembly contains the Guard,AgainstNullArgument method? It doesn't appear to be a standard one.
-
Jason Duffett over 8 yearsGuard.AgainstNullArgument was a convenience method I was using in that project. It effectively looks like this: if (argument == null) throw new ArgumentNullException("Argument cannot be null");
-
Dave over 5 yearsSimplified to:(HttpContext.Current.ApplicationInstance).GetType().BaseType.Assembly.GetName.Version.ToString()