Is it possible to put resource files (.resx) within subfolders inside App_GlobalResources?
For example:
/App_GlobalResources/someresources/myfile.resx
/App_GlobalResources/someresources/myfile.fr-fr.resx
/App_GlobalResources/othereresources/otherfile.resx
/App_GlobalResources/othereresources/otherfile.fr-fr.resx
Or, are all the .resx files placed directly inside App_GlobalResources?
If it is possible to use subfolders, how do you programmatically access resources within subfolders?
Technically, yes it is possible but there are some pitfalls. First, let me show you an example. Suppose my App_GlobalResources folder looks like so:
/App_GlobalResources
/Test
TestSubresource.resx
TestResource.resx
Each resource file has a single entry called "TestString". I added each resource file using the Visual Studio menu so it created a class for me. By default, all classes added to the App_GlobalResources folder will have the same namespace of Resource. So, if I want to use the class generator and I want Test in the namespace, I need to go into the TestSubresource.Designer.cs file and manually change the namespace. Once I do that, I can do the following:
var rootResource = Resources.TestResource.TestString;
var subResource = Resources.Test.TestSubResource.TestString;
I can also reference them using GetGlobalResourceObject:
var rootResource = GetGlobalResourceObject( "TestResource", "TestString" );
var subResource1 = GetGlobalResourceObject( "TestSubresource", "TestString" );
Notice that I still use the "TestSubresource" as the means to reference the resources in that file even though it is in a subfolder. Now, one of the catches, is that all the files must be unique across all folders in App_GlobalResources or your project will throw a runtime error. If I add a resource named "TestResource.resx" to /Test, it will throw the following runtime error:
The resource file '/App_GlobalResources/TestResource.resx' cannot be
used, as it conflicts with another file with the same name.).
This is true even if I change the namespace on the new resource.
So, in conclusion, yes it is possible, but you increase the odds of getting a runtime error because of two identically named resource files in different parts of the App_GlobalResources folder structure which is allowed by the file system but not by .NET.
It's possible. At least, I managed to do it.
Within a web site I added the App_GlobalResources folder. Inside it I created another folder "MyFolder" and placed MyResource.resx file inside. Resx file contained one pair MyKey1 - MyValue1.
Using the GetResource method of the following class I successfully extracted "MyValue1" for name="MyKey1"
static class Class1 {
static Assembly FindGlobalResAssembly() {
foreach(Assembly asm in AppDomain.CurrentDomain.GetAssemblies()) {
if(asm.FullName.StartsWith("App_GlobalResources."))
return asm;
}
return null;
}
public static object GetResource(string name) {
Assembly asm = FindGlobalResAssembly();
if(asm == null)
return null;
return new ResourceManager("Resources.MyResource", asm).GetObject(name);
}
}
This approach works in Medium trust also.
It seems that folders make no difference when accessing resources from code.
Related
I want to load the .plist files and store in com.webobjects.foundation.NSDictionary variable.
The piece of code which was earlier
private NSDictionary variable;
try{
variable = OWWOFileUtilities.loadConfigFile("xxxxx.plist", null);
}
variable.objectforkey("string");
Now the OWWOFileUtilities is not used anymore, So I want the alternate way to load the .plist into my project
See,
com.webobjects.foundation.NSPropertyListSerialization.dictionaryForString(String value)
Apache configuration classes also support loading plists.
I am working on Nginx server, with PHP-FPM. I installed Laravel 4.1 and bootstrap v3.1.1., and here is the problem. For the last 30 minutes, I have been trying to change a css rule that I first declared to check boostrap.
.jumbotron{
background: red;
}
The first time it worked. The jumbotron container was red. So, I removed that css value and started working, but still no matter which browse I use, the container is red. I even checked the css file through the Google Chromes inspection tool, and it is showing me that first value when jumbotron had a background:red. I deleted the css file and renamed it and add new styles, I configured chrome not to cache pages. But Still the same value. I'm convinced now, that Laravel has kept a cache of the first style declaration.
Is there any way to disable this at all?
General explanation
When you access a Laravel Blade view, it will generate it to a temporary file so it doesn't have to process the Blade syntax every time you access to a view. These files are stored in app/storage/view with a filename that is the MD5 hash of the file path.
Usually when you change a view, Laravel regenerate these files automatically at the next view access and everything goes on. This is done by comparing the modification times of the generated file and the view's source file through the filemtime() function. Probably in your case there was a problem and the temporary file wasn't regenerated. In this case, you have to delete these files, so they can be regenerated. It doesn't harm anything, because they are autogenerated from your views and can be regenerated anytime. They are only for cache purposes.
Normally, they should be refreshed automatically, but you can delete these files anytime if they get stuck and you have problems like these, but as I said these should be just rare exceptions.
Code break down
All the following codes are from laravel/framerok/src/Illuminate/View/. I added some extra comments to the originals.
Get view
Starting from Engines/CompilerEngine.php we have the main code we need to understand the mechanics.
public function get($path, array $data = array())
{
// Push the path to the stack of the last compiled templates.
$this->lastCompiled[] = $path;
// If this given view has expired, which means it has simply been edited since
// it was last compiled, we will re-compile the views so we can evaluate a
// fresh copy of the view. We'll pass the compiler the path of the view.
if ($this->compiler->isExpired($path))
{
$this->compiler->compile($path);
}
// Return the MD5 hash of the path concatenated
// to the app's view storage folder path.
$compiled = $this->compiler->getCompiledPath($path);
// Once we have the path to the compiled file, we will evaluate the paths with
// typical PHP just like any other templates. We also keep a stack of views
// which have been rendered for right exception messages to be generated.
$results = $this->evaluatePath($compiled, $data);
// Remove last compiled path.
array_pop($this->lastCompiled);
return $results;
}
Check if regeneration required
This will be done in Compilers/Compiler.php. This is an important function. Depending on the result it will be decided whether the view should be recompiled. If this returns false instead of true that can be a reason for views not being regenerated.
public function isExpired($path)
{
$compiled = $this->getCompiledPath($path);
// If the compiled file doesn't exist we will indicate that the view is expired
// so that it can be re-compiled. Else, we will verify the last modification
// of the views is less than the modification times of the compiled views.
if ( ! $this->cachePath || ! $this->files->exists($compiled))
{
return true;
}
$lastModified = $this->files->lastModified($path);
return $lastModified >= $this->files->lastModified($compiled);
}
Regenerate view
If the view is expired it will be regenerated. In Compilers\BladeCompiler.php we see that the compiler will loop through all Blade keywords and finally give back a string that contains the compiled PHP code. Then it will check if the view storage path is set and save the file there with a filename that is the MD5 hash of the view's filename.
public function compile($path)
{
$contents = $this->compileString($this->files->get($path));
if ( ! is_null($this->cachePath))
{
$this->files->put($this->getCompiledPath($path), $contents);
}
}
Evaluate
Finally in Engines/PhpEngine.php the view is evaluated. It imports the data passed to the view with extract() and include the file with the passed path in a try and catch all exceptions with handleViewException() that throws the exception again. There are some output buffering too.
Same issue here. I am using VirtualBox with Shared Folders pointing to my document root.
This pointed me in the right direction:
https://stackoverflow.com/a/26583609/1036602
Which led me to this:
http://www.danhart.co.uk/blog/vagrant-virtualbox-modified-files-not-updating-via-nginx-apache
and this:
https://forums.virtualbox.org/viewtopic.php?f=1&t=24905
If you're mounting your local dev root via vboxsf Shared Folders, set EnableSendFile Off in your apache2.conf (or sendfile off if using Nginx).
For what it's worth and because this answer came up first in my google search...
I had the same problem. The CSS and JS files wouldn't update. Deleting the cache files didn't work. The timestamps were not the problem. The only way I could update them was to change the filename, load it directly to get the 404 error, and then change the name back to the original name.
In the end the problem was not related to Laravel or the browser cache at all. The problem was due to NginX using sendfile which doesn't work with remote file systems. In my case, I was using VirtualBox for the OS and the remote file system was vboxsf through Guest Additions.
I hope this saves someone else some time.
In Laravel 5.8+ you can use so:
The version method will automatically append a unique hash to the filenames of all compiled files, allowing for more convenient cache busting:
mix.js('resources/js/app.js', 'public/js').version();
After generating the versioned file, you won't know the exact file name. So, you should use Laravel's global mix function within your views to load the appropriately hashed asset. The mix function will automatically determine the current name of the hashed file:
<script src="{{ mix('/js/app.js') }}"></script>
full document: https://laravel.com/docs/5.8/mix
When users upload an image, it is stored in the file system but outside of what is publicly reachable.
I am displaying a list of items, and each item has an image associated with it.
How can I display the image when the actual file is stored outside of the wwwroot folder? i.e. it isn't publicly available.
Since the action method is running on the server, it can access any file it has permission to. The file does not need to be within the wwwroot folder. You simply need to tell the action method which image to get.
For instance:
<img src="/mycontroller/myaction/123">
Your action would then look like:
public FileResult MyAction(int id)
{
var dir = "c:\myimages\";
var path = Path.Combine(dir, id + ".jpg");
return new FileStreamResult(new FileStream(path, FileMode.Open), "image/jpeg");
}
Please note that the id is an int which will prevent someone from injecting a path to access different files on the drive/share.
You could do this two ways.
Option 1, you could create a Virtual directory which points to this other Directory. This would then mean that you could access the images via another URL. e.g. Create a Virtual Directory called "OtherImages", then your URL would be;
http://www.mywebsite.com/otherimages/myimage.jpg
Option 2, you could create a simple HttpHandler which can load up the image from the absolute path, then output this in the response. Read up on HttpHandlers and dynamically generating images.
I have 2 different project. One is supposed to upload images (admin) and the other is supposed to show them.
I was writing something like "/Contents/images/image path"... But wait! I will I upload the images from the application into that address?
Any help and suggestions please.
If you have two applications that will interact with the same files, it's probably better to have an ImageController with an action that allows you to upload/download the image rather than storing them directly as content. That way both applications can reference the same file location or images stored in a database and manipulate them. Your download action would simply use a FileContentResult to deliver the bytes from the file. You can derive the content type from the file extension.
Example using a database. Note that I assume that the database table contains the content type as determined at upload time. You could also use a hybrid approach that stores the image metadata in a database and loads the actual file from a file store.
public class ImageController : Controller
{
public ActionResult Get( int id )
{
var context = new MyDataContext();
var image = context.Images.SingleOrDefault( i => i.ID == id );
if (image != null)
{
return File( image.Content, image.ContentType );
}
// or you could return a placeholder image here if appropriate.
throw new HttpException( 404, "The image does not exist" );
}
}
An alternative would be to incorporate your administrative interface in an area of the same application rather than in a separate project. This way you could reuse the content/images directory if you wanted. I find that when you have dynamic images the database or a hybrid approach works better from a programming perspective since it's more consistent with the rest of your data model.
you could try like this..
Let's assume that all of your images are in Project A and you want to use the same images in Project B.
Open Project B with Visual Studio. In the Solution Explorer, right click your Project Name and select "Add Existing Item...".
Browse to the physical location on disc where your images in Project A are stored and select the files that you want to import.
You'll then be able to access those images from project A in Project B.
I have a asp.net website that has the following directory:
C:\Users\Desktop\Testing\src\website
I have another folder called "files" that is here:
C:\Users\Desktop\Testing\src\files
from inside my project i am trying to read files from the "files" folder, i am doing it like this:
var path = HttpContext.Current.Server.MapPath("/files");
I also tried :
var path = HttpContext.Current.Server.MapPath("..");
But it says Failed to map the path '/files'.
What could be the reason for this? could it do something with my IIS? How can i get this working??
Thank you!
You can't do this. The Server.MapPath method only works with folders relative to the root of the web application which in your case is C:\Users\Desktop\Testing\src\website. You cannot go one level up in the hierarchy using this method as you are leaving the domain of control of this ASP.NET application. To achieve this you will have to use an absolute path. For example if you want to read some file which is situated outside of your application:
var data = File.ReadAllText(#"C:\Users\Desktop\Testing\src\files\somefile.txt");
assuming the websites's virtual directory is mapped to .../src/website you need to get "files" folder like this:
var filesDir = Path.Combine(HttpContext.Current.Server.MapPath("~"), "../files/");