Solved

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

Posted on 2010-09-23
4
1,392 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
  • 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

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

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

The task of choosing a web design company to build a website for your business should never be taken in a light manner. Provided the fact that your website will act as a representative to your business and will be responsible for imposing an online …
This article aims to explain the working of CircularLogArchiver. This tool was designed to solve the buildup of log file in cases where systems do not support circular logging or where circular logging is not enabled
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…
Internet Business Fax to Email Made Easy - With  eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, f…

911 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

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now