Got media saving now.

Signed-off-by: Shannon <sdeminick@gmail.com>
This commit is contained in:
Shannon
2013-06-11 01:56:30 +02:00
committed by Shannon
parent 4bf09089e6
commit 3fee64d6eb
15 changed files with 348 additions and 313 deletions

View File

@@ -27,46 +27,7 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
}
/** internal method process the saving of data and post processing the result */
function saveContentItem(content, action, files) {
var deferred = $q.defer();
//save the active tab id so we can set it when the data is returned.
var activeTab = _.find(content.tabs, function(item) {
return item.active;
});
var activeTabIndex = (activeTab === undefined ? 0 : _.indexOf(content.tabs, activeTab));
//save the data
umbRequestHelper.postMultiPartRequest(
getSaveUrl(content.id),
{ key: "contentItem", value: umbDataFormatter.formatContentPostData(content, action) },
function (data, formData) {
//now add all of the assigned files
for (var f in files) {
//each item has a property id and the file object, we'll ensure that the id is suffixed to the key
// so we know which property it belongs to on the server side
formData.append("file_" + files[f].id, files[f].file);
}
},
function (data, status, headers, config) {
//success callback
//reset the tabs and set the active one
_.each(data.tabs, function (item) {
item.active = false;
});
data.tabs[activeTabIndex].active = true;
//the data returned is the up-to-date data so the UI will refresh
deferred.resolve(data);
},
function (data, status, headers, config) {
//failure callback
deferred.reject('Failed to publish data for content id ' + content.id);
});
return deferred.promise;
return umbRequestHelper.postSaveContent(getSaveUrl(content.id), content, action, files);
}
return {
@@ -238,7 +199,7 @@ angular.module('umbraco.resources').factory('contentTypeResource', contentTypeRe
* @name umbraco.resources.treeResource
* @description Loads in data for trees
**/
function mediaResource($q, $http) {
function mediaResource($q, $http, umbDataFormatter, umbRequestHelper) {
/** internal method to get the api url */
function getMediaUrl(contentId) {
@@ -261,46 +222,7 @@ function mediaResource($q, $http) {
/** internal method process the saving of data and post processing the result */
function saveMediaItem(content, action, files) {
var deferred = $q.defer();
//save the active tab id so we can set it when the data is returned.
var activeTab = _.find(content.tabs, function (item) {
return item.active;
});
var activeTabIndex = (activeTab === undefined ? 0 : _.indexOf(content.tabs, activeTab));
//save the data
umbRequestHelper.postMultiPartRequest(
getSaveUrl(content.id),
{ key: "mediaItem", value: umbDataFormatter.formatContentPostData(content, action) },
function (data, formData) {
//now add all of the assigned files
for (var f in files) {
//each item has a property id and the file object, we'll ensure that the id is suffixed to the key
// so we know which property it belongs to on the server side
formData.append("file_" + files[f].id, files[f].file);
}
},
function (data, status, headers, config) {
//success callback
//reset the tabs and set the active one
_.each(data.tabs, function (item) {
item.active = false;
});
data.tabs[activeTabIndex].active = true;
//the data returned is the up-to-date data so the UI will refresh
deferred.resolve(data);
},
function (data, status, headers, config) {
//failure callback
deferred.reject('Failed to save data for media id ' + content.id);
});
return deferred.promise;
return umbRequestHelper.postSaveContent(getSaveUrl(content.id), content, action, files);
}
return {

View File

@@ -590,8 +590,52 @@ angular.module('umbraco.services')
* @name umbraco.services:umbRequestHelper
* @description A helper object used for sending requests to the server
**/
function umbRequestHelper($http) {
function umbRequestHelper($http, $q, umbDataFormatter) {
return {
postSaveContent: function (restApiUrl, content, action, files) {
var deferred = $q.defer();
//save the active tab id so we can set it when the data is returned.
var activeTab = _.find(content.tabs, function (item) {
return item.active;
});
var activeTabIndex = (activeTab === undefined ? 0 : _.indexOf(content.tabs, activeTab));
//save the data
this.postMultiPartRequest(
restApiUrl,
{ key: "contentItem", value: umbDataFormatter.formatContentPostData(content, action) },
function (data, formData) {
//now add all of the assigned files
for (var f in files) {
//each item has a property id and the file object, we'll ensure that the id is suffixed to the key
// so we know which property it belongs to on the server side
formData.append("file_" + files[f].id, files[f].file);
}
},
function (data, status, headers, config) {
//success callback
//reset the tabs and set the active one
_.each(data.tabs, function (item) {
item.active = false;
});
data.tabs[activeTabIndex].active = true;
//the data returned is the up-to-date data so the UI will refresh
deferred.resolve(data);
},
function (data, status, headers, config) {
//failure callback
deferred.reject('Failed to save data for media id ' + content.id);
});
return deferred.promise;
},
/** Posts a multi-part mime request to the server */
postMultiPartRequest: function (url, jsonData, transformCallback, successCallback, failureCallback) {

View File

@@ -19,46 +19,7 @@ function contentResource($q, $http, umbDataFormatter, umbRequestHelper) {
}
/** internal method process the saving of data and post processing the result */
function saveContentItem(content, action, files) {
var deferred = $q.defer();
//save the active tab id so we can set it when the data is returned.
var activeTab = _.find(content.tabs, function(item) {
return item.active;
});
var activeTabIndex = (activeTab === undefined ? 0 : _.indexOf(content.tabs, activeTab));
//save the data
umbRequestHelper.postMultiPartRequest(
getSaveUrl(content.id),
{ key: "contentItem", value: umbDataFormatter.formatContentPostData(content, action) },
function (data, formData) {
//now add all of the assigned files
for (var f in files) {
//each item has a property id and the file object, we'll ensure that the id is suffixed to the key
// so we know which property it belongs to on the server side
formData.append("file_" + files[f].id, files[f].file);
}
},
function (data, status, headers, config) {
//success callback
//reset the tabs and set the active one
_.each(data.tabs, function (item) {
item.active = false;
});
data.tabs[activeTabIndex].active = true;
//the data returned is the up-to-date data so the UI will refresh
deferred.resolve(data);
},
function (data, status, headers, config) {
//failure callback
deferred.reject('Failed to publish data for content id ' + content.id);
});
return deferred.promise;
return umbRequestHelper.postSaveContent(getSaveUrl(content.id), content, action, files);
}
return {

View File

@@ -3,7 +3,7 @@
* @name umbraco.resources.treeResource
* @description Loads in data for trees
**/
function mediaResource($q, $http) {
function mediaResource($q, $http, umbDataFormatter, umbRequestHelper) {
/** internal method to get the api url */
function getMediaUrl(contentId) {
@@ -26,46 +26,7 @@ function mediaResource($q, $http) {
/** internal method process the saving of data and post processing the result */
function saveMediaItem(content, action, files) {
var deferred = $q.defer();
//save the active tab id so we can set it when the data is returned.
var activeTab = _.find(content.tabs, function (item) {
return item.active;
});
var activeTabIndex = (activeTab === undefined ? 0 : _.indexOf(content.tabs, activeTab));
//save the data
umbRequestHelper.postMultiPartRequest(
getSaveUrl(content.id),
{ key: "mediaItem", value: umbDataFormatter.formatContentPostData(content, action) },
function (data, formData) {
//now add all of the assigned files
for (var f in files) {
//each item has a property id and the file object, we'll ensure that the id is suffixed to the key
// so we know which property it belongs to on the server side
formData.append("file_" + files[f].id, files[f].file);
}
},
function (data, status, headers, config) {
//success callback
//reset the tabs and set the active one
_.each(data.tabs, function (item) {
item.active = false;
});
data.tabs[activeTabIndex].active = true;
//the data returned is the up-to-date data so the UI will refresh
deferred.resolve(data);
},
function (data, status, headers, config) {
//failure callback
deferred.reject('Failed to save data for media id ' + content.id);
});
return deferred.promise;
return umbRequestHelper.postSaveContent(getSaveUrl(content.id), content, action, files);
}
return {

View File

@@ -5,8 +5,52 @@
* @name umbraco.services:umbRequestHelper
* @description A helper object used for sending requests to the server
**/
function umbRequestHelper($http) {
function umbRequestHelper($http, $q, umbDataFormatter) {
return {
postSaveContent: function (restApiUrl, content, action, files) {
var deferred = $q.defer();
//save the active tab id so we can set it when the data is returned.
var activeTab = _.find(content.tabs, function (item) {
return item.active;
});
var activeTabIndex = (activeTab === undefined ? 0 : _.indexOf(content.tabs, activeTab));
//save the data
this.postMultiPartRequest(
restApiUrl,
{ key: "contentItem", value: umbDataFormatter.formatContentPostData(content, action) },
function (data, formData) {
//now add all of the assigned files
for (var f in files) {
//each item has a property id and the file object, we'll ensure that the id is suffixed to the key
// so we know which property it belongs to on the server side
formData.append("file_" + files[f].id, files[f].file);
}
},
function (data, status, headers, config) {
//success callback
//reset the tabs and set the active one
_.each(data.tabs, function (item) {
item.active = false;
});
data.tabs[activeTabIndex].active = true;
//the data returned is the up-to-date data so the UI will refresh
deferred.resolve(data);
},
function (data, status, headers, config) {
//failure callback
deferred.reject('Failed to save data for media id ' + content.id);
});
return deferred.promise;
},
/** Posts a multi-part mime request to the server */
postMultiPartRequest: function (url, jsonData, transformCallback, successCallback, failureCallback) {

View File

@@ -30,13 +30,20 @@ angular.module("umbraco")
$scope.saveAndPublish = function (cnt) {
cnt.publishDate = new Date();
contentResource.publishContent(cnt, $routeParams.create, $scope.files);
notificationsService.success("Published", "Content has been saved and published");
contentResource.publishContent(cnt, $routeParams.create, $scope.files)
.then(function(data) {
$scope.content = data;
notificationsService.success("Published", "Content has been saved and published");
});
};
$scope.save = function (cnt) {
cnt.updateDate = new Date();
contentResource.saveContent(cnt, $routeParams.create, $scope.files);
notificationsService.success("Saved", "Content has been saved");
contentResource.saveContent(cnt, $routeParams.create, $scope.files)
.then(function (data) {
$scope.content = data;
notificationsService.success("Saved", "Content has been saved");
});
};
});

View File

@@ -28,8 +28,11 @@ function mediaEditController($scope, $routeParams, mediaResource, notificationsS
$scope.save = function (cnt) {
cnt.updateDate = new Date();
mediaResource.saveMedia(cnt, $routeParams.create, $scope.files);
notificationsService.success("Saved", "Media has been saved");
mediaResource.saveMedia(cnt, $routeParams.create, $scope.files)
.then(function (data) {
$scope.content = data;
notificationsService.success("Saved", "Media has been saved");
});
};
}

View File

@@ -117,6 +117,13 @@ namespace Umbraco.Web.UI.App_Plugins.MyPackage.PropertyEditors
//TODO: We need to remove any files that were previously persisted but are no longer persisted. FOr example, if we
// uploaded 5 files before and then only uploaded 3, then the last two should be deleted.
//NOTE: We will save a simple string if there is only one media item, this is mostly for backwards compatibility and for
// the current media pickers to work.
if (newValue.Count == 1)
{
return newValue[0]["file"].ToString();
}
return newValue.ToString(Formatting.None);
}
}

View File

@@ -12,7 +12,7 @@ define(['namespaceMgr'], function () {
//for legacy data, this will not be an array, just a string so convert to an array
if (!$scope.model.value.startsWith('[')) {
$scope.model.value = "[file: '" + $scope.model.value + "']";
$scope.model.value = "[{\"file\": \"" + $scope.model.value + "\"}]";
}
$scope.persistedFiles = _.map(angular.fromJson($scope.model.value), function (item) {

View File

@@ -95,8 +95,8 @@ namespace Umbraco.Web.Editors
[ContentItemValidationFilter(typeof(ContentItemValidationHelper<IMedia>))]
[FileUploadCleanupFilter]
public MediaItemDisplay PostSave(
[ModelBinder(typeof(ContentItemBinder))]
ContentItemSave<IMedia> mediaItem)
[ModelBinder(typeof(MediaItemBinder))]
ContentItemSave<IMedia> contentItem)
{
//If we've reached here it means:
// * Our model has been bound
@@ -106,16 +106,16 @@ namespace Umbraco.Web.Editors
//Now, we just need to save the data
//Save the property values
foreach (var p in mediaItem.ContentDto.Properties)
//Save the property values (for properties that have a valid editor ... not legacy)
foreach (var p in contentItem.ContentDto.Properties.Where(x => x.PropertyEditor != null))
{
//get the dbo property
var dboProperty = mediaItem.PersistedContent.Properties[p.Alias];
var dboProperty = contentItem.PersistedContent.Properties[p.Alias];
//create the property data to send to the property editor
var d = new Dictionary<string, object>();
//add the files if any
var files = mediaItem.UploadedFiles.Where(x => x.PropertyId == p.Id).ToArray();
var files = contentItem.UploadedFiles.Where(x => x.PropertyId == p.Id).ToArray();
if (files.Any())
{
d.Add("files", files);
@@ -127,10 +127,10 @@ namespace Umbraco.Web.Editors
}
//save the item
Services.MediaService.Save(mediaItem.PersistedContent);
Services.MediaService.Save(contentItem.PersistedContent);
//return the updated model
return _mediaModelMapper.ToMediaItemDisplay(mediaItem.PersistedContent);
return _mediaModelMapper.ToMediaItemDisplay(contentItem.PersistedContent);
}
}
}

View File

@@ -434,7 +434,9 @@
</Compile>
<Compile Include="UrlHelperExtensions.cs" />
<Compile Include="Editors\MediaController.cs" />
<Compile Include="WebApi\Binders\ContentItemBaseBinder.cs" />
<Compile Include="WebApi\Binders\ContentItemBinder.cs" />
<Compile Include="WebApi\Binders\MediaItemBinder.cs" />
<Compile Include="WebApi\Filters\ContentItemValidationFilterAttribute.cs" />
<Compile Include="WebApi\Filters\FileUploadCleanupFilterAttribute.cs" />
<Compile Include="WebApi\Filters\HttpQueryStringFilterAttribute.cs" />

View File

@@ -0,0 +1,152 @@
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.ModelBinding;
using Newtonsoft.Json;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Web.Models.ContentEditing;
using Task = System.Threading.Tasks.Task;
namespace Umbraco.Web.WebApi.Binders
{
/// <summary>
/// Binds the content model to the controller action for the posted multi-part Post
/// </summary>
internal abstract class ContentItemBaseBinder<TPersisted> : IModelBinder
where TPersisted : IContentBase
{
protected ApplicationContext ApplicationContext { get; private set; }
/// <summary>
/// Constructor
/// </summary>
/// <param name="applicationContext"></param>
internal ContentItemBaseBinder(ApplicationContext applicationContext)
{
ApplicationContext = applicationContext;
}
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
//NOTE: Validation is done in the filter
if (actionContext.Request.Content.IsMimeMultipartContent() == false)
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
var root = HttpContext.Current.Server.MapPath("~/App_Data/TEMP/FileUploads");
//ensure it exists
Directory.CreateDirectory(root);
var provider = new MultipartFormDataStreamProvider(root);
var task = Task.Run(() => GetModel(actionContext.Request, provider))
.ContinueWith(x =>
{
if (x.IsFaulted && x.Exception != null)
{
throw x.Exception;
}
bindingContext.Model = x.Result;
});
task.Wait();
return bindingContext.Model != null;
}
/// <summary>
/// Builds the model from the request contents
/// </summary>
/// <param name="request"></param>
/// <param name="provider"></param>
/// <returns></returns>
private async Task<ContentItemSave<TPersisted>> GetModel(HttpRequestMessage request, MultipartFormDataStreamProvider provider)
{
//IMPORTANT!!! We need to ensure the umbraco context here because this is running in an async thread
UmbracoContext.EnsureContext(request.Properties["MS_HttpContext"] as HttpContextBase, ApplicationContext.Current);
var content = request.Content;
var result = await content.ReadAsMultipartAsync(provider);
if (result.FormData["contentItem"] == null)
{
throw new HttpResponseException(
new HttpResponseMessage(HttpStatusCode.BadRequest)
{
ReasonPhrase = "The request was not formatted correctly and is missing the 'contentItem' parameter"
});
}
//get the string json from the request
var contentItem = result.FormData["contentItem"];
//transform the json into an object
var model = JsonConvert.DeserializeObject<ContentItemSave<TPersisted>>(contentItem);
//get the files
foreach (var file in result.FileData)
{
//The name that has been assigned in JS has 2 parts and the second part indicates the property id
// for which the file belongs.
var parts = file.Headers.ContentDisposition.Name.Trim(new char[] { '\"' }).Split('_');
if (parts.Length != 2)
{
throw new HttpResponseException(
new HttpResponseMessage(HttpStatusCode.BadRequest)
{
ReasonPhrase = "The request was not formatted correctly the file name's must be underscore delimited"
});
}
int propertyId;
if (int.TryParse(parts[1], out propertyId) == false)
{
throw new HttpResponseException(
new HttpResponseMessage(HttpStatusCode.BadRequest)
{
ReasonPhrase = "The request was not formatted correctly the file name's 2nd part must be an integer"
});
}
var fileName = file.Headers.ContentDisposition.FileName.Trim(new char[] {'\"'});
model.UploadedFiles.Add(new ContentItemFile
{
TempFilePath = file.LocalFileName,
PropertyId = propertyId,
FileName = fileName
});
}
if (model.Action == ContentSaveAction.Publish || model.Action == ContentSaveAction.Save)
{
//finally, let's lookup the real content item and create the DTO item
model.PersistedContent = GetExisting(model);
}
else
{
//we are creating new content
model.PersistedContent = CreateNew(model);
}
model.ContentDto = Map(model);
//we will now assign all of the values in the 'save' model to the DTO object
foreach (var p in model.Properties)
{
model.ContentDto.Properties.Single(x => x.Id == p.Id).Value = p.Value;
}
return model;
}
protected abstract TPersisted GetExisting(ContentItemSave<TPersisted> model);
protected abstract TPersisted CreateNew(ContentItemSave<TPersisted> model);
protected abstract ContentItemDto<TPersisted> Map(ContentItemSave<TPersisted> model);
}
}

View File

@@ -1,38 +1,18 @@
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using System.Web.Http.Controllers;
using System.Web.Http.ModelBinding;
using Newtonsoft.Json;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.Models.Mapping;
using Task = System.Threading.Tasks.Task;
namespace Umbraco.Web.WebApi.Binders
{
/// <summary>
/// Binds the content model to the controller action for the posted multi-part Post
/// </summary>
internal class ContentItemBinder : IModelBinder
internal class ContentItemBinder : ContentItemBaseBinder<IContent>
{
private readonly ApplicationContext _applicationContext;
private readonly ContentModelMapper _contentModelMapper;
/// <summary>
/// Constructor
/// </summary>
/// <param name="applicationContext"></param>
/// <param name="contentModelMapper"></param>
internal ContentItemBinder(ApplicationContext applicationContext, ContentModelMapper contentModelMapper)
public ContentItemBinder(ApplicationContext applicationContext, ContentModelMapper contentModelMapper)
: base(applicationContext)
{
_applicationContext = applicationContext;
_contentModelMapper = contentModelMapper;
}
@@ -44,122 +24,24 @@ namespace Umbraco.Web.WebApi.Binders
{
}
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
protected override IContent GetExisting(ContentItemSave<IContent> model)
{
//NOTE: Validation is done in the filter
if (!actionContext.Request.Content.IsMimeMultipartContent())
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
var root = HttpContext.Current.Server.MapPath("~/App_Data/TEMP/FileUploads");
//ensure it exists
Directory.CreateDirectory(root);
var provider = new MultipartFormDataStreamProvider(root);
var task = Task.Run(() => GetModel(actionContext.Request, provider))
.ContinueWith(x =>
{
if (x.IsFaulted && x.Exception != null)
{
throw x.Exception;
}
bindingContext.Model = x.Result;
});
task.Wait();
return bindingContext.Model != null;
return ApplicationContext.Services.ContentService.GetById(model.Id);
}
/// <summary>
/// Builds the model from the request contents
/// </summary>
/// <param name="request"></param>
/// <param name="provider"></param>
/// <returns></returns>
private async Task<ContentItemSave<IContent>> GetModel(HttpRequestMessage request, MultipartFormDataStreamProvider provider)
protected override IContent CreateNew(ContentItemSave<IContent> model)
{
//IMPORTANT!!! We need to ensure the umbraco context here because this is running in an async thread
UmbracoContext.EnsureContext(request.Properties["MS_HttpContext"] as HttpContextBase, ApplicationContext.Current);
var content = request.Content;
var result = await content.ReadAsMultipartAsync(provider);
if (result.FormData["contentItem"] == null)
var contentType = ApplicationContext.Services.ContentTypeService.GetContentType(model.ContentTypeAlias);
if (contentType == null)
{
throw new HttpResponseException(
new HttpResponseMessage(HttpStatusCode.BadRequest)
{
ReasonPhrase = "The request was not formatted correctly and is missing the 'contentItem' parameter"
});
throw new InvalidOperationException("No content type found wth alias " + model.ContentTypeAlias);
}
return new Content(model.Name, model.ParentId, contentType);
}
//get the string json from the request
var contentItem = result.FormData["contentItem"];
//transform the json into an object
var model = JsonConvert.DeserializeObject<ContentItemSave<IContent>>(contentItem);
//get the files
foreach (var file in result.FileData)
{
//The name that has been assigned in JS has 2 parts and the second part indicates the property id
// for which the file belongs.
var parts = file.Headers.ContentDisposition.Name.Trim(new char[] { '\"' }).Split('_');
if (parts.Length != 2)
{
throw new HttpResponseException(
new HttpResponseMessage(HttpStatusCode.BadRequest)
{
ReasonPhrase = "The request was not formatted correctly the file name's must be underscore delimited"
});
}
int propertyId;
if (!int.TryParse(parts[1], out propertyId))
{
throw new HttpResponseException(
new HttpResponseMessage(HttpStatusCode.BadRequest)
{
ReasonPhrase = "The request was not formatted correctly the file name's 2nd part must be an integer"
});
}
var fileName = file.Headers.ContentDisposition.FileName.Trim(new char[] {'\"'});
model.UploadedFiles.Add(new ContentItemFile
{
TempFilePath = file.LocalFileName,
PropertyId = propertyId,
FileName = fileName
});
}
if (model.Action == ContentSaveAction.Publish || model.Action == ContentSaveAction.Save)
{
//finally, let's lookup the real content item and create the DTO item
model.PersistedContent = _applicationContext.Services.ContentService.GetById(model.Id);
}
else
{
//we are creating new content
var contentType = _applicationContext.Services.ContentTypeService.GetContentType(model.ContentTypeAlias);
if (contentType == null)
{
throw new InvalidOperationException("No content type found wth alias " + model.ContentTypeAlias);
}
model.PersistedContent = new Content(model.Name, model.ParentId, contentType);
}
model.ContentDto = _contentModelMapper.ToContentItemDto(model.PersistedContent);
//we will now assign all of the values in the 'save' model to the DTO object
foreach (var p in model.Properties)
{
model.ContentDto.Properties.Single(x => x.Id == p.Id).Value = p.Value;
}
return model;
protected override ContentItemDto<IContent> Map(ContentItemSave<IContent> model)
{
return _contentModelMapper.ToContentItemDto(model.PersistedContent);
}
}
}

View File

@@ -0,0 +1,47 @@
using System;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.Models.Mapping;
namespace Umbraco.Web.WebApi.Binders
{
internal class MediaItemBinder : ContentItemBaseBinder<IMedia>
{
private readonly MediaModelMapper _mediaModelMapper;
public MediaItemBinder(ApplicationContext applicationContext, MediaModelMapper mediaModelMapper)
: base(applicationContext)
{
_mediaModelMapper = mediaModelMapper;
}
/// <summary>
/// Constructor
/// </summary>
public MediaItemBinder()
: this(ApplicationContext.Current, new MediaModelMapper(ApplicationContext.Current, new ProfileModelMapper()))
{
}
protected override IMedia GetExisting(ContentItemSave<IMedia> model)
{
return ApplicationContext.Services.MediaService.GetById(model.Id);
}
protected override IMedia CreateNew(ContentItemSave<IMedia> model)
{
var contentType = ApplicationContext.Services.ContentTypeService.GetMediaType(model.ContentTypeAlias);
if (contentType == null)
{
throw new InvalidOperationException("No content type found wth alias " + model.ContentTypeAlias);
}
return new Core.Models.Media(model.Name, model.ParentId, contentType);
}
protected override ContentItemDto<IMedia> Map(ContentItemSave<IMedia> model)
{
return _mediaModelMapper.ToMediaItemDto(model.PersistedContent);
}
}
}

View File

@@ -6,6 +6,7 @@ using System.Net.Http;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using Umbraco.Core;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
using Umbraco.Core.PropertyEditors;
using Umbraco.Web.Models.ContentEditing;
@@ -96,8 +97,10 @@ namespace Umbraco.Web.WebApi.Filters
if (editor == null)
{
var message = string.Format("The property editor with id: {0} was not found for property with id {1}", p.DataType.ControlId, p.Id);
actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.NotFound, message);
return false;
LogHelper.Warn<ContentItemValidationHelper<TPersisted>>(message);
//actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.NotFound, message);
//return false;
continue;
}
//get the posted value for this property