Answered Social network API with WCF

  • Friday, May 04, 2012 5:44 PM
     
      Has Code

    I am developing a custom WCF service that uses a SharePoint 2010 social network API (Microsoft.Office.Server.UserProfiles and Microsoft.Office.Server.ActivityFeed) to get the UserProfileDetails and Newsfeed Activities for a specified user. 

    This service is running under the same application pool that is used by MySite host but hosted on different port, In IIS authentication section only windows authentication is enabled, I have enabled asp.net compatibility mode for this service in web.config using <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> and in service class by decorating is with [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]. This service uses basicHttpBinding with following details.

    <system.serviceModel>
            <bindings>
                <basicHttpBinding>
                    <binding name="BasicHttpEndpointBinding">
                        <security mode="TransportCredentialOnly">
                            <transport clientCredentialType="Windows" />
                        </security>
                    </binding>
                </basicHttpBinding>
            </bindings>
            <services>
                <service behaviorConfiguration="M.Enterprise.Core.Services.CommonBehavior"
                  name="M.Enterprise.Core.Services.Common">
                    <endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttpEndpointBinding" contract="M.Enterprise.Core.Interfaces.ICommon">
                        <identity>
                            <dns value="localhost" />
                        </identity>
                    </endpoint>
                </service>
                <service behaviorConfiguration="M.Enterprise.Core.Services.SocialBehavior"
                  name="M.Enterprise.Core.Services.Social">
                    <endpoint address="" binding="basicHttpBinding" bindingConfiguration="BasicHttpEndpointBinding" contract="M.Enterprise.Core.Interfaces.ISocial">
                        <identity>
                            <dns value="localhost" />
                        </identity>
                    </endpoint>
                </service>
            </services>
            <behaviors>
                <serviceBehaviors>
                    <behavior name="M.Enterprise.Core.Services.CommonBehavior">
                        <serviceMetadata httpGetEnabled="true" />
                        <serviceDebug includeExceptionDetailInFaults="true" />
                    </behavior>
                    <behavior name="M.Enterprise.Core.Services.SocialBehavior">
                        <serviceMetadata httpGetEnabled="true" />
                        <serviceDebug includeExceptionDetailInFaults="true" />
                    </behavior>
                </serviceBehaviors>
            </behaviors>
            <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
        </system.serviceModel>

    With the above configuration I am getting "cannot complete this action" error when trying to create a "UserProfileManager" instance with following code, If I wrap the below code with "RunWithElevatedPrivileges" then it does work but it always returns the activities of the Application Pool user but not the one I mention in the "accountName" parameter. Surprisingly same code works well with ASMX service but not with WCF service.

    public ActivityFeedsCollection GetActivitiesForMe(string accountName)
    	{
    		ActivityFeedsCollection activityFeedsCollection = new ActivityFeedsCollection();
    		HttpContext httpContextBackup = HttpContext.Current;
    
    		try
    		{
    			//Empty the HttpContext - Hack
    			HttpContext.Current = null;
    
    			using (SPSite site = new SPSite(MySiteURL))
    			{
    				SPServiceContext context = SPServiceContext.GetContext(site);
    				UserProfileManager profileManager = new UserProfileManager(context);
    				UserProfile profile = profileManager.GetUserProfile(accountName);
    
    				ActivityManager activityManager = new ActivityManager(profile, context);
    				ActivityEventsCollection activityEventsForMeCollection = activityManager.GetActivitiesForMe();
    				ActivityTypesCollection activityTypeCollection = activityManager.ActivityTypes;
    
    				activityFeedsCollection = BindActivityFeed(activityEventsForMeCollection, activityTypeCollection);
    			}
    		}
    		catch (Exception ex)
    		{
    			ExceptionHelper.HandleException(activityFeedsCollection, ex);
    		}
    		finally
    		{
    			HttpContext.Current = httpContextBackup;
    		}
    
    		return activityFeedsCollection;
    	}

    Can someone please help me to get this working, Am I missing anything in WCF configuration.

    Thanks in advance
    Ajay Sawant


    • Edited by Ajay.Sawant Friday, May 04, 2012 5:45 PM
    •  

All Replies

  • Monday, May 07, 2012 11:06 AM
     
     

    Ajay,

    It's probably totally unrelated, but since you have no replies I thought I'd trow this out. I ran into an odd issue in Silverlight and documanted the fix here: http://www.ableblue.com/blog/archive/2011/03/18/silverlight-and-sharepoint-user-profile-service-guids/

    Maybe it will get you pushed in the right direction.

    Matthew


    Matthew McDermott, MVP SharePoint

  • Wednesday, May 09, 2012 12:52 PM
     
     

    Hi Matthew,

    Thanks for your help, my issue is not similar to this one.. I somehow think that it's related to the impersonation because I was able to get the same code working with ASMX but not with WCF

    Can someone please help me with this issue?

    Thanks in advance
    Ajay Sawant

    
  • Wednesday, May 16, 2012 2:33 PM
     
     Answered

    Hi All,

    I was able to resolve this issue and surprisingly it turns out to be an issue with WCF configuration and not with "Social network API" or anything related to SharePoint object model, it was the configuration issue with my main WCF Service and client application calling this service.

    First my custom WCF service which uses the SharePoint object model should have identity impersonation enabled into the web.config file, next the client which is calling this service should have the following line before calling the web method so it could pass a valid identity to the service for impersonation.

    svcClient.ClientCredentials.Windows.ClientCredential = new NetworkCredential("userToImpersonate", "secretPassword", "ADDomain");
    svcClient.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;

    You could find more details about this issue in WCF forum at the link below.

    http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/b30a7b89-bfdd-470d-899f-10ddd9e4ac24/#c3df1c1b-5343-44e2-a560-d1672ad88e84

    Hope this would help someone...

    Thanks
    Ajay Sawant


    • Marked As Answer by Ajay.Sawant Wednesday, May 16, 2012 2:33 PM
    •