diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs
index ec9ecb9ef2..958188f37a 100644
--- a/MediaBrowser.Dlna/DlnaManager.cs
+++ b/MediaBrowser.Dlna/DlnaManager.cs
@@ -20,13 +20,15 @@ namespace MediaBrowser.Dlna
private readonly IXmlSerializer _xmlSerializer;
private readonly IFileSystem _fileSystem;
private readonly ILogger _logger;
+ private readonly IJsonSerializer _jsonSerializer;
- public DlnaManager(IXmlSerializer xmlSerializer, IFileSystem fileSystem, IApplicationPaths appPaths, ILogger logger)
+ public DlnaManager(IXmlSerializer xmlSerializer, IFileSystem fileSystem, IApplicationPaths appPaths, ILogger logger, IJsonSerializer jsonSerializer)
{
_xmlSerializer = xmlSerializer;
_fileSystem = fileSystem;
_appPaths = appPaths;
_logger = logger;
+ _jsonSerializer = jsonSerializer;
//DumpProfiles();
}
@@ -381,10 +383,66 @@ namespace MediaBrowser.Dlna
public void CreateProfile(DeviceProfile profile)
{
+ profile = ReserializeProfile(profile);
+
+ if (string.IsNullOrWhiteSpace(profile.Name))
+ {
+ throw new ArgumentException("Profile is missing Name");
+ }
+
+ var newFilename = _fileSystem.GetValidFilename(profile.Name) + ".xml";
+ var path = Path.Combine(UserProfilesPath, newFilename);
+
+ _xmlSerializer.SerializeToFile(profile, path);
}
public void UpdateProfile(DeviceProfile profile)
{
+ profile = ReserializeProfile(profile);
+
+ if (string.IsNullOrWhiteSpace(profile.Id))
+ {
+ throw new ArgumentException("Profile is missing Id");
+ }
+ if (string.IsNullOrWhiteSpace(profile.Name))
+ {
+ throw new ArgumentException("Profile is missing Name");
+ }
+
+ var current = GetProfileInfosInternal().First(i => string.Equals(i.Info.Id, profile.Id, StringComparison.OrdinalIgnoreCase));
+
+ if (current.Info.Type == DeviceProfileType.System)
+ {
+ throw new ArgumentException("System profiles are readonly");
+ }
+
+ var newFilename = _fileSystem.GetValidFilename(profile.Name) + ".xml";
+ var path = Path.Combine(UserProfilesPath, newFilename);
+
+ if (!string.Equals(path, current.Path, StringComparison.Ordinal))
+ {
+ File.Delete(current.Path);
+ }
+
+ _xmlSerializer.SerializeToFile(profile, path);
+ }
+
+ ///
+ /// Recreates the object using serialization, to ensure it's not a subclass.
+ /// If it's a subclass it may not serlialize properly to xml (different root element tag name)
+ ///
+ ///
+ ///
+ private DeviceProfile ReserializeProfile(DeviceProfile profile)
+ {
+ if (profile.GetType() == typeof(DeviceProfile))
+ {
+ return profile;
+ }
+
+ var json = _jsonSerializer.SerializeToString(profile);
+
+ return _jsonSerializer.DeserializeFromString(json);
}
class InternalProfileInfo
diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs
index b7e9017d6e..d9d5e007e8 100644
--- a/MediaBrowser.ServerApplication/ApplicationHost.cs
+++ b/MediaBrowser.ServerApplication/ApplicationHost.cs
@@ -503,7 +503,7 @@ namespace MediaBrowser.ServerApplication
var appThemeManager = new AppThemeManager(ApplicationPaths, FileSystemManager, JsonSerializer, Logger);
RegisterSingleInstance(appThemeManager);
- var dlnaManager = new DlnaManager(XmlSerializer, FileSystemManager, ApplicationPaths, LogManager.GetLogger("DLNA"));
+ var dlnaManager = new DlnaManager(XmlSerializer, FileSystemManager, ApplicationPaths, LogManager.GetLogger("DLNA"), JsonSerializer);
RegisterSingleInstance(dlnaManager);
var collectionManager = new CollectionManager(LibraryManager, FileSystemManager, LibraryMonitor);