2008-10-27 21 views
27

Trong kịch bản WebForms bình thường, bất kỳ URL gốc tương đối (ví dụ ~/thư mục/file.txt) bên file CSS như:ASP.NET MVC URL tự động có độ phân giải trong file CSS

.form { background-image: url(~/Content/Images/form_bg.gif); } 

sẽ tự động được giải quyết trong thời gian chạy nếu tôi chỉ định

<head runat="server"> 

Trong trang tham chiếu.

Tuy nhiên, điều đó không còn xảy ra trên trang web ASP.NET MVC Beta1 nữa.

Có cách nào tôi có thể bật chức năng này mà không cần phải truy cập vào tệp hack hoặc trình tải tệp CSS không? Giống như HttpModules hay gì đó?

Hoặc tôi có không xác định chính xác trang web của mình không? Những gì được cho là một thiết kế tốt?

Kể từ khi ASP.NET WebForms gốc đã có tính năng này, tôi muốn sử dụng bất kỳ chức năng hiện có nào nếu có thể. Nhưng tôi không có nhiều đầu mối.

Ứng dụng web này sẽ được triển khai trong một số môi trường nơi thư mục gốc ~ có thể không rõ ràng.


EDIT: Ý tôi là các url trong nội dung của tập tin không phải là của tập tin url riêng của mình.

Trả lời

46

Tôi sẽ không bận tâm với nhân vật tự động tìm kiếm ~. Tôi hiểu rằng bạn muốn cùng một giải pháp để làm việc trong đó thư mục gốc khác giữa các triển khai, nhưng trong tài liệu CSS bạn không nên gặp bất kỳ vấn đề nào khi sử dụng các đường dẫn tương đối. Các đường dẫn trong tài liệu CSS (đến URL hình ảnh trong ví dụ của bạn) sẽ luôn liên quan đến vị trí của tệp CSS bất kể đường dẫn của bất kỳ trang nào tải tệp CSS đó. Vì vậy, nếu hình ảnh của bạn ở trong ~/Content/Images và biểu định kiểu của bạn ở trong ~/Content/Stylesheets, bạn sẽ luôn có thể sử dụng background-image: url(../Images/form_bg.gif); và nó sẽ hoạt động bất kể vị trí của trang tải biểu định kiểu.

Có lý do nào không hiệu quả?

+0

Ah ... Tôi đã ngu ngốc nhưng một lần nữa. Điều này sẽ hoạt động. Tôi se thử no. Tôi đã quen với việc có dấu ngã (~) tương đối trong CSS trong biểu mẫu web. Và nó luôn luôn làm việc vì vậy tôi đã mong đợi tương tự cho MVC nhưng duh .... – chakrit

+0

Nó có một số vấn đề với trình duyệt Mac cũ ... nhưng tôi không nghĩ rằng bất cứ ai hỗ trợ chúng nữa. – chakrit

+0

Nó cũng có một số vấn đề với phiên bản Netscape cũ phân tích quy tắc kiểu nền-hình ảnh theo cách không chuẩn, là lần cuối cùng tôi gặp sự cố này, do đó đề xuất của tôi sử dụng IHttpModule.Tuy nhiên, cuối cùng, có lẽ điều này sẽ xảy ra khi Netscape có thể sẽ biến mất. –

4

Herearesomeresources về việc thực hiện IHttpModule để đánh chặn các yêu cầu web để ứng dụng của bạn ...

Viết/thích ứng một để kiểm tra filetype (ví dụ giả: if (yêu cầu kết thúc với ".css") ...)

sau đó sử dụng một biểu thức chính quy để thay thế tất cả các trường hợp của "~ /" với System.Web.VirtualPathUtility.ToAbsolute ("~ /")

tôi không biết điều này sẽ làm gì để thực hiện, chạy mọi yêu cầu thông qua loại bộ lọc này, nhưng bạn có thể với tệp web.config và/hoặc các tuyến đường URL MVC của bạn để chuyển tất cả các yêu cầu .css thông qua loại bộ lọc này trong khi bỏ qua nó cho các tệp khác.

Hãy suy nghĩ về điều đó, bạn có thể đạt được hiệu ứng tương tự bên trong ứng dụng ASP.NET MVC bằng cách trỏ tất cả CSS của bạn vào một bộ điều khiển đặc biệt thực hiện loại tiền xử lý này cho bạn. tôi nghi ngờ rằng đó sẽ là biểu diễn như một IHttpModule mặc dù.

0

Bạn có thể sử dụng một số URL Rewriter để sửa URL khi yêu cầu đến, mặc dù tôi không chắc chắn rằng nó quá thanh lịch như một hack trong trường hợp này.

+0

Ah ý tưởng hay! Tôi có thể sử dụng khung định tuyến để làm điều đó. hãy để tôi thử – chakrit

0

Tôi đã tạo một lớp PathHelper util cung cấp cho tôi tất cả các đường dẫn tôi cần. Ví dụ

<link href="<%=PathHelper.CssUrl("FormulaIndex.css")%>" rel="Stylesheet" type="text/css"/> 

Cung cấp cho tôi địa chỉ chính xác đầy đủ với sự giúp đỡ của System.Web.VirtualPathUtility.ToAbsolute() và Công ước của riêng tôi (content/css/yourFile.css).

Tôi đã làm tương tự cho js, ​​xml, t9n, pics ... Trung tâm của nó, có thể tái sử dụng và bây giờ tôi chỉ phải thay đổi một dòng để nắm bắt chuyển động của thư mục tập lệnh từ nội dung/js sang Tập lệnh trong tất cả các trang web và trang của tôi.

Một động thái khờ dại nếu bạn hỏi tôi, nhưng đó là thực tế trong phiên bản beta hiện tại :(

+0

Tôi muốn nói Url trong CONTENT của tệp không phải là url của tệp. – chakrit

+0

Tôi c. –

1

Nếu bạn đang cố gắng để phân tích ~/ ra của bất kỳ tập tin, bao gồm các file văn bản, javascript, vv, bạn có thể viết một handler mà gán một bộ lọc để nó và bạn có thể sử dụng để tìm kiếm những con đường ... ví dụ ...

public class StringParsingFilter : MemoryStream { 

    public Stream OriginalStream { 
     get { return this.m_OriginalStream; } 
     set { this.m_OriginalStream = value; } 
    } 
    private System.IO.Stream m_OriginalStream; 

    public StringParsingFilter() : base() { 
     this.m_OriginalStream = null; 
    } 

    public override void Flush() { 
     this.m_OriginalStream.Flush(); 
    } 

    public override void Write(byte[] buffer, int offset, int count) { 

     //otherwise, parse for the correct content 
     string value = System.Text.Encoding.Default.GetString(buffer); 
     string contentType = HttpContext.Current.Response.ContentType; 

     //Do any parsing here 
     ... 

     //write the new bytes to the stream 
     byte[] bytes = System.Text.Encoding.Default.GetBytes(value); 
     this.m_OriginalStream.Write(bytes, offset, count + (bytes.Length - buffer.Length)); 

    } 

} 

và bạn sẽ viết một handler tùy chỉnh để biết khi nào chỉ định bộ lọc này ... như sau ...

public class FilterControlModule : IHttpModule { 

    public void Init(HttpApplication context) { 
     HttpApplication oAppContext = context; 
     oAppContext.BeginRequest += new EventHandler(_HandleSettingFilter);       
    } 

    private void _HandleSettingFilter(object sender, EventArgs e) { 

     //You might check the file at this part to make sure 
     //it is a file type you want to parse 
     //if (!CurrentFile.isStyleSheet()) { return; } 
     ... 

     //assign the new filter 
     StringParsingFilter filter = new StringParsingFilter(); 
     filter.OriginalStream = HttpContext.Current.Response.Filter; 
     HttpContext.Current.Response.Filter = (Stream)filter; 

    } 

} 

Có thể thực sự dễ dàng hơn khi nói "tra cứu IHttpModules" nhưng đây là một số mã mà tôi đã sử dụng để phân tích tệp cho các đường dẫn ngoài tệp ASP.net.

Bạn cũng sẽ phải thay đổi một số thứ trong cài đặt IIS để cho phép các tệp được phân tích cú pháp bằng cách đặt ASP.net ISAPI thành ký tự đại diện cho tất cả các tệp được xử lý. Bạn có thể xem thêm at this website, nếu bạn đang sử dụng IIS6 ...

Bạn cũng có thể sử dụng điều này để sửa đổi bất kỳ loại tệp nào để có thể gán một số bộ lọc cho hình ảnh, một số cho javascript hoặc stylesheets hoặc ... bất cứ điều gì ...

+0

Cảm ơn! Tôi đã có ánh xạ ký tự đại diện thực hiện điều đầu tiên. Tôi biết về các mô-đun http nhưng kể từ khi hình thức web ASP.NET * đã * có điều này vì vậy tôi đã nghĩ rằng phải có một cách đơn giản hơn .. giống như liên kết một số mô-đun hình thức web ASP.NET hiện có bị tước khỏi MVC. Cảm ơn anyway tôi có thể sử dụng mã của bạn – chakrit

5

Một mẹo nhỏ tôi đã sử dụng trong quá khứ, là để thực sự làm cho tập tin CSS của tôi có phần mở rộng .aspx, và thiết lập thuộc tính ContentType trong chữ ký page:

<%@ Page Language="C#" ContentType="text/css" %> 

body { 
    margin: 0; 
    padding: 0; 
    background: #C32605 url(<%= ResolveUrl("~/Content/themes/base/images/BodyBackground.png") %>) repeat-x; 
    font-family: Verdana, Arial, sans-serif; 
    font-size: small; 
    color: #d7f9ff; 
} 

Điều này sẽ đảm bảo rằng các tập tin CSS đi qua khung ASP.NET và thay thế mã phía máy chủ bằng đường dẫn tương đối của bạn.

Các vấn đề liên quan