2010-05-12 4 views
29

Tôi đang sử dụng phiên bản xây dựng tự động được đề cập trong this question (không phải câu trả lời đã chọn nhưng câu trả lời sử dụng kỹ thuật [assembly: AssemblyVersion("1.0.*")]). Tôi đang làm điều này trong chân của tập tin Site.Master tôi trong MVC 2. Mã của tôi để làm điều này là như sau:Không thể tải phiên bản lắp ráp cho chân trang

<div id="footer"> 
    <a href="emailto:[email protected]">[email protected]</a> - Copyright © 2005-<%= DateTime.Today.Year.ToString() %>, foo LLC. All Rights Reserved. 
    - Version: <%= Assembly.GetEntryAssembly().GetName().Version.ToString() %> 
</div> 

Ngoại lệ tôi nhận được là một Object reference not set to an instance of an objectGetEntryAssembly() lợi nhuận NULL. Các tùy chọn khác của tôi cũng không hoạt động. GetCallingAssembly() luôn trả về "4.0.0.0" và GetExecutingAssembly() luôn trả về "0.0.0.0". Khi tôi nhìn vào các tệp DLL của tôi, mọi thứ đều đang được phiên bản như tôi mong đợi. Nhưng tôi không thể tìm ra cách để truy cập nó để hiển thị trong chân của tôi !!

+0

'Assembly.GetAssembl. y (this.GetType()) GetName(). Version.ToString() 'cũng trả về" 0.0.0.0 " – Jaxidian

+0

GetEntryAssembly() cũng có thể trả về null khi assembly được gọi từ mã không được quản lý http://msdn.microsoft .com/en-us/library/system.reflection.assembly.getentryassembly.aspx – GenEric35

+0

và w3wp.exe thực sự không được quản lý, Mô-đun 'w3wp.exe' không chứa tiêu đề CLI – GenEric35

Trả lời

56

Đó là vì Assembly.GetEntryAssembly() trả về giá trị rỗng: có không có số "mục nhập" trong trang ASP.NET (vì khung .NET được lưu trữ trong quá trình w3wp.exe). Assembly.GetEntryAssembly() được sử dụng để lấy cụm .exe mà bạn đã khởi chạy từ (thường là trong giao diện điều khiển hoặc ứng dụng Windows)

trả về phiên bản với phiên bản 0.0.0.0 "là do ASP.NET biên dịch Site.Master của bạn vào một tập hợp tạm thời trong thư mục "Tệp tin tạm thời ASP.NET" của bạn. this là tham chiếu đến lớp "được tạo".

Assembly.GetExecutingAssembly()cơ bản giống như Assembly.GetAssembly(this.GetType()) (ngoại trừ nó cũng hoạt động khi không có "này" (ví dụ như trong các phương pháp tĩnh).

Cách tốt nhất là explicity sử dụng sử dụng một loại mà bạn bí quyết tồn tại trong lắp ráp bạn sau khi Như một ví dụ, tôi giả sử bạn "Site.Master" có một mã-đằng sau tập tin đó được biên dịch vào lắp ráp các bạn có thể sử dụng thay vì:..

Assembly.GetAssembly(typeof(Site)).GetName().Version.ToString() 

(giả sử tên của lớp là Site)

+10

Công trình này! '<% = Assembly.GetAssembly (typeof (HomeController)) GetName(). Version.ToString()%>' – Jaxidian

+0

Thú vị, tôi đã thực hiện một bài kiểm tra nhỏ bằng cách tạo phần mở rộng HtmlHelper có lệnh Assembly.GetExecutingAssembly() trong đó và tôi đã có thể gọi nó từ Site.Master của tôi và nó hoạt động tốt! Điều này thực sự là đáng ngạc nhiên đối với tôi bởi vì tôi đã sửa đổi tệp csproj của mình để biên dịch chế độ xem của tôi. Tôi có hiểu lầm về cài đặt đó không? Tôi nghĩ rằng loại bỏ tất cả các hội đồng tạm thời và whatnot? – Jaxidian

+1

Lượt xem luôn được biên dịch, sự khác biệt là bạn có thể biên dịch mọi thứ lên phía trước trong một lần hoặc bạn có thể biên dịch chúng theo yêu cầu khi trang web được truy cập lần đầu tiên. Dù bằng cách nào, họ vẫn sẽ được biên dịch thành một DLL riêng biệt. –

15

Cũng như một giải pháp mà mọi người có thể quan tâm, tôi đã bịa đặt những người giúp đỡ để giúp đỡ với vấn đề này:

public static class HtmlHelperExtensions 
{ 
    private static string _CachedCurrentVersionDate; 

    /// <summary> 
    /// Return the Current Version from the AssemblyInfo.cs file. 
    /// </summary> 
    public static string CurrentVersion(this HtmlHelper helper) 
    { 
     try 
     { 
      var version = Assembly.GetExecutingAssembly().GetName().Version; 
      return version.ToString(); 
     } 
     catch 
     { 
      return "?.?.?.?"; 
     } 
    } 

    public static string CurrentVersionDate(this HtmlHelper helper) 
    { 
     try 
     { 
      if (_CachedCurrentVersionDate == null) 
      { 
       // Ignores concurrency issues - assuming not locking this is faster than 
       // locking it, and we don't care if it's set twice to the same value. 
       var version = Assembly.GetExecutingAssembly().GetName().Version; 
       var ticksForDays = TimeSpan.TicksPerDay * version.Build; // days since 1 January 2000 
       var ticksForSeconds = TimeSpan.TicksPerSecond * 2 * version.Revision; // seconds since midnight, (multiply by 2 to get original) 
       _CachedCurrentVersionDate = new DateTime(2000, 1, 1).Add(new TimeSpan(ticksForDays + ticksForSeconds)).ToString(); 
      } 

      return _CachedCurrentVersionDate; 
     } 
     catch 
     { 
      return "Unknown Version Date"; 
     } 
    } 
} 

này cho phép tiêu thụ như sau trong footer của bạn:

Version: <%= Html.CurrentVersion() %> from <%= Html.CurrentVersionDate() %> 
+1

Điều chỉnh do thời gian tiết kiệm ánh sáng ban ngày không được tính trong thời gian tính toán. –

3

Nếu bạn đã có Global.asax tại chỗ, nó có thể là một nơi tốt để lưu trữ phiên bản trên toàn cầu một lần.

Global.asax.cs:

public class Global : HttpApplication 
{ 
    public static readonly Version Version = Assembly.GetExecutingAssembly().GetName().Version; 
} 

xem của bạn:

<div>- Version: @YourNamespace.Global.Version</div> 
+0

Rất tiếc, điều này không thể kiểm tra được. – abatishchev

8

Bạn có thể:

ví dụ trong phương pháp Application_Start của bạn trong toàn cầu.tập tin tuyến Asax thêm

protected void Application_Start(object sender, EventArgs e) 
{ 
    HttpContext.Current.Application.Add("Version", System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString()); 
} 

trong HTML hiển thị nó bằng cách

<div><% =HttpContext.Current.Application["Version"].ToString() %></div> 

CŨNG phiên bản Change hội để 1.0.0 * bằng cách vào -. tính chất dự án> Ứng dụng> Thông tin hội và phiên bản lắp ráp là hiển thị như 1.0.0.0 - thay đổi nó thành 1.0.0 *

này sẽ cung cấp cho bạn một số phiên bản

+0

Điều này trở nên có thể kiểm chứng bằng cách thêm các thủ thuật/tính phức tạp khác nhau. – abatishchev