Solved

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

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

PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

Question has a verified solution.

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

Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
Calculating holidays and working days is a function that is often needed yet it is not one found within the Framework. This article presents one approach to building a working-day calculator for use in .NET.
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…
Michael from AdRem Software outlines event notifications and Automatic Corrective Actions in network monitoring. Automatic Corrective Actions are scripts, which can automatically run upon discovery of a certain undesirable condition in your network.…

630 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