Overwrite ASP.NET MVC Active Style Set

I have a stylesheet in the application ~/Content/theme/style.css . It is referenced in my application using standard binding as such:

 bundles.Add(new StyleBundle("~/Content/css").Include( "~/Content/font-awesome/font-awesome.css", "~/Content/theme/style.css")); 

Now I used the Sass compiler (Libsass) so that I can change the style.css output file to a custom output file if necessary.

So basically I'm doing something like this.

 CompilationResult compileResult = SassCompiler.CompileFile(Server.MapPath(Path.Combine(WebConfigSettings.RootSassPath, "style.scss"), options: new CompilationOptions { SourceMap = true, SourceMapFileUrls = true }); 

and then I save it.

 string outputPath = Server.MapPath(WebConfigSettings.ThemeOutputPath); if (System.IO.File.Exists(outputPath)) System.IO.File.Copy(outputPath, string.Format("{0}.bak", outputPath), true); System.IO.File.WriteAllText(Server.MapPath(WebConfigSettings.ThemeOutputPath), compileResult.CompiledContent); 

However, with interruptions, I get the following terrible access error: "The process cannot access the C: .... \ style.css file" because it is being used by another process. " (Note: This happens on the line File.WriteAllText )

This does not make sense, because I do not open any streams in the file and do not perform what I believe is one atomic operation using File.WriteAllText .

Now I also noticed that this error is especially likely when I use two different browsers to modify this file in sequence.

My guess is that one of two things happens.

Or:

a. The package wrapper somehow locks the file because it was changed when it updates the packages and does not release the lock or

b. Since two different connections are accessing the file, somehow the lock is stored in them.

So, does anyone come across something similar? Any suggestions on how I can solve this problem?

PS: I tried using HttpRuntime.UnloadAppDomain(); as a hacker way to try and release any locks in the file, but that doesn't seem to help.

+5
source share
2 answers

The web server itself will receive a lock on the reading of the files (s) when they are being served. So, if you are going to write files at the same time, collisions are inevitable.

Option 1

Writing to disk in a repeat loop and ignoring this exception. Files are likely to be writable in a very short amount of time.

Option 2

Avoid the web server that blocks files by servicing them yourself from the cache.

From this answer :

... if you update these [files] a lot, you really stun the IIS caching mechanisms. And it's not great for a web server to serve files that are constantly changing. The web server works fine in static files.

Now, if your [files] are so dynamic, you might need to serve it through a server program.

Since you mentioned in the comment that your end users are changing files, I would suggest doing the following to make sure there is no lock conflict:

  • Use the action method to serve the contents of the package.
  • By default, read files from disk.
  • When the end user loads the application’s “editing” functionality, load the contents from the file (s) into the cache. Your action method that serves the content should first check this cache, serve it if available, and serve files from disk if not.
  • When the end user saves the content, compiles the content, writes it to disk, and then invalidates the cache. If the user does not save, the cache will eventually be disconnected, and the files will again be read from disk by end users.

See How can I add the result of an ASP.NET MVC controller action to a bundle? for some possible decisions about how to service a package from an action method, I would probably use a solution like this (although the caching strategy might need to be different).

Alternatively, you can reload the cache every time it is empty in the user request, and update both the files and the cache during the save operation, which will probably be simpler and will reduce the likelihood of file locking errors to zero, but also will not scale up.

+1
source

When one page is displayed in the browser, then the optimizer processes the associated css and jqueries in caching. Therefore, as soon as the page is cashed out, one page will reflash the browser, first check the contents of the cached page, if it is not present, then only it will call the service. There are only two solutions for your question: less or sass type of css usage.

0
source

Source: https://habr.com/ru/post/1271929/


All Articles