Solved

Passing a List<System.Web.Security.MembershipUser> through a webservice reference C# 2.0 HELP!!!

Posted on 2010-09-23
4
1,414 Views
Last Modified: 2012-05-10
I have a business layer that provides the membershipprovider access to a webservice - When I try to pass a List<MembershipUser> through, only Comment Email, and two other properties show up on the client side in the generated proxy.  My question is, how can I ensure that all of the properties are included when the proxy is generated when adding a web reference ? Xml Include ?  Something Else ? It is 2.0, no WCF :{
0
Comment
Question by:gsdevEE
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
4 Comments
 
LVL 17

Expert Comment

by:Jesse Houwing
ID: 33752344
You cannot alter the behavior of the MembershipUser class, as i is part of the framework. If this is the way it serializes itself, then you're stuck with it.

By default only properties that have a propertygetter and  property setter are serialized by the XmlSerializer.  Many of the properties in MembershipUser are read only and are thus not serialized:

    public virtual string Comment { get; set; }
    public virtual DateTime CreationDate { get; }
    public virtual string Email { get; set; }
    public virtual bool IsApproved { get; set; }
    public virtual bool IsLockedOut { get; }
    public bool IsOnline { get; }
    public virtual DateTime LastActivityDate { get; set; }
    public virtual DateTime LastLockoutDate { get; }
    public virtual DateTime LastLoginDate { get; set; }
    public virtual DateTime LastPasswordChangedDate { get; }
    public virtual string PasswordQuestion { get; }
    public virtual string ProviderName { get; }
    public virtual object ProviderUserKey { get; }
    public virtual string UserName { get; }

To get around this you should write your own MembershipUser data transfer object and copy the data from your MembershipUser to that class before sending it over the wire. That way you are in complete control over which fields do and which don't get serialized.

At the receiving end you can then re-create the original MembershipUser using the

public MembershipUser(string providerName, string name, object providerUserKey, string email, string passwordQuestion, string comment, bool isApproved, bool isLockedOut, DateTime creationDate, DateTime lastLoginDate, DateTime lastActivityDate, DateTime lastPasswordChangedDate, DateTime lastLockoutDate);

constructor.
   
0
 

Author Comment

by:gsdevEE
ID: 33753263
And by doing so I will not create a duplicate of the MembershipUser ?  Isnt there a way I can serialize the User Collection like this ?  I just cannot get the next step in ensureing the webreference  XmlIncludeType(MembershipUser) to work in the generated WebReference, that is what I really am looking for heres my webmethod

[WebMethodAttribute()]
[XmlInclude(typeof(MembershipUser)]
GSMembershipUserCollection()
{

}


    public sealed class GSMembershipUserCollection : ICollection
    {
        public static List<System.Web.Security.MembershipUser> GetAllUsers(bool removeAdmin)
        {
            System.Web.Security.MembershipUserCollection collection = System.Web.Security.Membership.GetAllUsers();
            if (collection == null)
                return null;
            List<System.Web.Security.MembershipUser> list = new List<System.Web.Security.MembershipUser>();
            List<String> sorter = new List<string>();
            foreach (System.Web.Security.MembershipUser user in collection)
            {
                if (removeAdmin && user.UserName.ToLowerInvariant() == "administrator")
                { continue; }
                else
                {
                    sorter.Add(user.UserName);
                }

            }
            //Sort the list, and then add to the UserCollection via the sorted Names, as you cannot sort a MembershipUser object
            sorter.Sort();
            for (int i = 0; i < sorter.Count; i++)
            {
                list.Add(System.Web.Security.Membership.GetUser(sorter[i].ToString()));
            }
            return list;

        }

        public GSMembershipUserCollection()
        {
        }

        public void Add(System.Web.Security.MembershipUser user)
        {
            if (user == null)
                throw new ArgumentNullException("user");

            CheckNotReadOnly();
            store.Add(user.UserName, user);
        }

        public void Clear()
        {
            CheckNotReadOnly();
            store.Clear();
        }

        void ICollection.CopyTo(Array array, int index)
        {
            store.CopyTo(array, index);
        }

        public void CopyTo(System.Web.Security.MembershipUser[] array, int index)
        {
            store.CopyTo(array, index);
        }

        public IEnumerator GetEnumerator()
        {
            return ((IEnumerable)store).GetEnumerator();
        }

        public void Remove(string name)
        {
            CheckNotReadOnly();
            store.Remove(name);
        }

        public void SetReadOnly()
        {
            readOnly = true;
        }

        public int Count
        {
            get { return store.Count; }
        }

        public bool IsSynchronized
        {
            get { return false; }
        }

        public System.Web.Security.MembershipUser this[string name]
        {
            get { return (System.Web.Security.MembershipUser)store[name]; }
        }

        public object SyncRoot
        {
            get { return this; }
        }

        void CheckNotReadOnly()
        {
            if (readOnly)
                throw new NotSupportedException();
        }

        KeyedList store = new KeyedList();
        bool readOnly = false;
    }
0
 

Author Comment

by:gsdevEE
ID: 33753273
Oh, and keyed list is here
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.Specialized;
using System.Web.UI;
using System.Collections;

namespace GlobalSubmit.SecurityProvider.Utility
{
    internal class KeyedList : IOrderedDictionary, IStateManager
    {

        private Hashtable objectTable = new Hashtable();
        private ArrayList objectList = new ArrayList();

        public void Add(object key, object value)
        {
            objectTable.Add(key, value);
            objectList.Add(new DictionaryEntry(key, value));
        }

        public void Clear()
        {
            objectTable.Clear();
            objectList.Clear();
        }

        public bool Contains(object key)
        {
            return objectTable.Contains(key);
        }

        public void CopyTo(Array array, int idx)
        {
            objectTable.CopyTo(array, idx);
        }

        public void Insert(int idx, object key, object value)
        {
            if (idx > Count)
                throw new ArgumentOutOfRangeException("index");

            objectTable.Add(key, value);
            objectList.Insert(idx, new DictionaryEntry(key, value));
        }

        public void Remove(object key)
        {
            objectTable.Remove(key);
            int index = IndexOf(key);
            if (index >= 0)
                objectList.RemoveAt(index);
        }

        public void RemoveAt(int idx)
        {
            if (idx >= Count)
                throw new ArgumentOutOfRangeException("index");

            objectTable.Remove(((DictionaryEntry)objectList[idx]).Key);
            objectList.RemoveAt(idx);
        }

        IDictionaryEnumerator IDictionary.GetEnumerator()
        {
            return new KeyedListEnumerator(objectList);
        }

        IDictionaryEnumerator IOrderedDictionary.GetEnumerator()
        {
            return new KeyedListEnumerator(objectList);
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return new KeyedListEnumerator(objectList);
        }

        void IStateManager.LoadViewState(object state)
        {
            if (state != null)
            {
                object[] states = (object[])state;
                if (states[0] != null)
                {
                    objectList = (ArrayList)states[0];
                    for (int i = 0; i < objectList.Count; i++)
                    {
                        DictionaryEntry pair = (DictionaryEntry)objectList[i];
                        objectTable.Add(pair.Key, pair.Value);
                    }
                }
            }
        }

        object IStateManager.SaveViewState()
        {
            object[] ret = new object[] { objectList };
            if (ret[0] == null)
                return null;

            return ret;
        }

        void IStateManager.TrackViewState()
        {
            trackViewState = true;
        }

        public int Count
        {
            get { return objectList.Count; }
        }

        public bool IsFixedSize
        {
            get { return false; }
        }

        public bool IsReadOnly
        {
            get { return false; }
        }

        public bool IsSynchronized
        {
            get { return false; }
        }

        public object this[int idx]
        {
            get { return ((DictionaryEntry)objectList[idx]).Value; }
            set
            {
                if (idx < 0 || idx >= Count)
                    throw new ArgumentOutOfRangeException("index");

                object key = ((DictionaryEntry)objectList[idx]).Key;
                objectList[idx] = new DictionaryEntry(key, value);
                objectTable[key] = value;
            }
        }

        public object this[object key]
        {
            get { return objectTable[key]; }
            set
            {
                if (objectTable.Contains(key))
                {
                    objectTable[key] = value;
                    objectTable[IndexOf(key)] = new DictionaryEntry(key, value);
                    return;
                }
                Add(key, value);
            }
        }

        public ICollection Keys
        {
            get
            {
                ArrayList retList = new ArrayList();
                for (int i = 0; i < objectList.Count; i++)
                {
                    retList.Add(((DictionaryEntry)objectList[i]).Key);
                }
                return retList;
            }
        }

        public ICollection Values
        {
            get
            {
                ArrayList retList = new ArrayList();
                for (int i = 0; i < objectList.Count; i++)
                {
                    retList.Add(((DictionaryEntry)objectList[i]).Value);
                }
                return retList;
            }
        }

        public object SyncRoot
        {
            get { return this; }
        }

        private bool trackViewState;

        bool IStateManager.IsTrackingViewState
        {
            get { return trackViewState; }
        }

        private int IndexOf(object key)
        {
            for (int i = 0; i < objectList.Count; i++)
            {
                if (((DictionaryEntry)objectList[i]).Key.Equals(key))
                {
                    return i;
                }
            }
            return -1;
        }
    }
}

0
 
LVL 17

Accepted Solution

by:
Jesse Houwing earned 500 total points
ID: 33753768
You could implement your own MembershipUser implementation and inherit from this class, implement the needed IXmlSerializable interface and be done with it. But that would be more work and would require implementing your own MembershipProvider as well.

What you're doing here is using an existing class, MembershipUser, in a way that it wan't designed for. act as a data transfer object. You cannot force a class do be something it isn't just by looking angry at it ;).

Or you can let your GSMembershipUserCollection implement IXmlSerializable and let it handle the serialization and deserialization of MembershipUser. (which is more work if you ask me).

You might also want to check out WCF Authentication Services (part of the framework) which exposes the membership and role subsystems of ASP.NET over services:
http://msdn.microsoft.com/en-us/library/bb398990.aspx
0

Featured Post

Put Machine Learning to Work--Protect Your Clients

Machine learning means Smarter Cybersecurity™ Solutions.
As technology continues to advance, managing and analyzing massive data sets just can’t be accomplished by humans alone. It requires huge amounts of memory and storage, as well as high-speed processing of the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Problem Hi all,    While many today have fast Internet connection, there are many still who do not, or are connecting through devices with a slower connect, so light web pages and fast load times are still popular.    If your ASP.NET page …
New Relic recently released its Synthetics product that allows for the creation of performance monitors that periodically test a site's performance. If you wish to test an interactive workflow New Relic employs Selenium WebDriverJS to run those test…
The purpose of this video is to demonstrate how to set up the WordPress backend so that each page automatically generates a Mailchimp signup form in the sidebar. This will be demonstrated using a Windows 8 PC. Tools Used are Photoshop, Awesome…
Monitoring a network: why having a policy is the best policy? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the enormous benefits of having a policy-based approach when monitoring medium and large networks. Software utilized in this v…

734 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question