/// <summary>
        /// Saves files in a MMMM/yyyy/{Guid} structure for observation images, to avoid
        /// a single directory being filled over time.
        /// </summary>
        /// <param name="observation">The observation to save the file path against</param>
        /// <param name="postedFile">A posted file to save</param>
        /// <returns>
        /// the relative path of the file for storage in the database. We do not want
        /// to store the full virtual path so that the files can easily
        /// be migrated elsewhere without having to update the database.
        /// </returns>

        private void SaveFile(DataLayer.Models.Observation observation, HttpPostedFileBase postedFile)
        {
            if (postedFile != null)
            {
                HttpServerUtility server = HttpContext.Current.Server;

                //Use the relative path provided if we already have one, so that we can overwrite
                //the existing upload.

                if (string.IsNullOrWhiteSpace(observation.FilePath))
                {
                    // - {Guid}.jpg
                    string filename = Guid.NewGuid() + Path.GetExtension(postedFile.FileName);

                    // - C:/.../Uploads/
                    var uploadFolder = new DirectoryInfo(server.MapPath(ObservationVirtualDirectory));

                    // - "2012/Feb"
                    string directoryRelativePath = CreateUploadDirectory(uploadFolder.FullName);

                    // - "2012/Feb/{Guid}.jpg"
                    observation.FilePath = UrlUtilities.Combine(directoryRelativePath, filename);
                }

                // - "~/Uploads/2012/Feb/{GUID}.xxx"
                string virtualFilePath = VirtualPathUtility.Combine(ObservationVirtualDirectory, observation.FilePath);

                // - Save the file
                postedFile.SaveAs(server.MapPath(virtualFilePath));
            }
        }
 private static async Task <HttpResponseMessage> Run(HttpRequest req, ILogger log, ExecutionContext ec, string version)
 {
     return(await SafeExecutor.Execute(async() =>
     {
         var cnfg = ConfigUtilities.LoadConfiguration();
         var graphRequestUrl = UrlUtilities.Combine(cnfg.GraphBaseUrl, req.Path, req.QueryString.ToString());
         var authProvider = FunctionUtilities.GetAuthenticationProvider(req, cnfg);
         var graphClient = GraphUtilities.GetAuthenticatedClient(cnfg.GraphBaseUrl, version, authProvider);
         var graphResponse = await GraphUtilities.ExecuteGetRequest(graphClient, graphRequestUrl);
         return await FunctionUtilities.TransformResponse(req.GetHostUrl(), cnfg.GraphBaseUrl, graphResponse);
     }, req, log));
 }
        /// <summary>
        /// Gets a fully qualified URL for the observation image.
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>

        public static string GetAbsoluteUrl(string filePath)
        {
            string virtualPath = GetVirtualPath(filePath);

            if (!string.IsNullOrEmpty(virtualPath))
            {
                string absolutePath = VirtualPathUtility.ToAbsolute(virtualPath, "/");
                return(UrlUtilities.Combine(SiteRootUrl, absolutePath));
            }

            return(null);
        }