문제

I have created a property under a MemberType called "testField" which is using a custom DataType dropdown list with 2 values in it (Employee and Subcontractor). I would like for a member to be able to select one, submit a form and to store their selection under this property, but I can't seem to figure it out.

Is it possible to do this whilst being able to change their selection manually in the back end?

Here's my code...

ASCX

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Register.ascx.cs" Inherits="nForum.usercontrols.nForum.membership.Register" %>

    <div id="forumregistration" class="validate">
            <dl class="form">
                <dt><label for="<%= tbLoginName.ClientID %>">Login/Username:</label></dt>
                <dd><asp:TextBox ToolTip="Enter username" CssClass="required" ID="tbLoginName" runat="server" /></dd>

                <dt><label for="<%= tbName.ClientID %>">Full Name:</label></dt>
                <dd><asp:TextBox ToolTip="Enter name" CssClass="required" ID="tbName" runat="server" /></dd>

                <dt><label for="<%= tbEmail.ClientID %>">Email:</label></dt>
                <dd><asp:TextBox ToolTip="Enter email address" CssClass="required email" ID="tbEmail" runat="server" /></dd>

                <dt><label for="<%= tbPassword.ClientID %>">Password:</label></dt>
                <dd><asp:TextBox ToolTip="Enter a password" CssClass="required password" ID="tbPassword" TextMode="Password" runat="server" /></dd>

                <dt><label for="">Status:</label></dt>
                <asp:dropdownlist ID="tbOrganisation" runat="server">
                    <asp:ListItem Text="Choose" Value="0"></asp:ListItem>
                    <asp:ListItem Text="Employee" Value="1"></asp:ListItem>
                    <asp:ListItem Text="Subcontractor" Value="2"></asp:ListItem>
                </asp:dropdownlist>
                <dt> </dt>
                <dd><asp:Button ID="btnSubmit" CssClass="textarea" runat="server" Text="Create Account" onclick="BtnSubmitClick" /></dd>

            </dl>
    </div>

CS

using System;
using System.Text;
using System.Web.Security;
using nForum.BusinessLogic;
using umbraco;
using umbraco.cms.businesslogic.member;

namespace nForum.usercontrols.nForum.membership
{
    public partial class Register : BaseForumUsercontrol
    {

        protected void BtnSubmitClick(object sender, EventArgs e)
        {
            var redirecturl = Settings.Url;

            // Check the user isn't already registered
            if (Member.GetMemberFromEmail(Helpers.GetSafeHtml(tbEmail.Text)) == null & Member.GetMemberFromLoginName(Helpers.GetSafeHtml(tbLoginName.Text)) == null)
            {
                // Set the member type and group
                var mt = MemberType.GetByAlias(MembershipHelper.ForumUserRoleName);
                var addToMemberGroup = MemberGroup.GetByName(MembershipHelper.ForumUserRoleName);

                //create a member
                var m = Member.MakeNew(Helpers.GetSafeHtml(tbName.Text), mt, new umbraco.BusinessLogic.User(0));

                //var mstatus = new MembershipCreateStatus();
                //var mp = Membership.CreateUser(tbName.Text, tbPassword.Text, tbEmail.Text, string.Empty, string.Empty, true, out mstatus);

                // Set the other properties
                m.Email = Helpers.GetSafeHtml(tbEmail.Text);
                m.LoginName = Helpers.GetSafeHtml(tbLoginName.Text);
                m.Password = Helpers.GetSafeHtml(tbPassword.Text);
                // Add 0 Karma to user, helps us later in the site
                m.getProperty("forumUserKarma").Value = 0;
                m.getProperty("forumUserAllowPrivateMessages").Value = 1;
                m.getProperty("forumUserLastPrivateMessage").Value = DateTime.Now;

                // Take selected dropdown value and store
                m.getProperty("testField").Value = tbOrganisation;

                //##### Manual Member Authorisation #####
                // If this is not enabled, mark the member as authorised
                if (!Settings.ManuallyAuthoriseNewMembers)
                {
                    m.getProperty("forumUserIsAuthorised").Value = 1;
                }

                m.AddGroup(addToMemberGroup.Id);

                //Save member
                m.Save();

                //Generate member Xml Cache
                m.XmlGenerate(new System.Xml.XmlDocument());

                if (!Settings.ManuallyAuthoriseNewMembers)
                {
                    //Login the user so they can be redirected to their profile page
                    FormsAuthentication.SetAuthCookie(tbLoginName.Text, false);
                }
                else
                {
                    redirecturl = string.Concat(CurrentPageAbsoluteUrl, "?m=", library.GetDictionaryItem("NotifiedWhenAccountAuth"));
                }

                // If admins wants email notification, then send it here
                if (Settings.EmailAdminOnNewMemberSignUp)
                {
                    SendAdminNotification(m);
                }
            }
            else
            {
                redirecturl = string.Concat(CurrentPageAbsoluteUrl, "?m=", library.GetDictionaryItem("UserAlreadyExists"));
            }

            // Now redirect to the correct page
            Response.Redirect("/discuss-it");

        }

        private void SendAdminNotification(Member newmember)
        {
            var sb = new StringBuilder();
            sb.AppendFormat(library.GetDictionaryItem("MemberSignUpEmailText"),
                Settings.Name,
                newmember.LoginName,
                newmember.Text,
                newmember.Email);
            Helpers.SendMail(Settings.EmailNotification, Settings.EmailAdmin, library.GetDictionaryItem("NewMemberSignUp"), sb.ToString());
        }
    }
}
도움이 되었습니까?

해결책

Your specific issue is two fold:

1) You are setting m.getProperty("testField") to the instance of the DropDownList rather than to it's SelectedValue

2) As noted in the comments on the question you had a mis-match in your hardcoded DropDownList values and the values stored in the Umbraco DataType for the testField property.

You can address the second issue more robustly by binding your DropDownList with what Umbraco calls the PreValues stored on the testField DataType is will ensure the available options in the DropDownList match the options defined on the DataType

As of writing this PreValues are stored as an XML fragment on the datatype definition in the following format:

<preValues>
    <preValue id="1">Option 1</preValue>
    <preValue id="2">Option 2</preValue>
    <preValue id="3">Option 3</preValue>
</preValues>

To retrieve these programmatically is a little clunky (IMO); You first you have to obtain the Id of DataType by mousing over the DataType in the umbraco interface and looking in the status bar (you should see something like javascript:openDataType(1111) where 1111 is the Id.

Next call the umbraco.library.GetPreValues() method, passing in the Id obtained above. This method returns an XPathNodeIterator which you can use to get the values in whichever way suits your need such as creation of a Dictionary<string,string> which you can bind to your DropDownList. The following example is taken from Damiaan Peeters blog and adapted ever so slightly.

private static Dictionary<string, string> GetPreValues(int dataTypeId)
{
    XPathNodeIterator preValueRootElementIterator = umbraco.library.GetPreValues(dataTypeId);
    preValueRootElementIterator.MoveNext(); //move to first 
    XPathNodeIterator preValueIterator = preValueRootElementIterator.Current.SelectChildren("preValue", "");
    var retVal = new Dictionary<int, object>();

    while (preValueIterator.MoveNext())        
        retVal.Add(preValueIterator.Current.GetAttribute("id", ""), preValueIterator.Current.Value);

    return retVal;
}

Then in your code behind you can do the following:

tbOrganisation.DataSource = GetPreValues(1111);
tbOrganisation.DataTextField = "Value";
tbOrganisation.DataValueField = "Key";
tbOrganisation.DataBind();
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top