diff --git a/build/NuSpecs/UmbracoCms.Core.nuspec b/build/NuSpecs/UmbracoCms.Core.nuspec
index feb530ce99..2d738475db 100644
--- a/build/NuSpecs/UmbracoCms.Core.nuspec
+++ b/build/NuSpecs/UmbracoCms.Core.nuspec
@@ -28,7 +28,7 @@
-
+
diff --git a/src/Umbraco.Core/IO/FileSystemExtensions.cs b/src/Umbraco.Core/IO/FileSystemExtensions.cs
index f2152afaab..64dcfc25a0 100644
--- a/src/Umbraco.Core/IO/FileSystemExtensions.cs
+++ b/src/Umbraco.Core/IO/FileSystemExtensions.cs
@@ -1,10 +1,42 @@
using System;
using System.IO;
+using System.Threading;
namespace Umbraco.Core.IO
{
public static class FileSystemExtensions
{
+
+ ///
+ /// Attempts to open the file at filePath up to maxRetries times,
+ /// with a thread sleep time of sleepPerRetryInMilliseconds between retries.
+ ///
+ public static FileStream OpenReadWithRetry(this FileInfo file, int maxRetries = 5, int sleepPerRetryInMilliseconds = 50)
+ {
+ var retries = maxRetries;
+
+ while (retries > 0)
+ {
+ try
+ {
+ return File.OpenRead(file.FullName);
+ }
+ catch(IOException)
+ {
+ retries--;
+
+ if (retries == 0)
+ {
+ throw;
+ }
+
+ Thread.Sleep(sleepPerRetryInMilliseconds);
+ }
+ }
+
+ throw new ArgumentException("Retries must be greater than zero");
+ }
+
public static long GetSize(this IFileSystem fs, string path)
{
using (var file = fs.OpenFile(path))
diff --git a/src/Umbraco.Web/Editors/EntityController.cs b/src/Umbraco.Web/Editors/EntityController.cs
index 7cebeb6252..b12d19d032 100644
--- a/src/Umbraco.Web/Editors/EntityController.cs
+++ b/src/Umbraco.Web/Editors/EntityController.cs
@@ -6,6 +6,7 @@ using System.Text;
using System.Web.Http;
using System.Web.Http.ModelBinding;
using AutoMapper;
+using ClientDependency.Core;
using Examine.LuceneEngine;
using Examine.LuceneEngine.Providers;
using Newtonsoft.Json;
@@ -637,15 +638,20 @@ namespace Umbraco.Web.Editors
private IEnumerable GetResultForKeys(IEnumerable keys, UmbracoEntityTypes entityType)
{
- if (keys.Any() == false) return Enumerable.Empty();
+ var keysArray = keys.ToArray();
+ if (keysArray.Any() == false) return Enumerable.Empty();
var objectType = ConvertToObjectType(entityType);
if (objectType.HasValue)
{
- var result = Services.EntityService.GetAll(objectType.Value, keys.ToArray())
+ var entities = Services.EntityService.GetAll(objectType.Value, keysArray)
.WhereNotNull()
.Select(Mapper.Map);
+ // entities are in "some" order, put them back in order
+ var xref = entities.ToDictionary(x => x.Id);
+ var result = keysArray.Select(x => xref.ContainsKey(x) ? xref[x] : null).Where(x => x != null);
+
return result;
}
//now we need to convert the unknown ones
@@ -664,15 +670,20 @@ namespace Umbraco.Web.Editors
private IEnumerable GetResultForIds(IEnumerable ids, UmbracoEntityTypes entityType)
{
- if (ids.Any() == false) return Enumerable.Empty();
+ var idsArray = ids.ToArray();
+ if (idsArray.Any() == false) return Enumerable.Empty();
var objectType = ConvertToObjectType(entityType);
if (objectType.HasValue)
{
- var result = Services.EntityService.GetAll(objectType.Value, ids.ToArray())
+ var entities = Services.EntityService.GetAll(objectType.Value, idsArray)
.WhereNotNull()
.Select(Mapper.Map);
+ // entities are in "some" order, put them back in order
+ var xref = entities.ToDictionary(x => x.Id);
+ var result = idsArray.Select(x => xref.ContainsKey(x) ? xref[x] : null).Where(x => x != null);
+
return result;
}
//now we need to convert the unknown ones
diff --git a/src/Umbraco.Web/Editors/MediaController.cs b/src/Umbraco.Web/Editors/MediaController.cs
index d807d84a26..861750e752 100644
--- a/src/Umbraco.Web/Editors/MediaController.cs
+++ b/src/Umbraco.Web/Editors/MediaController.cs
@@ -32,6 +32,7 @@ using umbraco;
using umbraco.BusinessLogic.Actions;
using Constants = Umbraco.Core.Constants;
using Umbraco.Core.Configuration;
+using Umbraco.Core.Persistence.FaultHandling;
namespace Umbraco.Web.Editors
{
@@ -404,7 +405,11 @@ namespace Umbraco.Web.Editors
var mediaService = ApplicationContext.Services.MediaService;
var f = mediaService.CreateMedia(fileName, parentId, mediaType);
- using (var fs = System.IO.File.OpenRead(file.LocalFileName))
+
+ var fileInfo = new FileInfo(file.LocalFileName);
+ var fs = fileInfo.OpenReadWithRetry();
+ if (fs == null) throw new InvalidOperationException("Could not acquire file stream");
+ using (fs)
{
f.SetValue(Constants.Conventions.Media.File, fileName, fs);
}