Solved

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

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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

ASP.Net to Oracle Connectivity Recently I had to develop an ASP.NET application connecting to an Oracle database.As I am doing it first time ,I had to solve several problems. This article will help to such developers  to develop an ASP.NET client…
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!
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…
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…

707 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

13 Experts available now in Live!

Get 1:1 Help Now