Site.less' 是物理路径,但应为虚拟路径

Posted

技术标签:

【中文标题】Site.less\' 是物理路径,但应为虚拟路径【英文标题】:Site.less' is a physical path, but a virtual path was expectedSite.less' 是物理路径,但应为虚拟路径 【发布时间】:2013-03-30 17:13:12 【问题描述】:

我在我的 MVC 4 项目中在网上找到了一个带有 LessTransformer.cs 的 DotLess。

using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Web.Optimization;
using MyNamespace.Infrastructure.Bundler;
using dotless.Core.configuration;

namespace MyNameSpace.Infrastructure.Transformers.Less

    public class LessTransform : IBundleTransform
    
        private readonly DotlessConfiguration _configuration;

        public LessTransform(DotlessConfiguration configuration)
        
            _configuration = configuration;
        

        public LessTransform()
            : this(DotlessConfiguration.GetDefaultWeb())
         

        public void Process(BundleContext context, BundleResponse response)
        
            var builder = new StringBuilder();

            _configuration.MinifyOutput         = false;
            _configuration.ImportAllFilesAsLess = true;
            _configuration.CacheEnabled         = false;
            _configuration.LessSource           = typeof(VirtualFileReader);

            foreach (var file in response.Files)
            
                if (!File.Exists(file.FullName))
                
                    continue;
                

                var content = ResolveImports(file);

                builder.AppendLine((_configuration.Web) ?
                                    dotless.Core.LessWeb.Parse(content, _configuration)
                                    : dotless.Core.Less.Parse(content, _configuration));
            

            response.ContentType = "text/css";
            response.Content = builder.ToString();
        

        private static readonly Regex SLessImportRegex =
            new Regex("@import [\"|'](.+)[\"|'];", RegexOptions.Compiled);

        private static string ResolveImports(FileInfo file)
        
            var content = File.ReadAllText(file.FullName, Encoding.UTF8);

            return SLessImportRegex.Replace(
                content,
                match =>
                
                    var import = match.Groups[1].Value;

                    // Is absolute path?
                    Uri uri;
                    if (Uri.TryCreate(import, UriKind.Absolute, out uri))
                    
                        return match.Value;
                    

                    var path = Path.Combine(file.Directory.FullName, import);

                    if (!File.Exists(path))
                    
                        throw new ApplicationException(string.Concat("Unable to resolve import ", import));
                    
                    return match.Value.Replace(import, path);
                );
        
    

我已经添加到这个

_configuration.MinifyOutput         = false;
_configuration.ImportAllFilesAsLess = true;
_configuration.CacheEnabled         = false;
_configuration.LessSource           = typeof(VirtualFileReader);



using System.IO;
using System.Web.Hosting;
using dotless.Core.Input;

namespace MyNamespace.Infrastructure.Bundler

    internal sealed class VirtualFileReader : IFileReader
    
        public byte[] GetBinaryFileContents(string fileName)
        
            fileName = GetFullPath(fileName);
            return File.ReadAllBytes(fileName);
        

        public string GetFileContents(string fileName)
        
            fileName = GetFullPath(fileName);
            return File.ReadAllText(fileName);
        

        public bool DoesFileExist(string fileName)
        
            fileName = GetFullPath(fileName);
            return File.Exists(fileName);
        

        private static string GetFullPath(string path)
        
            return HostingEnvironment.MapPath("\\Content\\css\\" + path);
        
    

我有一个 Less 文件

@import url('LESS\Site.less');
@import url('LESS\Site.Main.less');

body 
    #featured-posts 
        clear:both;
    


@media all and (max-width:320px) 
   @import url('LESS\Site.Mobile.less');

(我尝试了各种导入路径以及 /w 和 /wo 函数符号 url()

这都是在我的 BundleConfig 中提取的

    Bundle siteStyles = new      StyleBundle("~/bundles/css").Include("~/Content/css/Main.less");
    siteStyles.Transforms.Add(new LessTransform());
    siteStyles.Transforms.Add(new CssMinify());
    bundles.Add(siteStyles);

在添加 VirtualFileReader 之前,我遇到了错误:-

C:/SourceControl/Git/MyNameSpace/MyNameSpace/Content/css/LESS/Site.less' 是物理路径,但应该是虚拟路径。

自从我添加它后,我得到的只是 dotless.Core.LessWeb.Parse(content, _configuration) 上的值为 null

它总是在这条线上爆炸,因为我之前没有使用过这两种东西,但我似乎无法找到任何好的可靠文档/教程在上面。因此,如果您能帮助我解决我的错误,那将是非常棒的,并为我指明有关该主题的一些好的教程的方向,我将非常感激。

[编辑] 添加有关较少文件和文件结构的详细信息。

My File structure is 

Content/css/Main.less
Content/css/LESS/Site.less
Content/css/LESS/Mobile.less

等等... TIA。

附言不用担心 MyNamespace/MyNamespace 的内容,为了清楚起见,我已将其全部缩短。

【问题讨论】:

尝试将StyleBundle("~/bundles/css")更改为StyleBundle("~/Content/css/css") 另外,捆绑所有样式而不是使用@imports 似乎更有效。 它可能更有效,但 LESS 规范要求 @imports。理论上 BundleTransform 为我们做了“捆绑”。 不,在 VirtualFileReader.cs 中尝试过,在 LessTransformer.cs 中没有。我收到以下错误“您正在导入无法找到的以 .less 结尾的文件。”:“LESS\\Site.less” 次要问题,但您不应该在导入语句中使用正斜杠吗? 【参考方案1】:

我不明白你为什么要使用自定义转换器。

LESS 规范说,如果您使用以下语法,文件将被自动捆绑:

@import "LESS/Site";

它非常适合我,我不需要任何自定义转换器,只需要标准的无点包。要启用缩小,您需要在 web.config 中进行此设置:

<dotless minifyCss="true" cache="true" web="true" />

我有大约 30 个组件和子组件的导入,输出是一个缩小的文件。

我建议你不要使用样式包,而是直接指向你的 less 文件:

<link href="~/Content/css/main.less" rel="stylesheet" />

dotless http 处理程序将启动,将 less 转换为 css 并将其缓存以供后续请求使用

【讨论】:

啊我实际上在几周前就解决了这个问题,自从开始新工作后我就没有时间回复它。不过感谢您的回复。 @JTGrime 我的答案是正确的吗?您是否以不同的方式解决了您的问题? @MarcoBettiolo 使用这种方法对浏览器缓存有不利影响吗?意思是,如果你不使用缓存键的捆绑更新会有问题? @ctc 我看到了浏览器缓存的一个很好的改进,捆绑会为特定生成的捆绑包生成一个哈希值,只要捆绑包没有改变,密钥就保持不变。如果你不使用缓存键,那么你的浏览器我的缓存样式不对。我建议使用适当的缓存头来缓解这个问题。

以上是关于Site.less' 是物理路径,但应为虚拟路径的主要内容,如果未能解决你的问题,请参考以下文章

C#中网站根路径、应用根路径、物理路径、绝对路径,虚拟路径的区别

Server.MapPath()用法

Server.MapPath是使用

各位大侠,c#中创建目录和文件时的路径问题!!!!!求助!!!!!!!!

XEN创建出VM虚拟机文件物理路径

java.lang.IllegalStateException:应为 BEGIN_ARRAY,但路径为 BEGIN_OBJECT