Fixes up issues with editing the member profile and registering a member with our snippets including specifying a custom member type.
This commit is contained in:
@@ -48,6 +48,13 @@
|
||||
@for (var i = 0; i < profileModel.MemberProperties.Count; i++)
|
||||
{
|
||||
@Html.LabelFor(m => profileModel.MemberProperties[i].Value, profileModel.MemberProperties[i].Name)
|
||||
@*
|
||||
By default this will render a textbox but if you want to change the editor template for this property you can
|
||||
easily change it. For example, if you wanted to render a custom editor for this field called "MyEditor" you would
|
||||
create a file at ~/Views/Shared/EditorTemplates/MyEditor.cshtml", then you will change the next line of code to
|
||||
render your specific editor template like:
|
||||
@Html.EditorFor(m => profileModel.MemberProperties[i].Value, "MyEditor")
|
||||
*@
|
||||
@Html.EditorFor(m => profileModel.MemberProperties[i].Value)
|
||||
@Html.HiddenFor(m => profileModel.MemberProperties[i].Alias)
|
||||
<br />
|
||||
|
||||
@@ -78,6 +78,13 @@ else
|
||||
for (var i = 0; i < registerModel.MemberProperties.Count; i++)
|
||||
{
|
||||
@Html.LabelFor(m => registerModel.MemberProperties[i].Value, registerModel.MemberProperties[i].Name)
|
||||
@*
|
||||
By default this will render a textbox but if you want to change the editor template for this property you can
|
||||
easily change it. For example, if you wanted to render a custom editor for this field called "MyEditor" you would
|
||||
create a file at ~/Views/Shared/EditorTemplates/MyEditor.cshtml", then you will change the next line of code to
|
||||
render your specific editor template like:
|
||||
@Html.EditorFor(m => profileModel.MemberProperties[i].Value, "MyEditor")
|
||||
*@
|
||||
@Html.EditorFor(m => registerModel.MemberProperties[i].Value)
|
||||
@Html.HiddenFor(m => registerModel.MemberProperties[i].Alias)
|
||||
<br />
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using umbraco.cms.businesslogic.member;
|
||||
@@ -18,6 +19,7 @@ namespace Umbraco.Web.Models
|
||||
/// <summary>
|
||||
/// A readonly member profile model
|
||||
/// </summary>
|
||||
[ModelBinder(typeof(ProfileModelBinder))]
|
||||
public class ProfileModel : PostRedirectModel
|
||||
{
|
||||
|
||||
@@ -96,7 +98,18 @@ namespace Umbraco.Web.Models
|
||||
/// <remarks>
|
||||
/// Adding items to this list on the front-end will not add properties to the member in the database.
|
||||
/// </remarks>
|
||||
public List<UmbracoProperty> MemberProperties { get; set; }
|
||||
|
||||
public List<UmbracoProperty> MemberProperties { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A custom model binder for MVC because the default ctor performs a lookup!
|
||||
/// </summary>
|
||||
internal class ProfileModelBinder : DefaultModelBinder
|
||||
{
|
||||
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
|
||||
{
|
||||
return ProfileModel.CreateModel();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,14 @@ using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Mvc;
|
||||
using umbraco.cms.businesslogic.member;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Web.Security;
|
||||
|
||||
namespace Umbraco.Web.Models
|
||||
{
|
||||
[ModelBinder(typeof(RegisterModelBinder))]
|
||||
public class RegisterModel : PostRedirectModel
|
||||
{
|
||||
/// <summary>
|
||||
@@ -58,6 +60,7 @@ namespace Umbraco.Web.Models
|
||||
/// <summary>
|
||||
/// The member type alias to use to register the member
|
||||
/// </summary>
|
||||
[Editable(false)]
|
||||
public string MemberTypeAlias { get; set; }
|
||||
|
||||
/// <summary>
|
||||
@@ -90,5 +93,16 @@ namespace Umbraco.Web.Models
|
||||
/// </summary>
|
||||
public bool LoginOnSuccess { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A custom model binder for MVC because the default ctor performs a lookup!
|
||||
/// </summary>
|
||||
internal class RegisterModelBinder : DefaultModelBinder
|
||||
{
|
||||
protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
|
||||
{
|
||||
return RegisterModel.CreateModel();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using System.Xml;
|
||||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Xml;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
|
||||
@@ -9,9 +11,30 @@ namespace Umbraco.Web.Models
|
||||
/// </summary>
|
||||
public class UmbracoProperty
|
||||
{
|
||||
[Editable(false)]
|
||||
public string Alias { get; set; }
|
||||
public object Value { get; set; }
|
||||
|
||||
//NOTE: This has to be a string currently, if it is an object it will bind as an array which we don't want.
|
||||
// If we want to have this as an 'object' with a true type on it, we have to create a custom model binder
|
||||
// for an UmbracoProperty and then bind with the correct type based on the property type for this alias. This
|
||||
// would be a bit long winded and perhaps unnecessary. The reason is because it is always posted as a string anyways
|
||||
// and when we set this value on the property object that gets sent to the database we do a TryConvertTo to the
|
||||
// real type anyways.
|
||||
|
||||
[DataType(DataType.Text)]
|
||||
public string Value { get; set; }
|
||||
|
||||
[ReadOnly(true)]
|
||||
public string Name { get; set; }
|
||||
|
||||
//TODO: Perhaps one day we'll ship with our own EditorTempates but for now developers can just render their own inside the view
|
||||
|
||||
///// <summary>
|
||||
///// This can dynamically be set to a custom template name to change
|
||||
///// the editor type for this property
|
||||
///// </summary>
|
||||
//[ReadOnly(true)]
|
||||
//public string EditorTemplate { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,22 @@ namespace Umbraco.Web.Mvc
|
||||
{
|
||||
internal static class ControllerExtensions
|
||||
{
|
||||
internal static object GetDataTokenInViewContextHierarchy(this ControllerContext controllerContext, string dataTokenName)
|
||||
{
|
||||
if (controllerContext.RouteData.DataTokens.ContainsKey(dataTokenName))
|
||||
{
|
||||
return controllerContext.RouteData.DataTokens[dataTokenName];
|
||||
}
|
||||
|
||||
if (controllerContext.ParentActionViewContext != null)
|
||||
{
|
||||
//recurse!
|
||||
return controllerContext.ParentActionViewContext.GetDataTokenInViewContextHierarchy(dataTokenName);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the controller name from the controller type
|
||||
/// </summary>
|
||||
|
||||
@@ -94,19 +94,17 @@ namespace Umbraco.Web.Mvc
|
||||
/// <returns></returns>
|
||||
private bool ShouldFindView(ControllerContext controllerContext, bool isPartial)
|
||||
{
|
||||
var umbracoToken = controllerContext.GetDataTokenInViewContextHierarchy("umbraco");
|
||||
|
||||
//first check if we're rendering a partial view for the back office, or surface controller, etc...
|
||||
//anything that is not IUmbracoRenderModel as this should only pertain to Umbraco views.
|
||||
if (isPartial
|
||||
&& controllerContext.RouteData.DataTokens.ContainsKey("umbraco")
|
||||
&& !(controllerContext.RouteData.DataTokens["umbraco"] is RenderModel))
|
||||
if (isPartial && umbracoToken is RenderModel)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
//only find views if we're rendering the umbraco front end
|
||||
if (controllerContext.RouteData.DataTokens.ContainsKey("umbraco")
|
||||
&& controllerContext.RouteData.DataTokens["umbraco"] != null
|
||||
&& controllerContext.RouteData.DataTokens["umbraco"] is RenderModel)
|
||||
if (umbracoToken is RenderModel)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -129,16 +129,20 @@ namespace Umbraco.Web.Security
|
||||
{
|
||||
model.Username = (model.UsernameIsEmail || model.Username == null) ? model.Email : model.Username;
|
||||
|
||||
var membershipUser = Membership.CreateUser(model.Username, model.Password, model.Email,
|
||||
//TODO: Support q/a http://issues.umbraco.org/issue/U4-3213
|
||||
null, null,
|
||||
true, out status);
|
||||
MembershipUser membershipUser;
|
||||
|
||||
if (status != MembershipCreateStatus.Success) return null;
|
||||
|
||||
//update their real name
|
||||
if (Membership.Provider.IsUmbracoMembershipProvider())
|
||||
{
|
||||
membershipUser = ((UmbracoMembershipProviderBase)Membership.Provider).CreateUser(
|
||||
model.MemberTypeAlias,
|
||||
model.Username, model.Password, model.Email,
|
||||
//TODO: Support q/a http://issues.umbraco.org/issue/U4-3213
|
||||
null, null,
|
||||
true, null, out status);
|
||||
|
||||
if (status != MembershipCreateStatus.Success) return null;
|
||||
|
||||
var member = _applicationContext.Services.MemberService.GetByUsername(membershipUser.UserName);
|
||||
member.Name = model.Name;
|
||||
|
||||
@@ -155,7 +159,12 @@ namespace Umbraco.Web.Security
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO: Support this scenario!
|
||||
membershipUser = Membership.CreateUser(model.Username, model.Password, model.Email,
|
||||
//TODO: Support q/a http://issues.umbraco.org/issue/U4-3213
|
||||
null, null,
|
||||
true, out status);
|
||||
|
||||
if (status != MembershipCreateStatus.Success) return null;
|
||||
}
|
||||
|
||||
//Set member online
|
||||
@@ -282,23 +291,8 @@ namespace Umbraco.Web.Security
|
||||
|
||||
var builtIns = Constants.Conventions.Member.GetStandardPropertyTypeStubs().Select(x => x.Key).ToArray();
|
||||
|
||||
foreach (var prop in memberType.PropertyTypes
|
||||
.Where(x => builtIns.Contains(x.Alias) == false && memberType.MemberCanEditProperty(x.Alias)))
|
||||
{
|
||||
var value = string.Empty;
|
||||
var propValue = member.Properties[prop.Alias];
|
||||
if (propValue != null)
|
||||
{
|
||||
value = propValue.Value.ToString();
|
||||
}
|
||||
model.MemberProperties = GetMemberPropertiesViewModel(memberType, builtIns, member).ToList();
|
||||
|
||||
model.MemberProperties.Add(new UmbracoProperty
|
||||
{
|
||||
Alias = prop.Alias,
|
||||
Name = prop.Name,
|
||||
Value = value
|
||||
});
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
@@ -321,17 +315,10 @@ namespace Umbraco.Web.Security
|
||||
if (memberType == null)
|
||||
throw new InvalidOperationException("Could not find a member type with alias " + memberTypeAlias);
|
||||
|
||||
var props = memberType.PropertyTypes
|
||||
.Where(x => memberType.MemberCanEditProperty(x.Alias))
|
||||
.Select(prop => new UmbracoProperty
|
||||
{
|
||||
Alias = prop.Alias,
|
||||
Name = prop.Name,
|
||||
Value = string.Empty
|
||||
}).ToList();
|
||||
|
||||
var builtIns = Constants.Conventions.Member.GetStandardPropertyTypeStubs().Select(x => x.Key).ToArray();
|
||||
var model = RegisterModel.CreateModel();
|
||||
model.MemberProperties = props;
|
||||
model.MemberTypeAlias = memberTypeAlias;
|
||||
model.MemberProperties = GetMemberPropertiesViewModel(memberType, builtIns).ToList();
|
||||
return model;
|
||||
}
|
||||
else
|
||||
@@ -340,7 +327,64 @@ namespace Umbraco.Web.Security
|
||||
model.MemberTypeAlias = string.Empty;
|
||||
return model;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private IEnumerable<UmbracoProperty> GetMemberPropertiesViewModel(IMemberType memberType, IEnumerable<string> builtIns, IMember member = null)
|
||||
{
|
||||
var viewProperties = new List<UmbracoProperty>();
|
||||
|
||||
foreach (var prop in memberType.PropertyTypes
|
||||
.Where(x => builtIns.Contains(x.Alias) == false && memberType.MemberCanEditProperty(x.Alias)))
|
||||
{
|
||||
var value = string.Empty;
|
||||
if (member != null)
|
||||
{
|
||||
var propValue = member.Properties[prop.Alias];
|
||||
if (propValue != null)
|
||||
{
|
||||
value = propValue.Value.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
var viewProperty = new UmbracoProperty
|
||||
{
|
||||
Alias = prop.Alias,
|
||||
Name = prop.Name,
|
||||
Value = value
|
||||
};
|
||||
|
||||
//TODO: Perhaps one day we'll ship with our own EditorTempates but for now developers
|
||||
// can just render their own.
|
||||
|
||||
////This is a rudimentary check to see what data template we should render
|
||||
//// if developers want to change the template they can do so dynamically in their views or controllers
|
||||
//// for a given property.
|
||||
////These are the default built-in MVC template types: “Boolean”, “Decimal”, “EmailAddress”, “HiddenInput”, “Html”, “Object”, “String”, “Text”, and “Url”
|
||||
//// by default we'll render a text box since we've defined that metadata on the UmbracoProperty.Value property directly.
|
||||
//if (prop.DataTypeId == new Guid(Constants.PropertyEditors.TrueFalse))
|
||||
//{
|
||||
// viewProperty.EditorTemplate = "UmbracoBoolean";
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// switch (prop.DataTypeDatabaseType)
|
||||
// {
|
||||
// case DataTypeDatabaseType.Integer:
|
||||
// viewProperty.EditorTemplate = "Decimal";
|
||||
// break;
|
||||
// case DataTypeDatabaseType.Ntext:
|
||||
// viewProperty.EditorTemplate = "Text";
|
||||
// break;
|
||||
// case DataTypeDatabaseType.Date:
|
||||
// case DataTypeDatabaseType.Nvarchar:
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
|
||||
viewProperties.Add(viewProperty);
|
||||
}
|
||||
return viewProperties;
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user