示例#1
0
    public static msPortalPageLayoutContainer GetAppropriatePageLayout(this MemberSuiteObject mso)
    {
        var typeId     = mso.SafeGetValue <string>("Type");
        var objectType = mso.ClassType;

        if (string.IsNullOrWhiteSpace(typeId))
        {
            return(GetDefaultPageLayout(objectType));
        }

        var key = string.Format("GetAppropriatePageLayout::{0}_{1}", objectType, typeId);

        return(SessionManager.Get(key, () =>
        {
            // let's get the type
            using (var api = ConciergeAPIProxyGenerator.GenerateProxy())
            {
                var msoType = api.Get(typeId).ResultValue;
                var layoutId = msoType.SafeGetValue <string>("PortalPageLayout");

                if (string.IsNullOrWhiteSpace(layoutId))
                {
                    return GetDefaultPageLayout(objectType);
                }

                var pageLayout = api.Get(layoutId).ResultValue.ConvertTo <msPortalPageLayoutContainer>();

                return pageLayout;
            }
        }));
    }
    protected void addSearchOperations(SearchOperationGroup group, MemberSuiteObject mso)
    {
        foreach (var searchOperation in group.Criteria)
        {
            SearchOperationGroup sog = searchOperation as SearchOperationGroup;
            if (sog != null)
            {
                addSearchOperations(sog, mso);
                continue;
            }

            string safeFieldName = Formats.GetSafeFieldName(searchOperation.FieldName);

            if (mso.Fields.ContainsKey(safeFieldName))
            {
                continue;
            }

            switch (searchOperation.ValuesToOperateOn.Count)
            {
            case 0:
                mso[safeFieldName] = null;
                break;

            case 1:
                mso[safeFieldName] = searchOperation.ValuesToOperateOn[0];
                break;

            default:
                mso[safeFieldName] = searchOperation.ValuesToOperateOn;
                break;
            }
        }
    }
示例#3
0
    protected void wzEnterInfo_StepChanged(object sender, EventArgs e)
    {
        switch (wzEnterInfo.ActiveStepIndex)
        {
        // MS-5360
        case 0:
            DeleteCurrentForm();
            break;

        case 1:
            CustomFieldSet1.Harvest();
            // MS-5360
            targetInstance      = APIExtensions.SaveObject(targetInstance);
            CurrentFormID.Value = targetInstance["ID"].ToString();
            CustomFieldSet2.MemberSuiteObject = targetInstance;
            CustomFieldSet2.Bind();
            break;

        case 2:
            SubmitForm();
            if (ConciergeAPI.CurrentEntity == null && targetForm.AnonymousSubmissionCompletionUrl != null)
            {
                wzEnterInfo.FinishDestinationPageUrl = targetForm.AnonymousSubmissionCompletionUrl;
            }

            wzEnterInfo.DisplayCancelButton = false;

            break;
        }
    }
示例#4
0
    private void SubmitForm()
    {
        targetInstance = APIExtensions.SaveObject(targetInstance);

        // ok, log an activity
        if (ConciergeAPI.CurrentEntity != null)
        {
            if (targetForm.ActivityType != null)
            {
                msActivity a = CreateNewObject <msActivity>();
                a.Type   = targetForm.ActivityType;
                a.Name   = targetForm.Name;
                a.Date   = DateTime.Now;
                a.Entity = ConciergeAPI.CurrentEntity.ID;
                SaveObject(a);
            }

            // ok, send an email
            if (!string.IsNullOrWhiteSpace(targetForm.ConfirmationEmail))
            {
                using (var api = GetServiceAPIProxy())
                {
                    var emailTemplate = api.Get(targetForm.ConfirmationEmail).ResultValue.ConvertTo <msEmailTemplateContainer>();
                    api.SendTransactionalEmail(emailTemplate.Name, CurrentEntity.ID, null);
                }
            }
        }
    }
    protected void goToResults()
    {
        //Set the output fields
        MultiStepWizards.ViewChapterMembers.SearchManifest.DefaultSelectedFields =
            (from field in dlbOutputFields.Destination.Items
             join manifestField in targetSearchManifest.Fields on field.Value equals manifestField.Name
             select new SearchOutputColumn {
            Name = manifestField.Name, DisplayName = manifestField.Label
        }
            ).ToList();


        //Create a new search builder to define the criteria
        MultiStepWizards.ViewChapterMembers.SearchBuilder = new SearchBuilder(Search.FromManifest(targetSearchManifest));

        //Add the criteria using the search builder
        cfsSearchCriteria.Harvest();
        MemberSuiteObject mso = cfsSearchCriteria.MemberSuiteObject;

        ParseSearchCriteria(targetCriteriaFields, mso, MultiStepWizards.ViewChapterMembers.SearchBuilder);

        string nextUrl = rblOutputFormat.SelectedValue == "download"
                             ? string.Format("~/chapters/ViewChapterMembers_Results.aspx?contextID={0}&download=true", ContextID)
                             : string.Format("~/chapters/ViewChapterMembers_Results.aspx?contextID={0}",
                                             ContextID);

        if (!string.IsNullOrWhiteSpace(Filter))
        {
            nextUrl += "&filter=" + Filter;
        }

        GoTo(nextUrl);
    }
示例#6
0
        /// <summary>
        /// Demonstrates updating a Custom Object record and Inserting a new one
        /// For more information, please see...
        /// https://help.production.membersuite.com/hc/en-us/articles/115002960103-System-Overview-Configuration-How-To-Create-a-Custom-Object
        /// https://help.production.membersuite.com/hc/en-us/articles/115002985646-System-Overview-Configuration-Reference-Create-a-Custom-Object-Field-Descriptions
        /// https://help.production.membersuite.com/hc/en-us/articles/115002985666-System-Overview-Configuration-Custom-Objects
        /// https://help.production.membersuite.com/hc/en-us/articles/115002985586-System-Overview-Configuration-How-To-Edit-a-Custom-Object
        /// https://help.production.membersuite.com/hc/en-us/articles/115002986266-System-Overview-Configuration-How-To-Delete-a-Custom-Object
        /// </summary>
        private static void UpdateCustomObjects()
        {
            using (var api = ConciergeAPIProxyGenerator.GenerateProxy())
            {
                var cusObjSearch = new Search("FakeCustomObject__c");           //You'll need to create your own objects for this to work
                cusObjSearch.AddCriteria(Expr.Equals("Owner.LocalID", 101292)); //In this example, the FakeCustomObject derives from the Individual Object. So we are using the Owner.Local to query the Individual's LocalID and get back a specific FakeCustomObject record
                var cusObjResult = api.GetObjectBySearch(cusObjSearch, null);

                if (cusObjResult.ResultValue != null) //Update existing record
                {
                    var mso = new MemberSuiteObject();
                    mso.Fields["CompanyName__c"] = "TestCompany4";
                    mso.Fields["Description__c"] = "This is a test";
                    mso.Fields["Website__c"]     = "www.test.com";
                    mso.Fields["Name"]           = "test Trans";
                    mso.Fields["Owner"]          = cusObjResult.ResultValue;

                    var saveResult = api.Save(mso);
                }
                else //Insert new record
                {
                    var meta     = api.DescribeObject("FakeCustomObject__c").ResultValue;
                    var instance = MemberSuiteObject.FromClassMetadata(meta).ConvertTo <msCustomObjectInstance>();

                    instance.Owner = cusObjResult.ResultValue.Fields["ID"].ToString();
                    instance.Fields["CompanyName__c"] = "TestCompany4";
                    instance.Fields["Description__c"] = "This is a test";
                    instance.Fields["Website__c"]     = "www.test.com";
                    instance.Fields["Name"]           = "test Trans";

                    var insertResult = api.Save(instance);
                }
            }
        }
示例#7
0
    public static string GetUrlFor(MemberSuiteObject mso)
    {
        if (mso == null)
        {
            throw new ArgumentNullException("mso");
        }

        switch (mso.ClassType)
        {
        case msCommittee.CLASS_NAME:
            return("/committees/ViewCommittee.aspx?contextID=" + mso["ID"]);

        case msChapter.CLASS_NAME:
            return("/chapters/ViewChapter.aspx?contextID=" + mso["ID"]);

        case msSection.CLASS_NAME:
            return("/sections/ViewSection.aspx?contextID=" + mso["ID"]);

        case msOrganizationalLayer.CLASS_NAME:
            return("/organizationallayers/ViewOrganizationalLayer.aspx?contextID=" + mso["ID"]);

        default:
            throw new NotSupportedException("Cannot find url for class type " + mso.ClassType);
        }
    }
示例#8
0
    public void AddReferenceNamesToTargetObject(IConciergeAPIService proxy)
    {
        if (EditMode || PageLayout == null || MemberSuiteObject == null || Metadata == null)
        {
            return;
        }

        foreach (var controlSection in PageLayout.Sections)
        {
            foreach (var controlMetadata in controlSection.LeftControls.Union(controlSection.RightControls))
            {
                if (string.IsNullOrWhiteSpace(controlMetadata.DataSourceExpression) ||
                    !Metadata.Fields.Exists(x => x.Name == controlMetadata.DataSourceExpression))
                {
                    continue;
                }

                FieldMetadata fieldMetadata = Metadata.Fields.Single(x => x.Name == controlMetadata.DataSourceExpression);
                if (fieldMetadata.DataType != FieldDataType.Reference)
                {
                    continue;
                }

                string value = MemberSuiteObject.SafeGetValue(controlMetadata.DataSourceExpression) as string;

                if (string.IsNullOrWhiteSpace(value))
                {
                    continue;
                }

                MemberSuiteObject referencedObject = proxy.Get(value).ResultValue;
                MemberSuiteObject[controlMetadata.DataSourceExpression + "_Name__transient"] = referencedObject["Name"];
            }
        }
    }
    protected void btnSearch_Click(object sender, EventArgs e)
    {
        var searchBuilder = new SearchBuilder(Search.FromManifest(MultiStepWizards.SearchResumeBank.SearchManifest));

        MultiStepWizards.SearchResumeBank.SearchBuilder =
            searchBuilder;

        cfsSearchCriteria.Harvest();
        MemberSuiteObject mso = cfsSearchCriteria.MemberSuiteObject;

        string keywords = tbKeywords.Text;

        if (!string.IsNullOrWhiteSpace(keywords))
        {
            searchBuilder.AddOperation(
                new Keyword {
                FieldName = "File", ValuesToOperateOn = new List <object> {
                    keywords
                }
            },
                SearchOperationGroupType.And);
        }


        ParseSearchCriteria(targetCriteriaFields, mso, searchBuilder);

        string nextUrl = "~/careercenter/SearchResume_Results.aspx";

        if (rblOutputFormat.SelectedValue == "zip")
        {
            nextUrl += "?output=zip";
        }
        GoTo(nextUrl);
    }
示例#10
0
 public static MemberSuiteObject SaveObject(MemberSuiteObject msoObjectToSave)
 {
     using (var api = ConciergeAPIProxyGenerator.GenerateProxy())
     {
         var result = api.Save(msoObjectToSave);
         return(result.ResultValue);
     }
 }
示例#11
0
    protected msMembershipLeader ConvertLeaderSearchResult(SearchResult searchResult)
    {
        if (searchResult == null || searchResult.Table == null || searchResult.Table.Rows.Count == 0)
        {
            return(null);
        }

        return(MemberSuiteObject.FromDataRow(searchResult.Table.Rows[0]).ConvertTo <msMembershipLeader>());
    }
示例#12
0
    private void executePotentialDuplicatesSearch(IConciergeAPIService serviceProxy)
    {
        var config = serviceProxy.GetAssociationConfiguration().ResultValue;;

        if (config != null && config.SafeGetValue <bool>("DisableDuplicateCheckPortal"))    //dupe check disabled
        {
            return;
        }

        //Get the City/State from the Postal Code - This is better for duplicate matching because it removes zip+4 from the equation
        Address address = new Address();

        address.PostalCode = targetRequest.PostalCode;

        try
        {
            using (IConciergeAPIService proxy = GetConciegeAPIProxy())
            {
                var apiResult = proxy.PopulateCityStateFromPostalCode(address);
                address = apiResult.ResultValue;
            }
        }
        catch
        {
            // don't want to do anything if this fails
        }

        MemberSuiteObject mso = new MemberSuiteObject();

        mso.Fields.Add("FirstName", targetRequest.FirstName);
        mso.Fields.Add("LastName", targetRequest.LastName);
        mso.Fields.Add("City", address.City);
        mso.Fields.Add("State", address.State);
        mso.ClassType = "Individual";

        Search duplicateSearch = new Search();

        duplicateSearch.AddOutputColumn("ID");
        duplicateSearch.AddOutputColumn("FirstName");
        duplicateSearch.AddOutputColumn("LastName");
        duplicateSearch.AddOutputColumn("EmailAddress");
        duplicateSearch.AddOutputColumn("_Preferred_Address_Line1");
        duplicateSearch.AddOutputColumn("_Preferred_Address_City");
        duplicateSearch.AddOutputColumn("_Preferred_Address_State");
        duplicateSearch.AddOutputColumn("_Preferred_Address_PostalCode");
        duplicateSearch.AddSortColumn("FirstName");
        duplicateSearch.AddSortColumn("LastName");

        SearchResult duplicateResult;


        duplicateResult = serviceProxy.FindPotentialDuplicates(mso, null, duplicateSearch, 0, null).ResultValue;

        hideInfo(duplicateResult.Table);
        dvDuplicates = new DataView(duplicateResult.Table);
    }
示例#13
0
    public static string LogException(Exception ex, Uri u)
    {
        //if there's no http context do not log
        //If we don't know what association this is we can't log either because a auditlog requires a wall to save
        if (HttpContext.Current == null ||   CurrentAssociation == null)
            return null;

        try
        {
            NameValueCollection queryStringVariables = new NameValueCollection();
            if (u != null)
                queryStringVariables = HttpUtility.ParseQueryString(u.Query);
            string contextId = queryStringVariables["contextID"];

            MemberSuiteObject contextObject = null;

            using (IConciergeAPIService proxy = ConciergeAPIProxyGenerator.GenerateProxy())
            {
                //Get the current user details from the Concierge API
                LoginResult loginResult = proxy.WhoAmI().ResultValue;
                msUser currentUser = loginResult.PortalUser == null ? loginResult.User.ConvertTo<msUser>() : loginResult.PortalUser.ConvertTo<msUser>();

                //If there's a specified context then get the details on the context object
                if (!string.IsNullOrWhiteSpace(contextId))
                {
                    ConciergeResult<MemberSuiteObject> getResult = proxy.Get(contextId);
                    if (getResult.Success)
                        contextObject = getResult.ResultValue;
                }

                msAuditLog auditLog = constructAuditLog(currentUser, ex, contextId, contextObject);
                ConciergeResult<MemberSuiteObject> saveResult = proxy.RecordErrorAuditLog(auditLog);
                
                if (saveResult.Success)
                    return saveResult.ResultValue.SafeGetValue<string>("ID");
            }
        }
        catch(Exception e)
        {
            Console.WriteLine("Unable to log exception.");
            Console.WriteLine(e.ToString());
            Console.WriteLine(ex.ToString());
        }

        return null;
    }
示例#14
0
    protected override void InitializeTargetObject()
    {
        base.InitializeTargetObject();
        targetForm = LoadObjectFromAPI <msCustomObjectPortalForm>(ContextID);
        if (targetForm == null)
        {
            GoToMissingRecordPage();
        }

        string entityID = null;

        if (ConciergeAPI.CurrentEntity != null)
        {
            entityID = ConciergeAPI.CurrentEntity.ID;
        }

        using (var api = GetServiceAPIProxy())
            targetFormManifest = api.DescribePortalForm(targetForm.ID, entityID).ResultValue;

        // MS-5922 - only check this on initial load so that it will not fail on completion of creation of last allowed instance
        if (!IsPostBack)
        {
            if (!targetFormManifest.CanCreate)
            {
                GoTo("/AccessDenied.aspx");
            }
        }

        if (ConciergeAPI.CurrentEntity == null && !targetForm.AllowAnonymousSubmissions)  // we need them to go through registration
        {
            GoTo("~/profile/CreateAccount_BasicInfo.aspx?t=PortalForm&formID=" + targetForm.ID);
            return;
        }

        // ok, so we allow anonymous submissions here
        // MS-5360
        if (string.IsNullOrWhiteSpace(CurrentFormID.Value))
        {
            targetInstance          = MetadataLogic.CreateNewObject(targetFormManifest.UnderlyingObjectName);
            targetInstance["Owner"] = entityID;
        }
        else
        {
            targetInstance = APIExtensions.LoadObjectFromAPI(CurrentFormID.Value);
        }
    }
    protected void setTimeSlots()
    {
        timeslots = new List <msSessionTimeSlot>();

        using (var api = GetServiceAPIProxy())
        {
            Search sTimeSlots = new Search {
                Type = msSessionTimeSlot.CLASS_NAME
            };
            sTimeSlots.AddOutputColumn("ID");
            sTimeSlots.AddOutputColumn("Name");
            sTimeSlots.AddOutputColumn("StartTime");
            sTimeSlots.AddOutputColumn("EndTime");
            sTimeSlots.AddOutputColumn("AllowMultipleSessions");
            sTimeSlots.AddCriteria(Expr.Equals(msSessionTimeSlot.FIELDS.Event, targetEvent.ID));
            sTimeSlots.AddSortColumn("StartTime");
            sTimeSlots.AddSortColumn("Name");


            foreach (DataRow drResult in api.GetSearchResult(sTimeSlots, 0, null).Table.Rows)
            {
                timeslots.Add(MemberSuiteObject.FromDataRow(drResult).ConvertTo <msSessionTimeSlot>());
            }
        }


        pnlSessions.Visible = false;

        // add the NULL timeslot, for sessions that have not been placed into time slots
        timeslots.Insert(0, new msSessionTimeSlot {
            Name = "Events Happening During this Event", ID = null
        });

        // if there's one session, one session at all, then the panel is shown
        rptSessions.DataSource = timeslots;
        rptSessions.DataBind();

        if (targetRegistrationFee.MaximumNumberOfSessions != null)
        {
            cvMaxSession.ErrorMessage =
                string.Format(
                    "You have selected too many sessions. When registering using the '{0}' fee, you are allowed a maximum of {1} sessions.",
                    targetRegistrationFee.Name, targetRegistrationFee.MaximumNumberOfSessions.Value);
        }
    }
    protected void btnSearch_Click(object sender, EventArgs e)
    {
        MultiStepWizards.SearchDirectory.SearchBuilder =
            new SearchBuilder(Search.FromManifest(MultiStepWizards.SearchDirectory.SearchManifest));

        cfsSearchCriteria.Harvest();
        MemberSuiteObject mso = cfsSearchCriteria.MemberSuiteObject;

        ParseSearchCriteria(targetCriteriaFields, mso, MultiStepWizards.SearchDirectory.SearchBuilder);

        // MS-2152 - we need to make sure we're excluded terminated folks, and opt out
        Search s = MultiStepWizards.SearchDirectory.SearchBuilder.Search;

        SearchOperationGroup sog = new SearchOperationGroup();

        sog.Criteria.AddRange(s.Criteria);
        s.Criteria.Clear();
        s.GroupType = SearchOperationGroupType.And;


        s.AddCriteria(Expr.Equals(msMembership.FIELDS.ReceivesMemberBenefits, true));
        s.AddCriteria(Expr.Equals(msMembership.FIELDS.MembershipDirectoryOptOut, false));

        var sogTerminationDate = new SearchOperationGroup {
            GroupType = SearchOperationGroupType.Or
        };

        sogTerminationDate.Criteria.Add(Expr.IsBlank(msMembership.FIELDS.TerminationDate));
        sogTerminationDate.Criteria.Add(Expr.IsGreaterThan(msMembership.FIELDS.TerminationDate, DateTime.Today));
        s.AddCriteria(sogTerminationDate);

        // MS-5850 - Control whether or not inherited memberships are included
        if (!PortalConfiguration.Current.MembershipDirectoryIncludeInheritedMemberships)
        {
            s.AddCriteria(Expr.Equals(msMembership.FIELDS.IsInherited, false));
        }

        s.AddCriteria(sog); // now, add the criteria

        GoTo("~/directory/SearchDirectory_Results.aspx");
    }
示例#17
0
    /// <summary>
    /// Initializes the target object for the page
    /// </summary>
    /// <remarks>Many pages have "target" objects that the page operates on. For instance, when viewing
    /// an event, the target object is an event. When looking up a directory, that's the target
    /// object. This method is intended to be overriden to initialize the target object for
    /// each page that needs it.</remarks>
    protected override void InitializeTargetObject()
    {
        base.InitializeTargetObject();

        targetRelationship = LoadObjectFromAPI <msRelationship>(ContextID);
        if (targetRelationship == null)
        {
            GoToMissingRecordPage();
            return;
        }

        targetRelationshipType = LoadObjectFromAPI <msRelationshipType>(targetRelationship.Type);
        if (targetRelationshipType == null)
        {
            GoToMissingRecordPage();
            return;
        }

        leftSide  = APIExtensions.LoadObjectFromAPI(targetRelationship.LeftSide);
        rightSide = APIExtensions.LoadObjectFromAPI(targetRelationship.RightSide);
    }
示例#18
0
    protected void loadLeaders()
    {
        //If there's no chapters on this membership then the owner can't be a chapter leader
        if (dvChapterMembership.Count == 0)
        {
            leaders = new Dictionary <string, msMembershipLeader>();
            return;
        }

        Search sLeaders = GetChapterLeaderSearch(null);

        sLeaders.AddOutputColumn("Chapter");
        sLeaders.Criteria.Clear();
        sLeaders.AddCriteria(Expr.Equals("Individual", ConciergeAPI.CurrentEntity.ID));

        SearchOperationGroup chapterGroup = new SearchOperationGroup();

        chapterGroup.FieldName = "Chapter";
        chapterGroup.GroupType = SearchOperationGroupType.Or;

        foreach (DataRowView drvChapterMembership in dvChapterMembership)
        {
            chapterGroup.Criteria.Add(Expr.Equals("Chapter", drvChapterMembership["Chapter"].ToString()));
        }

        sLeaders.AddCriteria(chapterGroup);

        SearchResult srLeaders = APIExtensions.GetSearchResult(sLeaders, 0, null);

        leaders = new Dictionary <string, msMembershipLeader>();
        foreach (DataRow drLeader in srLeaders.Table.Rows)
        {
            //Store and clear the chapter to avoid a casting exception
            string chapterId = drLeader["Chapter"].ToString();
            drLeader["Chapter"] = DBNull.Value;

            msMembershipLeader leader = MemberSuiteObject.FromDataRow(drLeader).ConvertTo <msMembershipLeader>();
            leaders[chapterId] = leader;
        }
    }
        public object BeforeCall(string operationName, object[] inputs)
        {
            if (inputs == null)
            {
                return(null);
            }

            // we need to replace any items that derive from MemberSuiteObject
            // with the clean MemberSuite object equivalents, otherwise the
            // Data Contract Serializer will freak out
            for (var i = 0; i < inputs.Length; i++)
            {
                var input = inputs[i];


                if (input == null || !typeof(MemberSuiteObject).IsAssignableFrom(input.GetType()))
                {
                    continue;
                }

                var mso = MemberSuiteObject.ConvertToMemberSuiteObject(((MemberSuiteObject)input));

                // remove all transient fields
                if (mso.Fields != null)
                {
                    foreach (var keys in mso.Fields.Keys.ToList().FindAll(k => k.EndsWith("__transient")))
                    {
                        mso.Fields.Remove(keys);
                    }
                }

                inputs[i] = mso;
            }

            return(null);
        }
示例#20
0
 public static msPortalPageLayoutContainer GetDefaultPageLayout(this MemberSuiteObject mso)
 {
     return(GetDefaultPageLayout(mso.ClassType));
 }
        public override void Run()
        {
            /* The purpose of this sample is to show you how to use the API to execute a portal login
             * on behalf of an individual, and once that portal login is completed, how to query on a member's status.
             * We reuse some of what's in DeterminingMembershipStatus here.
             */

            // First, we need to prepare the proxy with the proper security settings.
            // This allows the proxy to generate the appropriate security header. For more information
            // on how to get these settings, see http://api.docs.membersuite.com in the Getting Started section
            if (!ConciergeAPIProxyGenerator.IsSecretAccessKeySet)
            {
                ConciergeAPIProxyGenerator.SetAccessKeyId(ConfigurationManager.AppSettings["AccessKeyID"]);
                ConciergeAPIProxyGenerator.SetSecretAccessKey(ConfigurationManager.AppSettings["SecretAccessKey"]);
                ConciergeAPIProxyGenerator.AssociationId = ConfigurationManager.AppSettings["AssociationID"];
            }

            // ok, let's generate our API proxy
            using (var api = ConciergeAPIProxyGenerator.GenerateProxy())
            {
                Console.WriteLine(
                    "Please enter login credentials. If you don't have specific credentials, try 'test' for both the user and password to get Terry Smith.");
                Console.WriteLine();
                Console.WriteLine("Please enter the username and hit ENTER.");
                string username = Console.ReadLine();

                Console.WriteLine("Please enter the password and hit ENTER.");
                string password = Console.ReadLine();

                ConciergeResult <LoginResult> portalLoginResult = api.LoginToPortal(username, password);

                if (!portalLoginResult.Success)
                {
                    Console.WriteLine("Portal login failed with this error: " + portalLoginResult.FirstErrorMessage);
                    return;
                }

                Console.WriteLine("Portal login successful - accessing member information...");

                // this is the "entity" that you've logged in as.
                // remember an entity is either an organization OR an individual - it's a base class.
                MemberSuiteObject entity = portalLoginResult.ResultValue.PortalEntity;

                // now, let's get that entity's ID
                string entityID = entity.SafeGetValue <string>("ID");

                // there's a lot of confusion between the different types of users, so let's list them
                Console.WriteLine();
                Console.WriteLine("Users");
                Console.WriteLine("-----------------------------");
                Console.WriteLine();
                Console.WriteLine("API User: {0} - this is the security context that your application is using.",
                                  portalLoginResult.ResultValue.User["Name"]);
                Console.WriteLine(
                    "Portal User: {0} - this is the security context that you are logging your member in as. It's linked to the actual member record via the Owner property.",
                    portalLoginResult.ResultValue.PortalUser["Name"]);
                Console.WriteLine(
                    "Individual/Organization: {0} - this is the entity record that the portal user is tied to. ",
                    portalLoginResult.ResultValue.PortalEntity["Name"]);
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine("The owner of the login has an ID of '{0}' - accessing...",
                                  entityID);

                // ok, let's get the membership status
                string msql = string.Format(
                    "select TOP 1 FirstName, LocalID, LastName, Membership.Type.Name, Membership.PrimaryChapter.Name, Membership.ExpirationDate, Membership.ReceivesMemberBenefits from Individual where ID = '{0}' order by LastName",
                    entityID);

                var result = api.ExecuteMSQL(msql, 0, null);

                if (!result.Success)
                {
                    Console.WriteLine("Search failed: {0}", result.FirstErrorMessage);
                    return;
                }

                DataRow resultRow = result.ResultValue.SearchResult.Table.Rows[0];
                // we know there's only one row, since the ID is unqiue
                Console.WriteLine("ID: " + resultRow["LocalID"]);
                Console.WriteLine("First Name: " + resultRow["FirstName"]);
                Console.WriteLine("Last Name: " + resultRow[msIndividual.FIELDS.LastName]);
                // <--- this is how you would use constants, which is the better way to go
                Console.WriteLine("Member? " + resultRow["Membership.ReceivesMemberBenefits"]);
                Console.WriteLine("Member Type: " + resultRow["Membership.Type.Name"]);
                Console.WriteLine("Chapter: " + resultRow["Membership.PrimaryChapter.Name"]);
                Console.WriteLine("Expiration Date: " + resultRow["Membership.ExpirationDate"]);
                Console.WriteLine("Search successful: {0} results returned.",
                                  result.ResultValue.SearchResult.TotalRowCount);
            }
        }
示例#22
0
 public static ClassMetadata DescribeObject(this MemberSuiteObject mso)
 {
     return(DescribeObject(mso.ClassType));
 }
        public override void Run()
        {
            /* This sample is going to login to the association and create a record with a name,
             * email, and birthday that you specify. Once saved, the system will display the ID
             * of the individual created, the age (which MemberSuite calculates), and will automatically
             * launch the 360 view of that record in the web browser */

            // First, we need to prepare the proxy with the proper security settings.
            // This allows the proxy to generate the appropriate security header. For more information
            // on how to get these settings, see http://api.docs.membersuite.com in the Getting Started section
            if (!ConciergeAPIProxyGenerator.IsSecretAccessKeySet)
            {
                ConciergeAPIProxyGenerator.SetAccessKeyId(ConfigurationManager.AppSettings["AccessKeyID"]);
                ConciergeAPIProxyGenerator.SetSecretAccessKey(ConfigurationManager.AppSettings["SecretAccessKey"]);
                ConciergeAPIProxyGenerator.AssociationId = ConfigurationManager.AppSettings["AssociationID"];
            }

            // ok, let's generate our API proxy
            using (var api = ConciergeAPIProxyGenerator.GenerateProxy())
            {
                // now, we want to create a new individual
                // First, we need to get a description of the individual
                // The description will tell the client SDK how to "build" the object; in other words, what the fields are
                // and what the default values are. So if you set a default value for LastName to 'Smith', the Describe
                // operation will have that in the metadata. When you construct the object, it will then have the last name
                // defaulted to 'Smith'
                ClassMetadata meta = api.DescribeObject("Individual").ResultValue;

                // now, create our MemberSuiteObject
                MemberSuiteObject mso = MemberSuiteObject.FromClassMetadata(meta);

                /* it's always easier to use the typed MemberSuiteObject
                *
                * You could just instantiate this directly by saying:
                *
                *      msIndividual p = new msIndividual();
                *
                * This would work - but without the class metadata, the object would not respect any of the defaults
                * that are set up. It would be a totally blank object.*/
                msIndividual person = mso.ConvertTo <msIndividual>();

                // now, you don't have to use dictionaries and string keys, you can access the object directly

                Console.WriteLine("Please enter a first name and press ENTER.");
                person.FirstName = Console.ReadLine();

                Console.WriteLine("Please enter a last name and press ENTER.");
                person.LastName = Console.ReadLine();

                person.EmailAddress = "*****@*****.**";

                Console.WriteLine("Please enter a birthdate and press ENTER.");
                string   date = Console.ReadLine();
                DateTime dob;
                if (!DateTime.TryParse(date, out dob))
                {
                    Console.WriteLine("Invalid birthdate... exiting...");
                    return;
                }

                person.DateOfBirth = dob;

                // ok, so we can save this now
                var result = api.Save(person);

                if (!result.Success)
                {
                    throw new ApplicationException("Unable to save: " + result.FirstErrorMessage);
                }

                msIndividual newPerson = result.ResultValue.ConvertTo <msIndividual>();

                Console.WriteLine("Successfully saved individual #{0} - {1}. Age is {2}. ", newPerson.LocalID,
                                  newPerson.Name, newPerson.Age);
                Console.WriteLine("URL is:");
                Console.WriteLine("https://console.production.membersuite.com/app/console/individual/view?c=" +
                                  newPerson.ID);
            }
        }
    private void setupChapters(msMembershipOrganization mo, msMembershipDuesProduct product)
    {
        ChapterMode cm = mo.ChapterMode;

        // check to see if we need to override on product
        if (product[msMembershipDuesProduct.FIELDS.ChapterMode] != null)
        {
            cm = product.SafeGetValue <ChapterMode>(msMembershipDuesProduct.FIELDS.ChapterMode);
        }

        switch (cm)
        {
        case ChapterMode.ChaptersDisabled:
            divChapter.Visible = false;     // don't show it
            return;

        case ChapterMode.MemberJoinsOneChapter:
            divChapter.Visible            = true;
            divAdditionalChapters.Visible = false;
            break;

        case ChapterMode.MemberCanJoinMultipleChapters:
            divChapter.Visible            = true;
            divAdditionalChapters.Visible = true;
            break;
        }

        // let's pull all of the chapters
        List <NameValueStringPair> tblChapters;

        using (var api = GetServiceAPIProxy())
        {
            tblChapters = api.GetApplicableChaptersForMembershipType(targetMembership.Type).ResultValue;
        }
        ddlSelectChapter.DataSource     = tblChapters;
        ddlSelectChapter.DataTextField  = "Name";
        ddlSelectChapter.DataValueField = "Value";
        ddlSelectChapter.DataBind();


        if (divAdditionalChapters.Visible)    // bind the list box, too
        {
            lbAdditionalChapters.DataSource     = tblChapters;
            lbAdditionalChapters.DataTextField  = "Name";
            lbAdditionalChapters.DataValueField = "Value";
            lbAdditionalChapters.DataBind();
        }

        ddlSelectChapter.Items.Insert(0, new ListItem("---- Select a Chapter ----", ""));

        // ok - are we suggesting a chapter based on zip code?
        var cpm = mo.ChapterPostalCodeMappingMode;

        // check to see if we need to override on product
        if (product[msMembershipDuesProduct.FIELDS.ChapterPostalCodeMappingMode] != null)
        {
            cpm = product.SafeGetValue <ChapterPostalCodeMappingMode>(msMembershipDuesProduct.FIELDS.ChapterPostalCodeMappingMode);
        }

        if (cpm != ChapterPostalCodeMappingMode.Disabled)
        {
            MemberSuiteObject msoChapter = null;
            using (var api = GetServiceAPIProxy())
                msoChapter = api.SuggestChapter(mo.ID, targetEntity.ID).ResultValue;

            if (msoChapter != null)   // have have a chapter
            {
                ListItem li = ddlSelectChapter.Items.FindByValue(msoChapter.SafeGetValue <string>("ID"));

                if (li != null)   // we have a match
                {
                    li.Selected = true;

                    if (cpm == ChapterPostalCodeMappingMode.Assign)
                    {
                        ddlSelectChapter.Enabled  = false; // can't be changed
                        trChapterAssigned.Visible = true;
                    }

                    // if a chapter matches, that's it, we're done
                    return;
                }
            }
        }


        // let's try and set to the default chapter
        if (targetMembership != null && targetMembership.Chapters != null)
        {
            // find the primary


            var cPrimary = (targetMembership.Chapters.Find(x => x.IsPrimary));

            // MS-4984 - only set the default chapter if it's set up in the mem org
            if (cPrimary != null && mo.MembersShouldInheritPreviousChapterUponRenewal)
            {
                ddlSelectChapter.SafeSetSelectedValue(cPrimary.Chapter);
            }


            // now, let's try to select the additional
            if (divAdditionalChapters.Visible)
            {
                foreach (var c in targetMembership.Chapters)
                {
                    if ((c.ExpirationDate == null || c.ExpirationDate == targetMembership.ExpirationDate) &&
                        (cPrimary == null || c.Chapter != cPrimary.Chapter))
                    {
                        ListItem li = lbAdditionalChapters.Items.FindByValue(c.Chapter);
                        if (li != null)
                        {
                            li.Selected = true;
                        }
                    }
                }
            }
        }
    }
示例#25
0
 public static MemberSuiteObject CreateNewObject(string className)
 {
     return(MemberSuiteObject.FromClassMetadata(DescribeObject(className)));
 }
示例#26
0
    protected void btnPlaceOrder_Click(object sender, EventArgs e)
    {
        const string ContentSuffix = "_Contents";

        if (!IsValid)
        {
            return;
        }

        lock (threadLock)
        {
            if (targetOrder == null)
            {
                Refresh();
                return;
            }

            targetOrder.Notes = tbNotesComments.Text;

            // add cross sell
            var csi = MultiStepWizards.PlaceAnOrder.CrossSellItems;
            if (csi != null && csi.Count > 0)
            {
                targetOrder.LineItems.AddRange(csi.FindAll(x => x.Quantity != 0)); // add any cross sell items
            }
            using (var api = GetServiceAPIProxy())
            {
                var msPayload = new List <MemberSuiteObject>();
                // Go over line items and generate payoads for all attachments realted fields.
                foreach (var lineItem in targetOrder.LineItems)
                {
                    // We're looking for _Content only. _Content has to be of MemberSuiteFile type.
                    var attachments = lineItem.Fields.Where(f => f.Key.EndsWith(ContentSuffix) && IsNonEmptyMemberSuiteFile(f.Value))
                                      .Select(c =>
                    {
                        var msf = (MemberSuiteFile)c.Value;
                        // Generate ID
                        var fileId = api.GenerateIdentifer("File").ResultValue;
                        // Create ms object...
                        var mso                     = new MemberSuiteObject();
                        mso.ClassType               = "File";
                        mso.Fields["ID"]            = fileId;
                        mso.Fields["FileContents"]  = msf.FileContents;
                        mso.Fields["Name"]          = msf.FileName;
                        mso.Fields["ContentLength"] = msf.FileContents.Length;

                        return(new { Key = c.Key.Replace(ContentSuffix, string.Empty), FileId = fileId, File = mso });
                    });

                    if (attachments.Count() > 0)
                    {
                        foreach (var a in attachments)
                        {
                            // JES product fullfillment logic expects an xml file to save.. Copy relevant values into MemberSuiteFile & serializer it to send to JES (MS-6424)
                            //
                            var ms = new MemberSuiteFile();
                            ms.FileName     = a.File.SafeGetValue <string>("Name");
                            ms.FileContents = a.File.SafeGetValue <byte[]>("FileContents");
                            ms.FileType     = a.File.SafeGetValue <string>("FileType"); //we don't currently have this


                            var xml = MemberSuite.SDK.Utilities.Xml.Serialize(ms);


                            lineItem.Options.Add(new NameValueStringPair {
                                Name = a.Key, Value = xml
                            });
                            // Add according ms file to payload.
                            msPayload.Add(a.File);
                        }
                    }
                }

                OrderPayload payload = MultiStepWizards.PlaceAnOrder.Payload;

                if (msPayload.Count() > 0)
                {
                    if (payload == null)
                    {
                        payload = new OrderPayload();
                    }

                    if (payload.ObjectsToSave == null)
                    {
                        payload.ObjectsToSave = new List <MemberSuiteObject>();
                    }

                    payload.ObjectsToSave.AddRange(msPayload);
                }

                if (targetOrder.Date == DateTime.MinValue)
                {
                    targetOrder.Date = DateTime.Now;
                }

                var processedOrderPacket = api.PreProcessOrder(targetOrder).ResultValue;
                cleanOrder       = processedOrderPacket.FinalizedOrder.ConvertTo <msOrder>();
                cleanOrder.Total = processedOrderPacket.Total;

                //if (string.IsNullOrWhiteSpace(cleanOrder.BillingEmailAddress))
                //    cleanOrder.BillingEmailAddress = CurrentUser.EmailAddress;

                if (MultiStepWizards.RegisterForEvent.IsSessionSwap)
                {
                    var swapResult = api.SwapSessions(
                        MultiStepWizards.RegisterForEvent.SwapRegistrationID,
                        MultiStepWizards.RegisterForEvent.SessionsToCancel,
                        cleanOrder);

                    if (!swapResult.Success)
                    {
                        QueueBannerError(swapResult.FirstErrorMessage);
                    }
                    else
                    {
                        QueueBannerMessage("Session updates complete.");
                    }

                    MultiStepWizards.RegisterForEvent.Clear();
                    GoTo(MultiStepWizards.PlaceAnOrder.OrderCompleteUrl ?? "OrderComplete.aspx");
                }

                var processInfo = api.ProcessOrder(cleanOrder, payload).ResultValue;


                // let's wait for the order
                var processStatus = OrderUtilities.WaitForOrderToComplete(api, processInfo);

                if (processStatus.Status == LongRunningTaskStatus.Failed)
                {
                    throw new ConciergeClientException(
                              MemberSuite.SDK.Concierge.ConciergeErrorCode.IllegalOperation,
                              processStatus.AdditionalInfo);
                }

                string url = MultiStepWizards.PlaceAnOrder.OrderCompleteUrl ?? "OrderComplete.aspx";
                if (url.Contains("?"))
                {
                    url += "&";
                }
                else
                {
                    url += "?";
                }


                targetOrder = null;

                // clear the cart
                if (isTransient)
                {
                    // clear out the items
                    if (MultiStepWizards.PlaceAnOrder.TransientShoppingCart != null)
                    {
                        MultiStepWizards.PlaceAnOrder.TransientShoppingCart.LineItems.Clear();
                    }

                    MultiStepWizards.PlaceAnOrder.TransientShoppingCart = null;
                }
                else
                {
                    MultiStepWizards.PlaceAnOrder.ShoppingCart       = null;
                    MultiStepWizards.PlaceAnOrder.RecentlyAddedItems = null;
                }

                MultiStepWizards.PlaceAnOrder.CrossSellItems = null;



                MultiStepWizards.PlaceAnOrder.EditOrderLineItem                    = null; // clear this out
                MultiStepWizards.PlaceAnOrder.EditOrderLineItemProductName         = null; // clear this out
                MultiStepWizards.PlaceAnOrder.EditOrderLineItemProductDemographics = null; // clear this out
                MultiStepWizards.PlaceAnOrder.OrderConfirmationPacket              = null;

                if (processStatus.Status == LongRunningTaskStatus.Running)
                {
                    // MS-5204. Don't create job posting here. If JES is down then, job posting will be created
                    // during order processing. Otherwise we'll endup with duplicate job postings.
                    // hack - let's save the job posting
                    //if (MultiStepWizards.PostAJob.JobPosting != null)
                    //    SaveObject(MultiStepWizards.PostAJob.JobPosting);

                    MultiStepWizards.PostAJob.JobPosting = null;

                    GoTo("OrderQueued.aspx");
                }

                var order = LoadObjectFromAPI <msOrder>(processStatus.WorkflowID);
                QueueBannerMessage(string.Format("Order #{0} was processed successfully.",
                                                 order.SafeGetValue <long>(
                                                     msLocallyIdentifiableAssociationDomainObject.FIELDS.LocalID)));

                url += "orderID=" + order.ID;

                if (!url.Contains("contextID="))
                {
                    url += "&contextID=" + order.ID;
                }

                GoTo(url);
            }
        }
    }
示例#27
0
    private static msAuditLog constructAuditLog(msUser currentUser, Exception ex, string contextId, MemberSuiteObject contextObject)
    {
        msAuditLog result = new msAuditLog();
        result.AffectedRecord_ID = contextId;
        result.Type = AuditLogType.Error;

        if (currentUser != null)
            result.Actor = currentUser.ID;

        if (contextObject != null)
        {
            result.AffectedRecord_Type = contextObject.ClassType;
            result.AffectedRecord_Name = contextObject.SafeGetValue<string>("Name");
        }

        result.Description = ex.ToString();

        return result;
    }
示例#28
0
    protected void ParseSearchCriteria(List <FieldMetadata> targetCriteriaFields, MemberSuiteObject criteria, SearchBuilder sb)
    {
        foreach (var fieldMetadata in targetCriteriaFields)
        {
            string fieldName = Formats.GetSafeFieldName(fieldMetadata.Name);
            bool   found     = false;

            if (_isValidRange(criteria.SafeGetValue(fieldName + "__from")))
            {
                // let's create a greater than
                sb.AddOperation(Expr.IsGreaterThanOrEqualTo(fieldMetadata.Name, criteria[fieldName + "__from"]), SearchOperationGroupType.And);
                found = true;
            }

            if (_isValidRange(criteria.SafeGetValue(fieldName + "__to")))
            {
                // let's create a less than
                sb.AddOperation(Expr.IsLessThanOrEqual(fieldMetadata.Name, criteria[fieldName + "__to"]), SearchOperationGroupType.And);
                found = true;
            }

            if (found || !criteria.Fields.ContainsKey(fieldName))
            {
                continue;
            }

            var fieldValue = criteria.Fields[fieldName];
            if (fieldValue == null)
            {
                continue;
            }

            SearchOperation so = new Equals(); //default
            so.ValuesToOperateOn = new List <object> {
                fieldValue
            };

            if (fieldValue is string)
            {
                string fieldValueAsString = (string)fieldValue;
                if (String.IsNullOrWhiteSpace(fieldValueAsString))
                {
                    continue;
                }

                if (fieldMetadata.DataType == FieldDataType.Boolean)
                {
                    bool b = false;
                    if (Boolean.TryParse(fieldValueAsString, out b))
                    {
                        so.ValuesToOperateOn = new List <object>()
                        {
                            b
                        }
                    }
                    ;
                }
                else
                {
                    so = new Contains(); //string should use contains instead of equals
                    so.ValuesToOperateOn = new List <object>()
                    {
                        fieldValueAsString.Trim()
                    };
                }
            }

            if (fieldValue is List <string> )
            {
                List <string> fieldValueAsList = fieldValue as List <string>;
                if (fieldValueAsList.Count == 0)
                {
                    continue;
                }

                so = new ContainsOneOfTheFollowing(); //Lists just look for one hit
                List <object> values = new List <object>();
                values.AddRange(fieldValueAsList);

                so.ValuesToOperateOn = values;
            }

            so.FieldName = fieldMetadata.Name;

            sb.AddOperation(so, SearchOperationGroupType.And);
        }
    }
        public override void Run()
        {
            /* This sample is going to login to the association and create a record with a name,
             * email, and birthday that you specify. Once saved, the system will display the ID
             * of the individual created, the age (which MemberSuite calculates), and will automatically
             * launch the 360 view of that record in the web browser */

            // First, we need to prepare the proxy with the proper security settings.
            // This allows the proxy to generate the appropriate security header. For more information
            // on how to get these settings, see http://api.docs.membersuite.com in the Getting Started section
            if (!ConciergeAPIProxyGenerator.IsSecretAccessKeySet)
            {
                ConciergeAPIProxyGenerator.SetAccessKeyId(ConfigurationManager.AppSettings["AccessKeyID"]);
                ConciergeAPIProxyGenerator.SetSecretAccessKey(ConfigurationManager.AppSettings["SecretAccessKey"]);
                ConciergeAPIProxyGenerator.AssociationId = ConfigurationManager.AppSettings["AssociationID"];
            }

            // ok, let's generate our API proxy
            using (var api = ConciergeAPIProxyGenerator.GenerateProxy())
            {
                // now, we want to create a new individual
                // First, we need to get a description of the individual
                // The description will tell the client SDK how to "build" the object; in other words, what the fields are
                // and what the default values are. So if you set a default value for LastName to 'Smith', the Describe
                // operation will have that in the metadata. When you construct the object, it will then have the last name
                // defaulted to 'Smith'
                var meta = api.DescribeObject(CustomActivityName).ResultValue;

                if (meta == null)
                {
                    var classDef = new MemberSuiteObject {
                        ClassType = msCustomObject.CLASS_NAME
                    };
                    classDef.Fields[msCustomObject.FIELDS.ClassDefinition] = new ClassMetadata
                    {
                        Name        = CustomActivityName,
                        Label       = "Custom Activity",
                        LabelPlural = "Custom Activities",
                        Module      = "CRM",
                    };

                    // ok, so we can save this now
                    var defResult = api.Save(classDef);

                    if (!defResult.Success)
                    {
                        throw new ApplicationException("Unable to create class definition: " + defResult.FirstErrorMessage);
                    }

                    meta = api.DescribeObject(CustomActivityName).ResultValue;

                    if (meta == null)
                    {
                        throw new ApplicationException("Class definition not created.");
                    }
                }

                if (meta.Fields.All(f => f.Name != CategoryFieldName))
                {
                    var fieldDef = new MemberSuiteObject {
                        ClassType = msCustomField.CLASS_NAME
                    };
                    fieldDef.Fields[msCustomField.FIELDS.CustomObject]    = meta.CustomObjectID;
                    fieldDef.Fields[msCustomField.FIELDS.ApplicableType]  = CustomActivityName;
                    fieldDef.Fields[msCustomField.FIELDS.FieldDefinition] = new FieldMetadata
                    {
                        Name        = CategoryFieldName,
                        Label       = "Category",
                        DataType    = FieldDataType.Text,
                        DisplayType = FieldDisplayType.TextBox,
                    };

                    // ok, so we can save this now
                    var defResult = api.Save(fieldDef);

                    if (!defResult.Success)
                    {
                        throw new ApplicationException("Unable to create field definition: " + defResult.FirstErrorMessage);
                    }

                    meta = api.DescribeObject(CustomActivityName).ResultValue;

                    if (meta == null || meta.Fields.All(f => f.Name != CategoryFieldName))
                    {
                        throw new ApplicationException("Field definition not created.");
                    }
                }

                Console.WriteLine("Please enter a Custom Activity Name and press ENTER.");
                var activityName = Console.ReadLine();

                // Search for an activity by Name
                var nameSearch = new Search {
                    Type = CustomActivityName
                };
                nameSearch.AddCriteria(Expr.Equals("Name", activityName));
                var searchResult = api.GetObjectBySearch(nameSearch, null);
                if (!searchResult.Success)
                {
                    throw new ApplicationException("Unable to search: " + searchResult.FirstErrorMessage);
                }

                MemberSuiteObject mso;
                if (searchResult.ResultValue != null)
                {
                    mso = searchResult.ResultValue;
                    Console.WriteLine("Match found, let's update it. Cateogry currently: {0}",
                                      mso.SafeGetValue <string>(CategoryFieldName));
                }
                else
                {
                    Console.WriteLine("No match found, let's create it.");

                    mso = new MemberSuiteObject {
                        ClassType = CustomActivityName
                    };

                    // You can also generate an Object from the full Metadata:
                    ////mso = MemberSuiteObject.FromClassMetadata(meta);

                    mso.Fields["Name"] = activityName;
                }

                Console.WriteLine("Please enter a Category for this Activity and press ENTER.");
                mso.Fields[CategoryFieldName] = Console.ReadLine();

                // ok, so we can save this now
                var saveResult = api.Save(mso);

                if (!saveResult.Success)
                {
                    throw new ApplicationException("Unable to save: " + saveResult.FirstErrorMessage);
                }

                var savedObject = saveResult.ResultValue;

                Console.WriteLine("Successfully saved Custom Activity #{0} - {1}.",
                                  savedObject.SafeGetValue <string>("ID"),
                                  savedObject.SafeGetValue <string>("Name"));
            }
        }
    protected void unbindControls()
    {
        cfsRegistrationFields.Harvest();
        MemberSuiteObject mso = cfsRegistrationFields.MemberSuiteObject;

        if (targetOrder.LineItems == null)
        {
            targetOrder.LineItems = new List <msOrderLineItem>();
        }

        if (mso == null)
        {
            throw new ApplicationException("No MemberSuiteObject");
        }

        foreach (var li in targetOrder.LineItems)
        {
            if (li.OrderLineItemID == null)
            {
                continue;
            }

            // otherwise, copy all of the values
            li.Options = new List <NameValueStringPair>();
            var relevantFields = (from f in mso.Fields
                                  where f.Key != null && f.Key.StartsWith(Formats.GetSafeFieldName(li.OrderLineItemID))
                                  select f);
            foreach (var entry in relevantFields)
            {
                object value = null;

                if (entry.Value != null)
                {
                    if (entry.Value is List <string> )
                    {
                        var valueAsList = (List <string>)entry.Value;
                        value = string.Join("|", valueAsList);
                    }

                    if (entry.Key.EndsWith("_Contents"))
                    {
                        value = entry.Value;
                    }
                    else
                    {
                        if (value == null)
                        {
                            value = entry.Value.ToString();
                        }
                    }


                    var name = entry.Key.Split('|')[1];

                    // MS-4322 - need to account for demographics here
                    // MS-4970 - need to account for name on registration field (ie: guest registration)

                    // MSIV-400 - the logic was switched here, for some reason
                    //if (name.EndsWith("__q") || (name == MemberSuiteConstants.Events.NAME_ON_REGISTRATION_FIELD))
                    li[name] = value;
                    //else
                    // MSIV-794 - do both
                    li.Options.Add(new NameValueStringPair(name, value.ToString()));
                }
            }
        }
    }