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.
Related
I have two Resource files under the app_GlobalResources folder in my Website project, (CaptionsA.resx and CaptionsB.resx), for CustomerA and CustomerB,respectively.
For example, in CaptionsA.resx, I have:
MyButtonText ------> Click me!
And in CaptionsB.resx, I have:
MyButtonText ------> Click Here
I have to use captions on multiple pages in my Website. But, when CustomerA uses the website all the captions from CaptionsA.resx should be visible and when CustomerB uses the website all the captions from CaptionsB.resx should be visible. Keep in mind that both customers use English as the website language, So I can't use the culture/language localization thingy.
What I want to ask is:
How to programmatically tell my website which Resource file to use when?
What to write in my VB.net code?
How to access the Resource File in my code?
If CustomerType = CustomerA
//RETRIEVE DATA FROM CaptionsA.resx (How to do this?)
else If CustomerType = CustomerB
//RETRIEVE DATA FROM CaptionsB.resx (How to do this?)
And what shall I write in the aspx source file?
<asp:Label ID="LblButtonText" runat="server" Text="<%$ Resources:**WHAT-TO-WRITE-HERE?**,MyButtonText %>"></asp:Label>
I have been searching a lot and have tried to find the answer on a gazillion forums, but threads related to this topic were mostly unanswered or were not helpful.
here is how you do it..
Dim resourceFileBaseName As String = "WebApplicationNamespace.app_GlobalResources.CaptionsA"
Dim isCustomerB As Boolean = True
If isCustomerB Then
resourceFileBaseName = "WebApplicationNamespace.app_GlobalResources.CaptionsB"
End If
Dim customerBasedResourceManager = New System.Resources.ResourceManager(resourceFileBaseName, GetType(CaptionsA).Assembly)
Dim resourceManagerField = GetType(CaptionsA).GetField("resourceMan", BindingFlags.[Static] Or BindingFlags.NonPublic)
resourceManagerField.SetValue(Nothing, customerBasedResourceManager)
All ResX files generate an equivalent class (e.g. CaptionsA) which have an underlying ResourceManager which points to the CaptionsA resource containing all the strings. Based on the customer type, we can make this resource manager point to the right underlying resx file. but this Resource Manager is internal to the class, hence we need to reflect and set the value. Also, the CaptionsA and CaptionsB have no relation to each other, otherwise we could have leveraged some pattern/casting to access their members.
what we're doing in the above code is:
set the right resource file base name based on the customer type. (ensure you're using the right namespace path for the classes)
create a custom resourcemanager which points to our actual resx file.
set the CaptionsA class' resourcemanager to our custom one by reflection.
now whenever you try to access a resource, based on the underlying resx it'll access captionsA.resx or CaptionsB.resx.
one thing you'll notice is that you'll be accessing resources of CaptionsB.resx too via CaptionsA class. this is unavoidable and is the closest to the culture based seamless resource access we can get via non-culture based varying resources.
for the fun of it, here is the C# code as well.
string resourceFileBaseName = "WebApplicationNamespace.app_GlobalResources.CaptionsA";
bool isCustomerB = true;
if (isCustomerB)
{
resourceFileBaseName = "WebApplicationNamespace.app_GlobalResources.CaptionsB";
}
var customerBasedResourceManager = new System.Resources.ResourceManager(resourceFileBaseName,
typeof(CaptionsA).Assembly);
var resourceManagerField = typeof(CaptionsA).GetField("resourceMan", BindingFlags.Static | BindingFlags.NonPublic);
resourceManagerField.SetValue(null, customerBasedResourceManager);
CaptionsA.MyButtonText will point to the value based on the customer type's resx file.
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'm writing a little blog app where the user can publish public and private news. Users can attach files to these news. I have two contexts for this app: public_news, with files which can be accessed by everyone; and private_news, with files which can only be accessed if the user has log on.
I want to be able to move files from the public_news context to the private_news context when the user changes a news from public to private, and vice versa.
I was hoping to do something as simple as $media->setContext('private_news');, but this won't move the physical file from one directory to the other.
What do you think about recreating this media?
$oldMedia = getYourOldMedia();
// $media = clone($oldMedia); # For me it didn't work as expected
# YMMV - I didn't spend lots wondering about that
$media = new Media();
// This will work fine with image and file provider,
// but it was not tested with other providers
$pool = $container->get('sonata.media.pool');
$provider = $pool->getProvider($oldMedia->getProviderName());
$media->setBinaryContent($provider->getReferenceFile($oldMedia));
}
$media->setProviderName($oldMedia->getProviderName());
$media->setContext('private_news');
/* copy any other data you're interested in */
$mediaManager->save($media);
$mediaManager->delete($oldMedia);
$mediaManager->delete might not delete your physical files depending on provider, you might want to create your own provider if you wish to do so.
Edit:
On further research I found out that you can manualy delete your files before deleting old media:
if ($pool->getFilesystem()->has($path)) {
$pool->getFilesystem()->delete($path);
}
But don't do that before saving your new media entity.
I'm developing an ASP.NET webapp that has a multilanguage feature allowing the webmaster to create new languages at runtime.
The approach that I was thinking is the following:
The user selects one available (not created) language.
When the user confirms, the application automatically copies a set of existing resources, replacing the filename with the new culture. For example: default.aspx.en-us.resx to default.aspx.es-ar.resx.
The user edits the recently created resources.
Currently I'm having troubles with step number 2. I've achieved to copy the resources, but then these new resources are ignored. I think that this happens because the new resources are not included in the running assembly, and therefore are being ignored.
When I test the following code in my local project, I would have to manually add the new resources to the solution and then recompile to make it work.
Does anyone know how to make this work?
This is the code of the mentioned copy.
string _dir = path_ + "App_LocalResources\\\\";
DirectoryInfo _dirInfo = new DirectoryInfo(_dir);
foreach (FileInfo _file in _dirInfo.GetFiles("*en-us.resx")) {
_file.CopyTo(_dir + _file.Name.Replace("en-us", idioma_.Cultura));
}
string _dir2 = path_ + "App_GlobalResources\\\\";
_dirInfo = new DirectoryInfo(_dir2);
foreach (FileInfo _file in _dirInfo.GetFiles("*en-us.resx")) {
_file.CopyTo(_dir2 + _file.Name.Replace("en-us", idioma_.Cultura));
}
Thank you very much.
Creating or editing Resource files is not possible the same way as reading data.
In order to create or edit a resource file, you should do it the same way you create or edit XML files because resource files have with a specific structured XML elements.
Maybe this article will help you...
I'm trying to import nodes from my forum to drupal 7. Not in bulk, but one by one so that news posts can be created and referenced back to the forum. The kicker is that I'm wanting to bring image attachments across as well...
So far, using the code example here http://drupal.org/node/889058#comment-3709802 things mostly work: Nodes are created, but the images don't go through any validation or processing.
I'd like the attached images to be validated against the rules defined in the content type. in particular the style associated with my image field which resizes them to 600x600.
So, instead of simply creating the nodes programatically with my own form, i decided to modify a "new" node using hook_node_prepare and using the existing form to create new content (based on passed in url args). This works really well and a create form is presented pre-filled with all my data. including the image! very cute.
I expected that i could then hit preview or save and all the validation and resizing would happen to my image, but instead i get the error:
"The file used in the Image field may not be referenced."
The reason for this is that my file doesn't have an entry in the file_usage table.. *le sigh*
so, how do i get to all the nice validation and processing which happens when i manually choose a file to upload? like resizing, an entry in the file_usage table.
The ajax upload function does it, but i can't find the code which is called to do this anywhere in the api.
What file upload / validation functions does Drupal call which i'm not doing?
Anybody have any experience with the file/image api for Drupal 7 who can help me out?
For getting the usage entry (in essence, checking out a file to a specific module so that it doesn't get deleted while its in use) look up the Drupal function 'file_usage_add()'
For validating incoming images, I got this example from user.module (if you're comfortable with PHP, you can always look at the core to see how something is done the 'Drupal way'):
function user_validate_picture(&$form, &$form_state) {
// If required, validate the uploaded picture.
$validators = array(
'file_validate_is_image' => array(),
'file_validate_image_resolution' => array(variable_get('user_picture_dimensions', '85x85')),
'file_validate_size' => array(variable_get('user_picture_file_size', '30') * 1024),
);
// Save the file as a temporary file.
$file = file_save_upload('picture_upload', $validators);
if ($file === FALSE) {
form_set_error('picture_upload', t("Failed to upload the picture image; the %directory directory doesn't exist or is not writable.", array('%directory' => variable_get('user_picture_path', 'pictures'))));
}
elseif ($file !== NULL) {
$form_state['values']['picture_upload'] = $file;
}
}
That function is added to the $form['#validate'] array like so:
$form['#validate'][] = 'user_validate_picture'