2008-10-27 14 views
27

सामान्य WebForms परिदृश्य में, किसी भी जड़-संबद्ध URL (जैसे ~/फ़ोल्डर/file.txt) जैसे अंदर सीएसएस फ़ाइलें:ASP.NET MVC URL ऑटो-संकल्प

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

होगा यदि मैं

<head runat="server"> 

संदर्भ पृष्ठ में निर्दिष्ट करता हूं तो स्वचालित रूप से रनटाइम के दौरान हल हो जाता है।

हालांकि, यह अब एएसपी.नेट एमवीसी बीटा 1 वेबसाइट पर नहीं हो रहा है।

क्या कोई तरीका है कि मैं हैक या सीएसएस-लोडर फ़ाइल का उपयोग किए बिना इस कार्यक्षमता को सक्षम कर सकता हूं? शायद HttpModules या कुछ की तरह?

या क्या मैं अपनी वेबसाइट को सही तरीके से डिज़ाइन नहीं कर रहा हूं? एक अच्छा डिजाइन क्या माना जाता है?

चूंकि मूल एएसपी.नेट वेबफॉर्म में पहले से ही यह सुविधा है, इसलिए यदि संभव हो तो मैं किसी भी मौजूदा कार्यक्षमता का उपयोग करना पसंद करूंगा। लेकिन मेरे पास ज्यादा सुराग नहीं है।

यह वेब एप्लिकेशन कई वातावरणों में तैनात किया जाएगा जहां रूट फ़ोल्डर स्पष्ट नहीं हो सकता है।


संपादित करें: मैं फ़ाइल की सामग्री फ़ाइल का URL ही नहीं में यूआरएल मतलब है।

उत्तर

46

मैं ऑटो रूट रूट ~ चरित्र से परेशान नहीं होगा। मैं समझता हूं कि आप उसी समाधान को काम करना चाहते हैं जहां रूट निर्देशिका तैनाती के बीच भिन्न होती है, लेकिन सीएसएस दस्तावेज़ के भीतर आपको सापेक्ष पथों का उपयोग करने में कोई समस्या नहीं होनी चाहिए। सीएसएस दस्तावेज़ में पथ (आपके उदाहरण में छवि यूआरएल में) हमेशा उस सीएसएस फ़ाइल के लोड के किसी भी पेज के पथ के बावजूद सीएसएस फ़ाइल के स्थान से संबंधित होंगे। इसलिए यदि आपकी छवियां ~/Content/Images में हैं और आपकी स्टाइलशीट ~/Content/Stylesheets में हैं, तो आप हमेशा background-image: url(../Images/form_bg.gif); का उपयोग करने में सक्षम होंगे और यह स्टाइलशीट को लोड करने वाले पृष्ठ के स्थान पर ध्यान दिए बिना काम करेगा।

क्या कोई कारण यह काम नहीं करेगा?

+0

आह का उपयोग कर सकता हूं ... मैं फिर भी बेवकूफ था। यह काम करना चाहिए। मैं इसे आज़माउंगा। मैं वेब रूपों में सीएसएस में tilde (~) सापेक्ष पथ रखने के लिए इस्तेमाल किया गया था। और यह हमेशा काम करता है इसलिए मैं एमवीसी के लिए इसकी अपेक्षा कर रहा था लेकिन डुह .... – chakrit

+0

पुराने मैक ब्राउज़र के साथ इसमें कुछ समस्याएं हैं ... लेकिन मुझे नहीं लगता कि कोई भी अब उनका समर्थन करता है। – chakrit

+0

इसमें पुराने नेटस्केप संस्करणों के साथ कुछ समस्याएं भी हैं जो पृष्ठभूमि-छवि शैली नियम को गैर-मानक तरीके से पार्स करती हैं, जो कि आखिरी बार है जब मैं इस समस्या में भाग गया, इसलिए मेरा सुझाव IHttpModule का उपयोग करने के लिए।अंत में, हालांकि, शायद ऐसा होगा क्योंकि नेटस्केप लंबे समय तक चला गया है। –

4

Herearesome IHttpModule को लागू करने से आपके एप्लिकेशन पर वेब अनुरोधों को रोक करने पर resources ...

लिखें/एक अनुकूलन फ़ाइल प्रकार के लिए जाँच करने के लिए (जैसे स्यूडोकोड: अगर (अनुरोध ".css" के साथ समाप्त होता है) ...)

तो System.Web.VirtualPathUtility.ToAbsolute साथ "~ /" के सभी उदाहरणों को बदलने के लिए रेगुलर एक्सप्रेशन का उपयोग ("~ /")

मैं क्या यह, प्रदर्शन करने के लिए करना होगा चल पता नहीं है इस तरह के एक फ़िल्टर के माध्यम से हर अनुरोध, लेकिन आप शायद बेवकूफ हो सकता है अपनी वेब.कॉन्फिग फ़ाइल और/या आपके एमवीसी यूआरएल रूट्स को इस तरह के फ़िल्टर के माध्यम से सभी .css अनुरोधों को फ़नल करने के लिए अन्य फ़ाइलों के लिए छोड़कर इसे फ़िल्टर करते समय।

इसके बारे में सोचने के लिए आओ, आप संभवतः एक एएसपी.नेट एमवीसी ऐप के अंदर एक ही प्रभाव प्राप्त कर सकते हैं जो आपके सभी सीएसएस रिफ्रेंस को एक विशेष नियंत्रक पर इंगित कर सकता है। यह आपके लिए इस तरह के प्रीप्रोसेसिंग का प्रदर्शन करता है। मुझे संदेह है कि हालांकि IHttpModule के रूप में प्रदर्शन करने वाला होगा।

0

अनुरोध के रूप में यूआरएल को ठीक करने के लिए आप URL Rewriter का उपयोग कर सकते हैं, हालांकि मुझे यकीन नहीं है कि यह इस मामले में हैक के रूप में इतना सुंदर है।

+0

आह अच्छा विचार! मैं ऐसा करने के लिए रूटिंग फ्रेमवर्क का उपयोग कर सकता था। मुझे – chakrit

0

मैंने पथहेल्पर उपयोग वर्ग बनाया जो मुझे आवश्यक सभी पथ देता है। उदाहरण

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

के लिए मुझे() System.Web.VirtualPathUtility.ToAbsolute की मदद और अपने खुद के सम्मेलन (सामग्री/सीएसएस/yourFile.css) के साथ सही पूर्ण यूआरएल देता है।

मैंने जेएस, एक्सएमएल, टी 9 एन, तस्वीरों के लिए ऐसा ही किया ... इसका केंद्रीय, पुन: प्रयोज्य और अब मुझे केवल अपनी लाइनों और पृष्ठों में सामग्री/जेएस से लिपियों के स्क्रिप्ट फ़ोल्डर के स्थान को पकड़ने के लिए एक पंक्ति को बदलना पड़ा।

एक मूर्खता चाल अगर आप मुझसे पूछते हैं, लेकिन यह वर्तमान बीटा :(में वास्तविकता है

+0

आज़माएं, मेरा मतलब है कि फ़ाइल की सामग्री में यूआरएल फ़ाइल यूआरएल नहीं है। – chakrit

+0

मैं सी। –

1

आप ~/ पाठ फ़ाइलें, जावास्क्रिप्ट सहित किसी भी फ़ाइल, से बाहर पार्स करने का प्रयास कर रहे हैं, आदि, तो आप एक हैंडलर है कि यह करने के लिए एक फिल्टर प्रदान करती है लिख सकते हैं और आप उसका प्रयोग उन रास्तों ... उदाहरण के लिए के लिए खोज करने के लिए कर सकते हैं ...

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

    } 

} 

और आप एक कस्टम हैंडलर लिखेंगे पता करने के लिए जब करने के लिए इस फ़िल्टर को असाइन करें ... निम्न की तरह ...

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; 

    } 

} 

यह वास्तव में "IHttpModules देखें" कहने में आसान हो सकता है लेकिन यह कुछ कोड है जिसे मैंने ASP.net फ़ाइलों के अलावा पथों के लिए फ़ाइलों को पार्स करने के लिए उपयोग किया है।

आपको अपने आईआईएस सेटिंग्स में कुछ चीजों को भी बदलना होगा ताकि फ़ाइलों को एएसपीनेट आईएसएपीआई को संभालने वाली सभी फ़ाइलों के लिए वाइल्डकार्ड सेट करके पार्स किया जा सके। यदि आप IIS6 का उपयोग कर रहे हैं, तो आप at this website देख सकते हैं ...

आप किसी भी फ़ाइल प्रकार को संशोधित करने के लिए इसका उपयोग भी कर सकते हैं ताकि आप छवियों के लिए कुछ फ़िल्टर असाइन कर सकें, कुछ जावास्क्रिप्ट या स्टाइलशीट या ... वास्तव में कुछ भी ...

+0

धन्यवाद! मेरे पास पहले से ही वाइल्डकार्ड मैपिंग्स पहली चीज है। मुझे http मॉड्यूल के बारे में पता है लेकिन चूंकि एएसपी.नेट वेब फॉर्म * पहले से ही * यह है इसलिए मैं सोच रहा था कि एक आसान तरीका होना चाहिए .. कुछ मौजूदा एएसपी.नेट वेब फॉर्म मॉड्यूल को जोड़ने जैसे एमवीसी से छीन लिया गया है। धन्यवाद वैसे भी मैं आपके कोड – chakrit

5

एक चाल मैंने पहले भी इस्तेमाल किया है, वास्तव में मेरे सीएसएस फ़ाइल बनाने के एक .aspx एक्सटेंशन है, और पेज हस्ताक्षर में ContentType गुण सेट करने के लिए किया गया था:

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

यह सुनिश्चित होगा कि सीएसएस फ़ाइल एएसपी.नेट फ्रेमवर्क के माध्यम से चला जाता है, और सर्वर साइड कोड को आपके सापेक्ष पथ से बदल देता है।