Skullcrusher's Blog

Andy Bonner's Blog at vbCity

vbCity Blogs moved to:
http://cs.vbcity.com/blogs
  Home :: Syndication  :: Login

Congratulations! You've managed to stumble across the mad rantings of Andy Bonner aka Skullcrusher

Here you'll find all sorts of hopefully useful info on MOSS (Microsoft Office SharePoint Server) and things .NET related. You might even find other useful gems if I get around to it.


You can contact me on the address below, but I won't guarantee a response 8-}

OctNovember 2009Dec
SMTWTFS
25262728293031
1234567
891011121314
15161718192021
22232425262728
293012345

Articles

Archives

Topics

Image Galleries

MOSS/SharePoint Links

I had the need the other day for a way of displaying a list of site users on an InfoPath form that the user can select from and came across this article on Jan Tielens' blog which I thought would do the trick. Unfortunately it was for SharePoint 2003 rather than 2007 so I had to play around a bit to get it working, & came up with 2 methods of accompishing it which I wanted to share with you.

Create a New Visual Studio .Net project based on the InfoPath Form Template and call it ExampleGetSiteUsers.

The first thing you'll need to do is go into Tools -> Form Options and set the forms security level to Full Trust

Then create your main data source like so

We'll need to create a DataConnection to the GetUserCollectionFromSite Method of the UserGroup SharePoint webservice.

From the Visual Studio menu select Data -> Data Connections

 

Click Add

Select Create a new connection to Receive data then click Next

Select Web service then click Next

Enter http://YourServerName/_vti_bin/UserGroup.asmx for the webservice location making sure you put in your moss servers name then click next

Select the GetUserCollectionFromSite method then click Next

Click Next

 

Enter a meaningful name for the data connection & ensure "Automatically retrieve data when the form is opened" is ticked. Then click Finish & close the data connections window. We now need to add a second data connection that will use the following XML file as it's source. Copy the code below to a new file & name it SiteUsersAndGroups.xml save it to a location on your machine that you'll remember.

Code Copy HideScrollFull
<?xml version="1.0" encoding="utf-8" ?>
<SiteUsersAndGroups>
    <Users xmlns="http://schemas.microsoft.com/sharepoint/soap/directory/">
        <User ID="" Sid="" Name="" LoginName="" Email="" Notes="" IsSiteAdmin="" IsDomainGroup=""/>
        <User ID="" Sid="" Name="" LoginName="" Email="" Notes="" IsSiteAdmin="" IsDomainGroup=""/>
    </Users>
</SiteUsersAndGroups>
. . .

 

From the Visual Studio menu select Data -> Data Connections Add a new connection to Receive data

This time select XML Document as the source then click Next

Enter the location of the XML document we just created then click Next

Click Next

Click Finish & close the Data Connections window

Create a couple of DropDown Lists on your Form for the 2 fields in the main data source

 

Go into the properties of the first Drop Down that is bound to our method1 field

 

Select "Look up values from an external data source" & set the Data source to the connection we just created Click on the Select XPath for the entries

Select the User repeating group & click OK

Set the value to the ID and the Display name to the Name We now need to create yet another Data connection that we can use as the source for our second Drop Down. Normally you wouldn't need to do this as you could use the same source for both, but because I'm showing 2 methods which will be slightly different in the content they show we'll need a second connection. Follow exactly the same steps as we used to create the first data connection to an xml file, but name the connection SiteUsers as in the second method we'll be stripping out groups.

Now we'll go into the properties of the second Drop Down & bind it to this new connection like so

You'll now need to create a new class within your project called Users.cs which contains the following code

Code Copy HideScrollFull
//------------------------------------------------------------------------------
//
//     This code was generated by a tool.
//     Runtime Version:2.0.50727.42
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
//

//------------------------------------------------------------------------------

using
System.Xml.Serialization;

//
// This source code was auto-generated by xsd, Version=2.0.50727.42.
//


///

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://schemas.microsoft.com/sharepoint/soap/directory/", IsNullable = false)]
public
partial class Users
{

    private User[] itemsField;

    ///
    [System.Xml.Serialization.XmlElementAttribute("User")]
    public User[] Items
    {
        get
        {
            return this.itemsField;
        }
        set
        {
            this.itemsField = value;
        }
    }
}

///

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.42")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public
partial class User
{

    private string idField;

    private string sidField;

    private string nameField;

    private string loginNameField;

    private string emailField;

    private string notesField;

    private string isSiteAdminField;

    private string isDomainGroupField;

    ///
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string ID
    {
        get
        {
            return this.idField;
        }
        set
        {
            this.idField = value;
        }
    }

    ///
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string Sid
    {
        get
        {
            return this.sidField;
        }
        set
        {
            this.sidField = value;
        }
    }

    ///
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string Name
    {
        get
        {
            return this.nameField;
        }
        set
        {
            this.nameField = value;
        }
    }

    ///
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string LoginName
    {
        get
        {
            return this.loginNameField;
        }
        set
        {
            this.loginNameField = value;
        }
    }

    ///
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string Email
    {
        get
        {
            return this.emailField;
        }
        set
        {
            this.emailField = value;
        }
    }

    ///
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string Notes
    {
        get
        {
            return this.notesField;
        }
        set
        {
            this.notesField = value;
        }
    }

    ///
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string IsSiteAdmin
    {
        get
        {
            return this.isSiteAdminField;
        }
        set
        {
            this.isSiteAdminField = value;
        }
    }

    ///
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string IsDomainGroup
    {
        get
        {
            return this.isDomainGroupField;
        }
        set
        {
            this.isDomainGroupField = value;
        }
    }
}
. . .

 

Finally we're ready to write some code in the FormCode file Here's some I cooked up earlier which I've heavily commented so you can see what I'm doing.

Code Copy HideScrollFull
using Microsoft.Office.InfoPath;
using
System;
using
System.Xml;
using
System.Xml.XPath;
using
System.Xml.Serialization;

namespace
ExampleGetSiteUsers
{
    public partial class FormCode
    {
        // NOTE: The following procedure is required by Microsoft Office InfoPath.
        // It can be modified using Microsoft Office InfoPath.
        public void InternalStartup()
        {
            this.EventManager.FormEvents.Loading += new LoadingEventHandler(FormEvents_Loading);
        }

        void FormEvents_Loading(object sender, LoadingEventArgs e)
        {
            //get an XPathNavigator to our webservice method
            XPathNavigator siteUsers = this.DataSources["GetUserCollectionFromSite"].CreateNavigator();

            //create the XmlNamespaceManager that will allow us to navigate the xml
            XmlNamespaceManager umanager = new XmlNamespaceManager(siteUsers.NameTable);
            umanager.AddNamespace("dfs", "http://schemas.microsoft.com/office/infopath/2003/dataFormSolution");
            umanager.AddNamespace("tns", "http://schemas.microsoft.com/sharepoint/soap/directory/");
            //get the node that contains all the users from the call to the web service
            XPathNavigator allusers = siteUsers.SelectSingleNode("/dfs:myFields/dfs:dataFields/tns:GetUserCollectionFromSiteResponse/tns:GetUserCollectionFromSiteResult/tns:GetUserCollectionFromSite/tns:Users", umanager);

            //method 1
            //get an XPathNavigator to our data source used by the first Drop Down
            XPathNavigator siteUsersAndGroups = this.DataSources["SiteUsersAndGroups"].CreateNavigator();

            //create the XmlNamespaceManager that will allow us to navigate the xml
            //we can reuse this for our second data source in method 2 as the xml schema is identical
            XmlNamespaceManager dmanager = new XmlNamespaceManager(siteUsersAndGroups.NameTable);
            dmanager.AddNamespace("tns", "http://schemas.microsoft.com/sharepoint/soap/directory/");
            //get the node within this data source that represents users
            XPathNavigator dusers = siteUsersAndGroups.SelectSingleNode("/SiteUsersAndGroups/tns:Users", dmanager);

            //fill this data source with the users returned by the web service call
            dusers.ReplaceSelf(allusers);


            //method 2
            //We'll start off by deserializing the xml node of users we got from the web service call
            //into our users class to make workingwith the data easier.
            Users su;
            XmlSerializer serializer = new XmlSerializer(typeof(Users));
            su = (Users)serializer.Deserialize(allusers.ReadSubtree());

            //create an XPathNavigator to the second data source we created from the xml document
            //i.e. the data source we're using for the second Drop Down
            //specifically the first User node
            XPathNavigator siteUser = this.DataSources["SiteUsers"].CreateNavigator().SelectSingleNode("/SiteUsersAndGroups/tns:Users/tns:User", dmanager);
            //create a clone of the this node so we can change the values
            XPathNavigator currentNode = siteUser.Clone();

            //We'll need to iterate through the users in our User class in
            //reverse order otherwise they'll appear in our drop down in decending order
            for (int i = su.Items.Length - 1; i >= 0; i--)
            {
                User user = su.Items[i];
                //Check each user to see if it's actually a group as we don't want those
                if (user.IsDomainGroup == "False")
                {
                    XPathNavigator newNode = currentNode;
                    //change some of the value on the clone, I'm only changing the 2 we need for this example
                    //but you could change them all
                    newNode.SelectSingleNode("/SiteUsersAndGroups/tns:Users/tns:User/@ID", dmanager).SetValue(user.ID);
                    newNode.SelectSingleNode("/SiteUsersAndGroups/tns:Users/tns:User/@Name", dmanager).SetValue(user.Name);

                    try
                    {
                        //insert the new node after the current one
                        currentNode.InsertAfter(newNode);
                    }
                    catch (Exception)
                    {
                    }
                    currentNode = newNode.Clone();
                }
            }
            //this is the first blank node from our sample xml file so we need to get rid of it
            siteUser.DeleteSelf();
        }
    }
}
. . .

 

Go ahead & run the project. The first drop down will show all users & groups for your site, whilst the second will only show the users. You'll notice that the second Drop Down will be at a blank record at the end of the list of users & may be wondering why. The reason is that in our xml file that we used for the data connection there were 2 blank user nodes, which we need to have originally to tell InfoPath that User is a repeating group. Now that the connection is created we can edit the file that is stored within our project to get rid of the second blank record which will fix this up. To be able to edit the file you'll need to make sure that you haven't got manifest.xsf open otherwise you wont be able to open the file. From the solution window open SiteUsers & delete the second User node, save the file & rerun the project & voila...

posted on Wednesday, December 20, 2006 12:05 PM

Feedback

# re: Get List of Site Users in InfoPath Form 1/29/2007 7:56 PM Radhi
It is works well... did a great job.
I have a question....
How to get only the logged in user of the sharepoint site in the Infopath form?

Thanks in advance....

# re: Get List of Site Users in InfoPath Form 1/31/2007 11:58 AM Andy Bonner (Skullcrusher)
Hi Radhi

If you take a look at my first article it shows you exactly how to do that.

http://blogs.vbcity.com/skullcrusher/articles/7734.aspx

# re: Get List of Site Users in InfoPath Form 4/26/2007 10:53 PM Malzenstwa
Very good start at a blog. I think it be a great site in the future.

# re: Get List of Site Users in InfoPath Form 7/24/2007 4:06 AM Dotnetdev
Hi,

I tried ur code(method1). I have the same scenario. But i'm getting null reference error. Please help me. Thanks in advance.

Here is my code

//Create XPathNavigator fro web services

XPathNavigator siteUsers = this.DataSources["Users"].CreateNavigator();

//create XmlNamespaceManager that will alow u to navigate the xml

XmlNamespaceManager u_manager = new XmlNamespaceManager(siteUsers.NameTable);

u_manager.AddNamespace("dfs", "http://schemas.microsoft.com/office/infopath/2003/dataFormSolution"">http://schemas.microsoft.com/office/infopath/2003/dataFormSolution");
u_manager.AddNamespace("s0", "http://schemas.microsoft.com/sharepoint/soap/directory/"">http://schemas.microsoft.com/sharepoint/soap/directory/");

//Get the node that contains all the users from the call to the web service

XPathNavigator allusers = siteUsers.SelectSingleNode("/dfs:myFields/dfs:dataFields/s0:GetUserCollectionFromSiteResponse/s0:GetUserCollectionFromSiteResult/s0:GetUserCollectionFromSite/s0:Users/s0:User", u_manager);

//Get an XPathNavigator to our data source used by the dropdown

XPathNavigator siteUsersandGroups = this.DataSources["TempUser"].CreateNavigator();
XmlNamespaceManager d_manager = new XmlNamespaceManager(siteUsersandGroups.NameTable);
d_manager.AddNamespace("dfs", "http://schemas.microsoft.com/office/infopath/2003/dataFormSolution"">http://schemas.microsoft.com/office/infopath/2003/dataFormSolution");

d_manager.AddNamespace("s0", "http://schemas.microsoft.com/sharepoint/soap/directory/"">http://schemas.microsoft.com/sharepoint/soap/directory/");

//Get the node within this datasource that represent users

XPathNavigator dusers = siteUsersandGroups.SelectSingleNode("/SiteUsersAndGroups/s0:Users", d_manager);
//fill this datasource with the users returned by the web service call

dusers.ReplaceSelf(allusers);


}

# re: Get List of Site Users in InfoPath Form 7/24/2007 11:54 PM Paul
Looking at method 2. I am trying to crteate a class file based on the GetUserCollectionFromGroup web service. Can you please let me know how you got the class for the other service.

Thanks

Paul

# re: Get List of Site Users in InfoPath Form 7/27/2007 7:58 AM Andy Bonner (Skullcrusher)
Hi DotNetDev

It's going to be a bit hard to diagnose the problem without knowing where in the code it's returning the error. Have you tried debugging it? If you flick me your emial address to my devcity address I can forward you a copy of my example project to play with.

Andy

# re: Get List of Site Users in InfoPath Form 7/27/2007 8:01 AM Andy Bonner (Skullcrusher)
Hi Paul

What I did to get that class was to save the xml returned by the web service call into a file that I could then use the XSD.exe command line tool that comes with VS to create a class.

Andy

# re: Get List of Site Users in InfoPath Form 8/10/2007 2:53 AM Matthieu
Hi,

I was looking for that trick and got so glad when I found your article that I did not realize it wasn't working when the InfoPath form is activated for navigators.

I keep on getting that "compatibility error" a compatibility error saying that "an expression is not supported". This is the unsupported expression :
xdXDocument:GetDOM("SiteUsers")/SiteUsersAndGroups/ns1:Users/ns1:User

Anyway, thanks for your work.
Matthieu.

# re: Get List of Site Users in InfoPath Form 8/15/2007 5:42 AM Gyan
I'm completely confused...

I designed a form in infopath 2007 in which I have a drop-down that I need to populate with all MOSS 2007 users.

How do I get the form into VS2005 Pro?

I don't have a manifest.xsd in my solution, how do I get that?

The screen shots you give look like they're from Infopath rather than VS, but you talk about doing the activities from VS.

Any chance you could give all the steps for those of us who are fumbling through all this?

# re: Get List of Site Users in InfoPath Form 8/20/2007 8:16 AM Andy Bonner (Skullcrusher)
Hi Gyan

Have you installed Visual Studio 2005 Tool for Office Second Edition?

http://www.microsoft.com/downloads/details.aspx?familyid=5E86CAB3-6FD6-4955-B979-E1676DB6B3CB&displaylang=en

Although I don't think that'll do you much good if your using VS2005 Pro as it'll only give you Application Level features (this is mentioned in the OverView in the link above).

The screenshots are from the InfoPath designer hosted within VS2005

If you take a look at my article, the only reason you need to use any code is to get rid of groups from the web service results, otherwise you can just bind a drop down list to the secondary datasource that's calling the GetUserCollectionFromSite method.


# re: Get List of Site Users in InfoPath Form 3/27/2008 7:18 PM Vuthy
Hi All,

I'd like to get a list of users based on a selected value of profile properties.

Could anyone have idea on how to go through?

Thanks

# re: Get List of Site Users in InfoPath Form 9/12/2008 2:04 AM Or Cingilli
I used the first method to access the web service. However, when the form loads the drop down box returns no results. There are no errors, but nothing appears in the drop down. Suggestions?

# re: Get List of Site Users in InfoPath Form 9/12/2008 7:52 AM Andy Bonner (Skullcrusher)
Have you tried connecting to the web service from a test .Net app and made sure it's returning data?

# re: Get List of Site Users in InfoPath Form 1/9/2009 2:09 AM Naida
hi , how to get the user list of the site in the infopath form, and i dont want to show the users list in the dorp down combo box., i want the control which default association form of approval workflow have to select the approver(user of site) from the list.guide me

thanx in advance


# InfoPath and Active Directory | keyongtech 1/21/2009 7:14 PM Pingback/TrackBack
InfoPath and Active Directory | keyongtech

# re: Get List of Site Users in InfoPath Form 6/20/2009 6:52 PM Dipti Chhatrapati
Hello ,

i tried above steps to get site users in IP form !!

but i m not able to populates users in dropdown !!

wht could be the mistakes from my side !! please help me as soon as possible.

thanks & regards ,
Dipti Chhatrapati

# re: Get List of Site Users in InfoPath Form 7/17/2009 5:21 AM George Gergues
My 2 Cents
This is a great long term fix for the problem
BUT
There is a faster approach to this , ( also a way to use InfoPath Web Forms)
You can create a custom list (Of users and Titles) in the site where you are planning to use this form, and add them as List items.
The list on the site will populate dynamically. ( you can connect to the list with a List connection from the data connections inside InfoPath) .
The main problem is that you have to maintain a list of users (business-wise makes sense ) to serve the form rendered.
I have noticed working with large organizations that most of those InfoPath applications are departmental and they can be managed by the department than a whole windows AD group and SharePoint Security Group.

If you want to email me, find me.
-George Gergues


Post Feedback

Title:
Name:
Url:
Comments: 
Protected by Clearscreen.SharpHIPEnter the code you see: