UplaodPicture not working in modified medium environment

Topics: Developer Forum
Feb 17, 2013 at 4:30 AM
Having implemented the Flickr API in our new website, I am able to display images, browse sets, etc by setting the cache location to a folder in the solution that has read, write, and execute permissions. I cannot, however, get the UploadPicture function to work even though I am setting the cache location to that same folder. The code is as follows:

Flickr.CacheLocation = Server.MapPath("../images/")

f = New Flickr(HttpContext.Current.Application("FlickrApiKey"), HttpContext.Current.Application("FlickrSharedSecret"), HttpContext.Current.Application("FlickrToken"))

...

Dim photoId As String = ""

photoId = f.UploadPicture(CType(plcImage.FindControl("ImageFile"), HtmlInputFile).PostedFile.FileName, CType(plcImage.FindControl("ImageDesc"), TextBox).Text)

The site was developed using vb.net. Everything worked when testing on my local computer, but after uploading it to our host, which is a modified medium trust level cloud environment, I get a "Security Exception" error.

I have been trying different things all day including setting the CacheDisabled property of Flickr to true. Any help would be greatly appreciated!
Coordinator
Feb 20, 2013 at 10:00 AM
From the experiences I've had a security exception in medium trust can happen for one of two reasons:
  1. URL Access - Medium trust by default does not allow you to access external domains. If this is the case then you need to contact your hosting company and try to get this fixes. By you saying it is a 'modified' Medium trust environment I guess they have already allowed access to external domains.
You could test this by simply using the WebClient class to get data from http://api.flickr.com and see if you still get the error.
  1. File Access - You are trying to read or write from somewhere you don't have permission.
Setting Flickr.CacheDisabled = true should stop any such error occurring, because in this case it does not write to the file system at all. However you say you've already tried this and it hasn't solved your problem.

Now there may be other reasons a security exception occurs that I'm not familiar with. Are you using the Release version of the FlickrNet dll which is strongly signed? Can you make other API calls, just not upload ones? Check the values of the filename and description before calling the Upload method. Try opening the image file using a FileStream to ensure the file exists and you have permission to open the uploaded file.

Actually - I've just spotted something - you are using PostedFile.FileName - this is the filename on the Client, not on the Server. Pass the PostedFile.InputStream to the UploadPicture method, rather than the filename.
Feb 20, 2013 at 11:22 PM
Thank you so much for the response. The last lines inspired the solution. What I needed to do was first upload the image to the server and then upload it to Flickr using the API…seems obvious in retrospect, but apparently coding at 2am keeps the obvious painfully out of reach. So, for anyone else out there in a modified medium trust ‘cloud’ environment who would like to upload photos via the Flickr API, try the following steps:

Step 1 – My host provides a sample config file that replicates their environment. Use this sample config for your solution if its provided.

Step 2 – My host recommended that, not only should I disable the cache, but that I should also set up impersonation. This is also done in the web.config using the following code within the <configuration></configuration> tags:
<identity impersonate="true" userName="[YOUR HOSTING USER NAME]" password="[YOUR HOSTING PASSWORD] />
NOTE: Be sure to comment out the impersonate code when testing on your local computer. It may throw an error if you don’t.
<system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>

    <httpProtocol>
      <customHeaders>
        <add name="Cache-Control" value="no-cache" />
      </customHeaders>
    </httpProtocol>

    <security>
      <requestFiltering>
        <requestLimits maxAllowedContentLength="10485760" />
      </requestFiltering>
    </security>
</system.webServer>
NOTE: I also set the maxAllowedContentLength to 10MB because the default was only 4MB and I needed to be able to upload hi-res images that were lager than the default.

STEP 3 – Get your Flickr API Key, Shared Secret, and Token and add the Flickr library to your solution. At this point all should be in order to browse images, sets, etc. Lots of great examples online explaining how to do this.

STEP 4 – To upload images. I used the following code (vb.NET is the language)
Imports FlickrNet

'Begin .aspx page code
Public Class test_uploader

    Inherits System.Web.UI.Page

    Private f As Flickr

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    'Stuff that happens when the page loads goes here
    End Sub

    'Subroutine to handle the click event of the upload button that will
    'upload the file chosen in the HTMLInputFile control of the page.
    Public Sub UploadBut_Click(ByVal sender As Object, ByVal e As System.Web.UI.ImageClickEventArgs)
    'Disable the cache (just to be sure)
    Flickr.CacheDisabled = True

    'Create a new instance of Flickr and set a ridiculous timeout to make
    'sure the file has time to upload
    f = New Flickr([YOUR API KEY], [YOUR SHARED SECRET] , [YOUR TOKEN]) 
    f.HttpTimeout = 10000000

    'If there is something in the HTMLInputFile control try and upload it
    'My HTMLInputFile Control’s ID is ImageFile
    If ImageFile.PostedFile.FileName.ToString <> "" Then
            
        'Get the name of the file and declare a new Flickr Photo
        Dim fn As String = ImageFile.PostedFile.FileName)
        Dim NewPhoto As New Photo

        'Upload the image from you local computer or network to the host
        'server in a directory that has read/write permissions. I created 
        'a folder in images called cache for this purpose. 
        ImageFile.PostedFile.SaveAs(Server.MapPath("images/cache/") & "\" & System.IO.Path.GetFileName(ImageFile.PostedFile.FileName))

        'Upload the image that has just been uploaded to the server to
        'Flickr and save the Id so that you can assign to it a set if needed
        'You can also pass a title and a bunch of other stuff to the 
        'UploadPicture Function as well.
        NewPhoto.PhotoId = f.UploadPicture(Server.MapPath("images/cache/") & fn)

        ‘Delete the file on the host server.
        System.IO.File.Delete(Server.MapPath("../images/cache/") & fn)
    End If
    End Sub
End Class
This worked for me. I hope it helps.