TermSet Creation gives error in SharePoint 2013 using custom webservice - web-services

I am trying to create a new term set in SharePoint 2013 using a custom WCF web service deployed within SharePoint 2013 server. I have written below code to create the term set.
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (Impersonator imp = new Impersonator("Username", "Domain", "Password"))
{
using (SPSite site = new SPSite("http://server:8002/sites/site/"))
{
site.AllowUnsafeUpdates = true;
TaxonomySession session = new TaxonomySession(site);
TermStore termStore = session.TermStores["Managed Metadata Service"];
var termStoreAdmin = termStore.TermStoreAdministrators.Where(obj => obj.PrincipalName.Contains("domain\\username")).FirstOrDefault();
if (termStoreAdmin == null)
termStore.AddTermStoreAdministrator("domain\\username");
Group group = termStore.GetGroup(new Guid(groupGuid));
if (group != null && !string.IsNullOrEmpty(termSetName))
{
TermSet termset = group.TermSets.FirstOrDefault(obj => obj.Name.Equals(termSetName));
if (termset == null)
{
termset = group.CreateTermSet(termSetName);
termSetGuid = termset.Id.ToString();
}
SetupNavTermSet(termset, session, site.OpenWeb());
}
termStore.CommitAll();
}
}
});
I am calling this method from silverlight code using soap message. While calling this code I am getting exception while executing group.CreateTermSet(termSetName); line.
The error is:
Error Message : Value cannot be null.
Source : Microsoft.SharePoint
Error Details : at Microsoft.SharePoint.Administration.Claims.SPClaimProviderManager.GetUserIdentifierEncodedClaim(IIdentity identity)
at Microsoft.SharePoint.Taxonomy.Internal.CommonUtilities.GetCurrentUserName()
at Microsoft.SharePoint.Taxonomy.TaxonomySession.get_CurrentUserName()
at Microsoft.SharePoint.Taxonomy.Group.CreateTermSet(String name, Guid newTermSetId, Int32 lcid)
at Microsoft.SharePoint.Taxonomy.Group.CreateTermSet(String name)
at SplitVisionMetadataManagement.CustomManageMetaDataWCFService.<>c__DisplayClassc.<CreateTaxonomyTermSet>b__8()
Has anybody got this issue and a solution?

I also encountered the same issue and figured out that the Microsoft.SharePoint.Taxonomy.Internal.CommonUtilities.GetCurrentUserName() method uses the HttpContext.Current.User security principal for arriving at the user name.
I am using similar code in a windows form application and hence the HttpContext was empty. I made a workaround by setting the context and user manually as below.
if (HttpContext.Current == null)
{
HttpRequest request = new HttpRequest("", SiteURL, "");
HttpContext.Current = new HttpContext(request, new HttpResponse(TextWriter.Null));
HttpContext.Current.User = System.Threading.Thread.CurrentPrincipal;
}
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(SiteURL))
{
using (SPWeb web = site.OpenWeb())
{
if (HttpContext.Current.Items["HttpHandlerSPWeb"] == null)
HttpContext.Current.Items["HttpHandlerSPWeb"] = web;
// Your SharePoint Term Creation code
}
}
});
In your case it seems like you are using claims based authentication and hence some issue with the claims provider in returning the name. You HTTP context would be the context under which the WCF is running. You may need to investigate further in those angle.
The above knowledge should help you to understand it further.

Related

How to manually set finbuckle current tenant for integration testing

I am trying to "integration test" a multi-tenant dotnet core application, since repositories and DbContexts requires the current tenant information which is normally set using the Mediator during requests.
In integration test I need to set the tenant manually,
I have tried to create httpcontext object and use the TrySetTenantInfo function but it gives error
Value cannot be null. (Parameter 'provider')
here is the code I tried for httpcontext setting
_httpContextAccessor =_servicesProvider.GetRequiredService<IHttpContextAccessor>();
_httpContextAccessor.HttpContext = new DefaultHttpContext();
TenantInfo ti = new TenantInfo
{
Id = "**",
Identifier = "**",
ConnectionString = "**",
Name = "***"
};
//here is the error thrown
if (_httpContextAccessor.HttpContext.TrySetTenantInfo(ti, true))
{
}
Thanks

Is Xamarin Master-Detail Template Broken When used with Azure Backing?

The Master-Detail template in Xamarin has typically been a great starting point for many of my apps that work with .Net Core Backing Service. For review it has a Dependency service in the Client that allows Mocking of the Azure Backing Service or connection to a real or local service while in development.
The control variable generated by the template is public static bool UseMockDataStore = true;
All Code discussed is completely found here: https://github.com/BicycleMark/SignalRGB
I created a Xamarin Master-Detail project naming it SignalRGB and did the following:
The solution project structure looks like:
I start Instance one Visual Studio 2019 And Run SignalRGB.Web
3) Made Note of url: [https://localhost:44300]
4) Opened another Instance of Visual Studio (2) to run client with UseMockDataSource=false / The default it displayed results in Client using MockDataSource
5)went to these lines and updated Client for talking to my local server waiting for an http request :
public static string AzureBackendUrl =
//DeviceInfo.Platform == DevicePlatform.Android ? "http://10.0.2.2:5000" : "http://localhost:44300";
DeviceInfo.Platform == DevicePlatform.Android ? "http://localhost:44300" : "http://localhost:44300";
public static bool UseMockDataStore = false;
public App()
{
InitializeComponent();
if (UseMockDataStore)
{
DependencyService.Register<MockDataStore>();
}
else
{
DependencyService.Register<AzureDataStore>();
}
MainPage = new MainPage();
}
Went and ran SignalRGB.UWP from VS Instance(2) and client application hung on the line GetStringAsync():
bool IsConnected => Connectivity.NetworkAccess == NetworkAccess.Internet;
public async Task<IEnumerable<Item>> GetItemsAsync(bool forceRefresh = false)
{
if (forceRefresh && IsConnected)
{
var json = await client.GetStringAsync ($"api/item");
items = await Task.Run(() => JsonConvert.DeserializeObject<IEnumerable<Item>>(json));
}
return items;
}
I have tried other platforms iOS and get same result:
What Am I doing wrong here?
Oversight? in the templated code perhaps. 44300 is the port but notice the protocol.
DeviceInfo.Platform == DevicePlatform.Android ? "https://localhost:44300" :

Getting .NET Core, WS Federation, Identity Core Issue with TicketDataFormat

I have two applications that are using WS Federation and I am working to migrate one of these applications over to .NET Core. These two applications need to be able to share cookies and this is where I am running into an issue on the .NET Core side.
This is a portion of my Startup.cs
services.AddIdentity<ApplicationUser, ApplicationRole>()
.AddEntityFrameworkStores<Context>()
.AddDefaultTokenProviders();
services.ConfigureApplicationCookie(options =>
{
options.LoginPath = new PathString("/Account/Login");
//LOGIN WORKS CORRECTLY WITH THE BELOW LINE COMMENTED
options.TicketDataFormat = new AuthTicketDataFormat();
options.Cookie.Name = "cookiename";
options.Cookie.Path = "/";
options.Cookie.Domain = "";
});
services.ConfigureExternalCookie(options => {
options.LoginPath = new PathString("/Account/Login");
//LOGIN WORKS CORRECTLY WITH THE BELOW LINE COMMENTED
options.TicketDataFormat = new AuthTicketDataFormat();
options.Cookie.Name = "cookiename";
options.Cookie.Path = "/";
options.Cookie.Domain = "";
});
services.AddAuthentication()
.AddWsFederation(options => {
// MetadataAddress represents the Active Directory instance used to authenticate users.
options.MetadataAddress = authentication.GetValue<string>("AdfsWsFedMetadataUri");
// Wtrealm is the app's identifier in the Active Directory instance.
// For ADFS, use the relying party's identifier, its WS-Federation Passive protocol URL:
options.Wtrealm = authentication.GetValue<string>("AdfsRelyingPartyIdentifier");
});
I am able to see that I do receive a cookie in the Network tab, but the issue I am having is that I am being put into an infinite loop because on my anonymous Callback endpoint I have the following:
var loginInfo = await this._signInManager.GetExternalLoginInfoAsync();
//loginInfo is always coming back as null
if (loginInfo == null) {
return RedirectToAction("Login");
}
It seems the issue is being caused by options.TicketDataFormat and creating a custom format for the cookie. The cookie seems to be created correctly with the ticketDataFormat, but getExternalLoginInfoAsync on signInManager is always returning null.
Any help or direction is greatly appreciated as I've been banging my head against the wall for a day trying to figure this out.

Unable to authenticate in accessing Dynamic CRM Online Web Service

I need to utilize Dynamic CRM Data Service Endpoint exposed to get data from one of the methods.
Service(microsoft) account has access to this service.
I've tried authenticating to Discovery Service and Organization Service using sample code provided here [https://msdn.microsoft.com/en-us/library/hh675404.aspx] and succeed. However am not able to use same authentication to access data Service as I could find anyway to relate Data Service with the other two. Doing basic authentication using Network Credentials does not work.
I have downloaded the CSDL exposed and added that as service reference to my project, which created an class of web service which extends from DataServiceContext. Am trying to retrieve data of one of the methods using LinQ queries. It returs following error:
"The response payload is a not a valid response payload. Please make sure that the top level element is a valid Atom or JSON element or belongs to 'http://schemas.microsoft.com/ado/2007/08/dataservices' namespace." On capturing using fiddle I realized that on hitting data service URL it is redirected to sign in page 'login.microsoftonline.com/'
Can anybody suggest a way to authenticate the user to access Data Serivce?
Adding code:
//<snippetAuthenticateWithNoHelp1>
IServiceManagement<IDiscoveryService> serviceManagement =
ServiceConfigurationFactory.CreateManagement<IDiscoveryService>(
new Uri(_discoveryServiceAddress));
AuthenticationProviderType endpointType = serviceManagement.AuthenticationType;
// Set the credentials.
AuthenticationCredentials authCredentials = GetCredentials(serviceManagement, endpointType);
String organizationUri = String.Empty;
// Get the discovery service proxy.
using (DiscoveryServiceProxy discoveryProxy =
GetProxy<IDiscoveryService, DiscoveryServiceProxy>(serviceManagement, authCredentials))
{
// Obtain organization information from the Discovery service.
if (discoveryProxy != null)
{
// Obtain information about the organizations that the system user belongs to.
OrganizationDetailCollection orgs = DiscoverOrganizations(discoveryProxy);
// Obtains the Web address (Uri) of the target organization.
organizationUri = FindOrganization(_organizationUniqueName,
orgs.ToArray()).Endpoints[EndpointType.OrganizationService];
}
}
//</snippetAuthenticateWithNoHelp1>
if (!String.IsNullOrWhiteSpace(organizationUri))
{
//<snippetAuthenticateWithNoHelp3>
IServiceManagement<IOrganizationService> orgServiceManagement =
ServiceConfigurationFactory.CreateManagement<IOrganizationService>(
new Uri(organizationUri));
// Set the credentials.
AuthenticationCredentials credentials = GetCredentials(orgServiceManagement, endpointType);
// Get the organization service proxy.
using (OrganizationServiceProxy organizationProxy =
GetProxy<IOrganizationService, OrganizationServiceProxy>(orgServiceManagement, credentials))
{
// This statement is required to enable early-bound type support.
organizationProxy.EnableProxyTypes();
// Now make an SDK call with the organization service proxy.
// Display information about the logged on user.
Guid userid = ((WhoAmIResponse)organizationProxy.Execute(
new WhoAmIRequest())).UserId;
SystemUser systemUser = organizationProxy.Retrieve("systemuser", userid,
new ColumnSet(new string[] { "firstname", "lastname" })).ToEntity<SystemUser>();
Console.WriteLine("Logged on user is {0} {1}.",
systemUser.FirstName, systemUser.LastName);
Uri x = new Uri("https://<MyOrgainzationName>.crm.dynamics.com/XRMServices/2011/OrganizationData.svc/");
MyOrgainzationContext saContext = new MyOrgainzationContext(x);
NetworkCredential nc = new NetworkCredential();
nc.UserName = "*****#microsoft.com";
nc.Password = "********";
saContext.Credentials = nc;
var query_where3 = from c in saContext.new_productSet
select new
{
ProductStatus = c.new_ProductStatus,
LineofBusiness = c.new_LineofBusiness
};
var temp = saContext.Entities;
foreach (var c in query_where3)
{
System.Console.WriteLine("ProductStatus: " +
c.ProductStatus +
"\t\t\t" +
"LineofBusiness: " +
c.LineofBusiness);
}
}
//</snippetAuthenticateWithNoHelp3>
}
MyOrganizationContext is the context class created on adding CSDL file exposed at service endpoints
Have a look at the CRM Web Api Preview: https://msdn.microsoft.com/en-us/dynamics/crm/webapipreview.aspx. You can call this endpoint from outside xRM and you can authenticate with OAuth 2.0.

How to call processing page via web service

I have a processing page and I want to run function process all via web service (add web reference into my C# window form app). My code below:
var context = new ModuleABCService.Screen() // limk web services: http://localhost:8686/soap/DMSBL009.asmx
{
CookieContainer = new CookieContainer(),
AllowAutoRedirect = true,
EnableDecompression = true,
Timeout = 60000
};
var loginResult = context.Login(string.Format("{0}#{1}", val.UserName, company), val.Password);
if (loginResult.Code != ErrorCode.OK)
{
throw new Exception(string.Format("Can not login {0}", company));
}
Content content = context.GetSchema();
context.Clear();
context.Submit(
new Command[]
{
content.Actions.ProcessAll
}
);
And I got an exception message:
System.Web.Services.Protocols.SoapExceptio:n Server was unable to process request. ---> PX.Data.PXUndefinedCompanyException: Unable determine proper company id for the request. at PX.Data.PXDatabaseProviderBase.getCompanyID(String tableName, companySetting& setting) in c:\Builders\4_10-2014_4_28-21_21_17-Full\Scripts\BuildTemp\NetTools\PX.Data\Database\Common\DbProviderBaseCompanies.cs:line 471...
Have you ever got this error before? Could you please give me any suggestion? Thank you so much!
Ok, I found out, because Acumatica's license