diff --git a/src/Umbraco.Core/Models/PropertyType.cs b/src/Umbraco.Core/Models/PropertyType.cs
index 0aebcb6544..492051fca7 100644
--- a/src/Umbraco.Core/Models/PropertyType.cs
+++ b/src/Umbraco.Core/Models/PropertyType.cs
@@ -1,6 +1,5 @@
using System;
using System.Diagnostics;
-using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
@@ -436,4 +435,4 @@ namespace Umbraco.Core.Models
return clone;
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Umbraco.Core/Services/IMemberService.cs b/src/Umbraco.Core/Services/IMemberService.cs
index 9153d23da9..ea214bbe76 100644
--- a/src/Umbraco.Core/Services/IMemberService.cs
+++ b/src/Umbraco.Core/Services/IMemberService.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
+using System.Net.Http;
using System.Xml.Linq;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Membership;
@@ -199,6 +200,8 @@ namespace Umbraco.Core.Services
/// Id of the MemberType
void DeleteMembersOfType(int memberTypeId);
+ HttpResponseMessage ExportMemberData(Guid key);
+
[Obsolete("Use the overload with 'long' parameter types instead")]
[EditorBrowsable(EditorBrowsableState.Never)]
IEnumerable FindMembersByDisplayName(string displayNameToMatch, int pageIndex, int pageSize, out int totalRecords, StringPropertyMatchType matchType = StringPropertyMatchType.StartsWith);
@@ -249,4 +252,4 @@ namespace Umbraco.Core.Services
///
IEnumerable GetMembersByPropertyValue(string propertyTypeAlias, DateTime value, ValuePropertyMatchType matchType = ValuePropertyMatchType.Exact);
}
-}
\ No newline at end of file
+}
diff --git a/src/Umbraco.Core/Services/MemberService.cs b/src/Umbraco.Core/Services/MemberService.cs
index f22c63e652..1a88f0b714 100644
--- a/src/Umbraco.Core/Services/MemberService.cs
+++ b/src/Umbraco.Core/Services/MemberService.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
+using System.IO;
using System.Threading;
using System.Web.Security;
using System.Xml.Linq;
@@ -14,6 +15,9 @@ using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Persistence.UnitOfWork;
using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Net.Http.Headers;
using Umbraco.Core.Security;
namespace Umbraco.Core.Services
@@ -253,6 +257,89 @@ namespace Umbraco.Core.Services
}
}
}
+ ///
+ /// Exports Member data by unique key
+ ///
+ ///
+ ///
+ public HttpResponseMessage ExportMemberData(Guid key)
+ {
+
+ //Filters
+ List memberPropFilter = new List
+ {
+ "RawPasswordValue","ParentId","SortOrder", "Level", "Path", "CreatorId", "Version", "ContentTypeId", "HasIdentity",
+ "PropertyGroups", "PropertyTypes", "ProviderUserKey", "ContentType"
+ };
+
+ List propertiesFilter = new List
+ {
+ "PropertyType", "Version", "Id", "HasIdentity", "Key"
+ };
+
+
+ //Get the member
+ var member = GetByKey(key);
+ var memberProperties = member.GetType().GetProperties();
+
+ string fileName = member.Name + "_" + member.Email + ".txt";
+
+ using (MemoryStream ms = new MemoryStream())
+ {
+ using (TextWriter tw = new StreamWriter(ms))
+ {
+ foreach (var memberProp in memberProperties)
+ {
+ if (memberPropFilter.Contains(memberProp.Name)) continue;
+
+ var propValue = memberProp.GetValue(member, null);
+ var type = propValue?.GetType();
+
+ if (type == typeof(PropertyCollection))
+ {
+ tw.WriteLine("");
+ tw.WriteLine("PROPERTIES");
+ tw.WriteLine("**********");
+
+ if (propValue is PropertyCollection pc)
+ foreach (var prop in pc)
+ {
+ var propProperties = prop.GetType().GetProperties();
+
+ //Writing the proerty name
+ tw.WriteLine("Name : " + prop.PropertyType.Name);
+
+ foreach (var p in propProperties)
+ {
+ if (propertiesFilter.Contains(p.Name)) continue;
+ var pValue = p.GetValue(prop, null);
+ tw.WriteLine(p.Name + " : " + pValue);
+ }
+
+ tw.WriteLine("------------------------");
+ }
+ }
+ else
+ {
+ tw.WriteLine(memberProp.Name + " : " + propValue);
+ }
+ }
+
+ tw.Flush();
+ }
+
+ HttpResponseMessage httpResponseMessage = new HttpResponseMessage();
+ httpResponseMessage.Content = new ByteArrayContent(ms.ToArray());
+ httpResponseMessage.Content.Headers.Add("x-filename", fileName);
+ httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
+ httpResponseMessage.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
+ httpResponseMessage.Content.Headers.ContentDisposition.FileName = fileName;
+ httpResponseMessage.StatusCode = HttpStatusCode.OK;
+
+ return httpResponseMessage;
+ }
+ }
+
[Obsolete("Use the overload with 'long' parameter types instead")]
[EditorBrowsable(EditorBrowsableState.Never)]
@@ -588,7 +675,7 @@ namespace Umbraco.Core.Services
Mandate.ParameterCondition(pageIndex >= 0, "pageIndex");
Mandate.ParameterCondition(pageSize > 0, "pageSize");
- using (var uow = UowProvider.GetUnitOfWork(readOnly:true))
+ using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateMemberRepository(uow);
return repository.GetPagedXmlEntriesByPath("-1", pageIndex, pageSize, null, out totalRecords);
diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/member.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/member.resource.js
index 2073307db9..f98d30ee69 100644
--- a/src/Umbraco.Web.UI.Client/src/common/resources/member.resource.js
+++ b/src/Umbraco.Web.UI.Client/src/common/resources/member.resource.js
@@ -10,8 +10,8 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) {
return umbRequestHelper.postSaveContent({
restApiUrl: umbRequestHelper.getApiUrl(
- "memberApiBaseUrl",
- "PostSave"),
+ "memberApiBaseUrl",
+ "PostSave"),
content: content,
action: action,
files: files,
@@ -67,35 +67,35 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) {
}
var params = [
- { pageNumber: options.pageNumber },
- { pageSize: options.pageSize },
- { orderBy: options.orderBy },
- { orderDirection: options.orderDirection },
- { orderBySystemField: toBool(options.orderBySystemField) },
- { filter: options.filter }
+ { pageNumber: options.pageNumber },
+ { pageSize: options.pageSize },
+ { orderBy: options.orderBy },
+ { orderDirection: options.orderDirection },
+ { orderBySystemField: toBool(options.orderBySystemField) },
+ { filter: options.filter }
];
if (memberTypeAlias != null) {
params.push({ memberTypeAlias: memberTypeAlias });
}
return umbRequestHelper.resourcePromise(
- $http.get(
- umbRequestHelper.getApiUrl(
- "memberApiBaseUrl",
- "GetPagedResults",
- params)),
- 'Failed to retrieve member paged result');
+ $http.get(
+ umbRequestHelper.getApiUrl(
+ "memberApiBaseUrl",
+ "GetPagedResults",
+ params)),
+ 'Failed to retrieve member paged result');
},
getListNode: function (listName) {
return umbRequestHelper.resourcePromise(
- $http.get(
- umbRequestHelper.getApiUrl(
- "memberApiBaseUrl",
- "GetListNodeDisplay",
- [{ listName: listName }])),
- 'Failed to retrieve data for member list ' + listName);
+ $http.get(
+ umbRequestHelper.getApiUrl(
+ "memberApiBaseUrl",
+ "GetListNodeDisplay",
+ [{ listName: listName }])),
+ 'Failed to retrieve data for member list ' + listName);
},
/**
@@ -122,12 +122,12 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) {
getByKey: function (key) {
return umbRequestHelper.resourcePromise(
- $http.get(
- umbRequestHelper.getApiUrl(
- "memberApiBaseUrl",
- "GetByKey",
- [{ key: key }])),
- 'Failed to retrieve data for member id ' + key);
+ $http.get(
+ umbRequestHelper.getApiUrl(
+ "memberApiBaseUrl",
+ "GetByKey",
+ [{ key: key }])),
+ 'Failed to retrieve data for member id ' + key);
},
/**
@@ -152,12 +152,12 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) {
*/
deleteByKey: function (key) {
return umbRequestHelper.resourcePromise(
- $http.post(
- umbRequestHelper.getApiUrl(
- "memberApiBaseUrl",
- "DeleteByKey",
- [{ key: key }])),
- 'Failed to delete item ' + key);
+ $http.post(
+ umbRequestHelper.getApiUrl(
+ "memberApiBaseUrl",
+ "DeleteByKey",
+ [{ key: key }])),
+ 'Failed to delete item ' + key);
},
/**
@@ -194,20 +194,20 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) {
if (alias) {
return umbRequestHelper.resourcePromise(
- $http.get(
- umbRequestHelper.getApiUrl(
- "memberApiBaseUrl",
- "GetEmpty",
- [{ contentTypeAlias: alias }])),
- 'Failed to retrieve data for empty member item type ' + alias);
+ $http.get(
+ umbRequestHelper.getApiUrl(
+ "memberApiBaseUrl",
+ "GetEmpty",
+ [{ contentTypeAlias: alias }])),
+ 'Failed to retrieve data for empty member item type ' + alias);
}
else {
return umbRequestHelper.resourcePromise(
- $http.get(
- umbRequestHelper.getApiUrl(
- "memberApiBaseUrl",
- "GetEmpty")),
- 'Failed to retrieve data for empty member item type ' + alias);
+ $http.get(
+ umbRequestHelper.getApiUrl(
+ "memberApiBaseUrl",
+ "GetEmpty")),
+ 'Failed to retrieve data for empty member item type ' + alias);
}
},
@@ -242,6 +242,38 @@ function memberResource($q, $http, umbDataFormatter, umbRequestHelper) {
*/
save: function (member, isNew, files) {
return saveMember(member, "save" + (isNew ? "New" : ""), files);
+ },
+
+ exportMemberData: function (key) {
+ return umbRequestHelper.resourcePromise(
+ $http.get(
+ umbRequestHelper.getApiUrl(
+ "memberApiBaseUrl",
+ "ExportMemberData",
+ [{ key: key }]))
+ .success(function (data, status, headers) {
+
+ headers = headers();
+
+ var filename = headers['x-filename'];
+ var contentType = headers['content-type'];
+
+ var linkElement = document.createElement('a');
+
+ var blob = new Blob([data], { type: contentType });
+ var url = window.URL.createObjectURL(blob);
+
+ linkElement.setAttribute('href', url);
+ linkElement.setAttribute("download", filename);
+
+ var clickEvent = new MouseEvent("click", {
+ "view": window,
+ "bubbles": true,
+ "cancelable": false
+ });
+
+ linkElement.dispatchEvent(clickEvent);
+ }));
}
};
}
diff --git a/src/Umbraco.Web.UI.Client/src/views/member/edit.html b/src/Umbraco.Web.UI.Client/src/views/member/edit.html
index d72750c770..3008786d3a 100644
--- a/src/Umbraco.Web.UI.Client/src/views/member/edit.html
+++ b/src/Umbraco.Web.UI.Client/src/views/member/edit.html
@@ -20,13 +20,13 @@
-
+
+
+
+
+
-
-
-
-
-
+
diff --git a/src/Umbraco.Web.UI.Client/src/views/member/member.edit.controller.js b/src/Umbraco.Web.UI.Client/src/views/member/member.edit.controller.js
index 215cd7777c..842590c4e7 100644
--- a/src/Umbraco.Web.UI.Client/src/views/member/member.edit.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/member/member.edit.controller.js
@@ -17,6 +17,7 @@ function MemberEditController($scope, $routeParams, $location, $q, $window, appS
$scope.page.nameLocked = false;
$scope.page.listViewPath = null;
$scope.page.saveButtonState = "init";
+ $scope.page.exportButton = "init";
$scope.busy = false;
$scope.page.listViewPath = ($routeParams.page && $routeParams.listName)
@@ -171,6 +172,11 @@ function MemberEditController($scope, $routeParams, $location, $q, $window, appS
};
+ $scope.export = function() {
+ var memberKey = $scope.content.key;
+ memberResource.exportMemberData(memberKey);
+ }
+
}
angular.module("umbraco").controller("Umbraco.Editors.Member.EditController", MemberEditController);
diff --git a/src/Umbraco.Web/Editors/MemberController.cs b/src/Umbraco.Web/Editors/MemberController.cs
index 2440ad0691..3ad4d05eb7 100644
--- a/src/Umbraco.Web/Editors/MemberController.cs
+++ b/src/Umbraco.Web/Editors/MemberController.cs
@@ -774,5 +774,15 @@ namespace Umbraco.Web.Editors
return Request.CreateResponse(HttpStatusCode.OK);
}
+ ///
+ /// Exports member data
+ ///
+ ///
+ ///
+ [HttpGet]
+ public HttpResponseMessage ExportMemberData(Guid key)
+ {
+ return Services.MemberService.ExportMemberData(key);
+ }
}
}