Programatically access TFS account to get project names and work items - c#

I've been trying to access a TFS account (programatically using the TFS SDK) in order to get information such as the project names, work item names and developpment times for each work item.
I wasn't able to get project or work item information, but I was able to authenticate and access TFS using the class TfsTeamProjectCollection.
However, using the class TfsConfigurationServer, I was never able to authenticate to the server. This is a pity because the majority of examples I've seen in the web use this TfsConfigurationServer class.
The code that allows me to access TFS:
// Connect to Team Foundation Server.
NetworkCredential netCred = new NetworkCredential("myEmail#email.com", "myPassword");
BasicAuthCredential basicCred = new BasicAuthCredential(netCred);
TfsClientCredentials tfsCred = new TfsClientCredentials(basicCred);
tfsCred.AllowInteractive = false;
TfsTeamProjectCollection tpc = new TfsTeamProjectCollection(new Uri("https://tfs.gfi.pt:4430/tfs/gfi/"),tfsCred);
tpc.Authenticate(); // This one works, and when I enter tpc I can see I am correctly signed-in in TFS (I can for instance check my full name)
ITeamProjectCollectionService projCollect = tpc.GetService<ITeamProjectCollectionService>(); //returns null :(
I have 2 questions:
What is the difference between the TfsConfigurationServer and the TfsTeamProjectCollection? I know the first leads me to the Server-Level and the second to the Collection-level, but, what is the server-level and collection-level?
Why am I unable to get the projectCollection when I am perfectly capable of signing-in (why does the last line returns null when I am sure I have 2 projects on TFS)?

Regarding question #1, you can find some whys in Introducing the TfsConnection, TfsConfigurationServer and TfsTeamProjectCollection Classes. Shortly, you can have many user databases, i.e. Collection, managed by a single TFS instance, i.e. the Server.

I just found out what the problem was. I just needed to replace the last line:
ITeamProjectCollectionService projCollect = tpc.GetService<ITeamProjectCollectionService>(); //returns null :(
By:
// Get the catalog of team project collections
ReadOnlyCollection<CatalogNode> collectionNodes = tpc.CatalogNode.QueryChildren(
new [] { CatalogResourceTypes.TeamProject},
false, CatalogQueryOptions.None);
// List the team project collections
foreach (CatalogNode collectionNode in collectionNodes)
{
Console.WriteLine(collectionNode.Resource.DisplayName);
}

Related

SharePoint CSOM call failing to small list

We have a Console application which makes SharePoint CSOM calls to a list in a SharePoint site in an intranet.
This call works with a list with 1000+ records. However this call is failing when we deployed the Console application in a different machine in the intranet.
It cannot be MaxReceivedMessageSize or MaxParseMessageSize because it works elsewhere.
Is there a machine specific setting that needs to be taken care?
The code looks like this:
using (var clientContext = new ClientContext(SharePointSiteUrl))
{
clientContext.Credentials = AuthenticationHelper.GetNetworkCredential();
var list = clientContext.Web.Lists.GetByTitle(RequestsList);
var requestIdField = list.Fields.GetByInternalNameOrTitle("RequestID");
var query = CamlQuery.CreateAllItemsQuery();
var items = list.GetItems(query);
clientContext.Load(requestIdField);
clientContext.Load(items);
clientContext.ExecuteQuery();
foreach (var request in requests)
{
var itemCreateInfo = new ListItemCreationInformation();
var newItem = list.AddItem(itemCreateInfo);
newItem[requestIdField.InternalName] = request.RequestID;
newItem.Update();
}
clientContext.ExecuteQuery();
result = true;
}
ERROR:
AppName: Unhandled Exception: Details: Message:The request message is too big. The server does not allow messages larger than 2097152 bytes.
StackTrace: at Microsoft.SharePoint.Client.ClientRequest.ProcessResponseStream(Stream responseStream)
at Microsoft.SharePoint.Client.ClientRequest.ProcessResponse()
at Microsoft.SharePoint.Client.ClientRequest.ExecuteQueryToServer(ChunkStringBuilder sb)
at Microsoft.SharePoint.Client.ClientRequest.ExecuteQuery()
at Microsoft.SharePoint.Client.ClientRuntimeContext.ExecuteQuery()
at Microsoft.SharePoint.Client.ClientContext.ExecuteQuery()
at AppName.SharePoint.SharePointHelper.Method3(List`1 requests)
at AppName.Program.Method2()
at AppName.Program.Main(String[] args)
TargetSite:Void ProcessResponseStream(System.IO.Stream)
Source:Microsoft.SharePoint.Client.Runtime
SharePoint has its own limits for CSOM. Unfortunately, these limits cannot be configured in Central Administration and also cannot be set using CSOM for obvious reasons.
When googling for the issue, mostly a solution is given by setting the ClientRequestServiceSettings.MaxReceivedMessageSize property to the desired size.
Call the following PowerShell script from SharePoint Management Shell :
$ws = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
$ws.ClientRequestServiceSettings.MaxReceivedMessageSize = 209715200
$ws.Update()
This will set the limit to 200 MB.
However, in SharePoint 2013 Microsoft apparently added another configuration setting to also limit the amount of data which the server shall process from a CSOM request (Why anyone would configure this one differently is beyond me...). After reading a very, very long SharePoint Log file and crawling through some disassembled SharePoint server code, I found that this parameter can be set via the property ClientRequestServiceSettings.MaxParseMessageSize.
We are now using the following script with SharePoint 2013 and it works great:
$ws = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
$ws.ClientRequestServiceSettings.MaxReceivedMessageSize = 209715200
$ws.ClientRequestServiceSettings.MaxParseMessageSize = 209715200
$ws.Update()

LDAP search fails on server, not in Visual Studio

I'm creating a service to search for users in LDAP. This should be fairly straightforward and probably done a thousand times, but I cannot seem to break through properly. I thought I had it, but then I deployed this to IIS and it all fell apart.
The following is setup as environment variables:
ldapController
ldapPort
adminUsername 🡒 Definitely a different user than the error reports
adminPassword
baseDn
And read in through my Startup.Configure method.
EDIT I know they are available to IIS, because I returned them in a REST endpoint.
This is my code:
// Connect to LDAP
LdapConnection conn = new LdapConnection();
conn.Connect(ldapController, ldapPort);
conn.Bind(adminUsername, adminPassword);
// Run search
LdapSearchResults lsc = conn.Search(
baseDn,
LdapConnection.SCOPE_SUB,
lFilter,
new string[] { /* lots of attributes to fetch */ },
false
);
// List out entries
var entries = new List<UserDto>();
while (lsc.hasMore() && entries.Count < 10) {
LdapEntry ent = lsc.next(); // <--- THIS FAILS!
// ...
}
return entries;
As I said, when debugging this in visual studio, it all works fine. When deployed to IIS, the error is;
Login failed for user 'DOMAIN\IIS_SERVER$'
Why? The user specified in adminUsername should be the user used to login (through conn.Bind(adminUsername, adminPassword);), right? So why does it explode stating that the IIS user is the one doing the login?
EDIT I'm using Novell.Directory.Ldap.NETStandard
EDIT The 'user' specified in the error above, is actually NOT a user at all. It is the AD registered name of the computer running IIS... If that makes any difference at all.
UPDATE After consulting with colleagues, I set up a new application pool on IIS, and tried to run the application as a specified user instead of the default passthrough. Exactly the same error message regardless of which user I set.
Try going via Network credentials that allows you to specify domain:
var networkCredential = new NetworkCredential(userName, password, domain);
conn.Bind(networkCredential);
If that does not work, specify auth type basic (not sure that the default is) before the call to bind.
conn.AuthType = AuthType.Basic;

TF400813: Resource not available for anonymous access. Client authentication required

I am working on the CodedUI Test Automation project. i am developing a framework in which i am trying to access Test Cases in VSTS through RestAPI. I have worked on an MVC application previously in which i did the same thing to pull data from VSTS using RestAPI.
Now the problem is i am not able to access the VSTS. Everytime i am trying to access the VSTS, i got the exception TF400813: Resource not available for anonymous access. Client authentication required.
I am using the same PAT token. I have all the required access on my team project. I am able to access all work items in my project from browser. I have tried all the option mentioned in below thread but still its not working.
Client authentication error when starting Visual Studio 2015.3Any leads will be appreciated.Below is my code to get data from VSTS:
public static List<WorkItem> GetWorkItemsWithSpecificFields(IEnumerable<int> ids)
{
var collectionUri = "https://<name>.visualstudio.com";
var fields = new string[] {
"System.Id",
"System.Title",
"System.WorkItemType",
"Microsoft.VSTS.Scheduling.RemainingWork"
};
using (WorkItemTrackingHttpClient workItemTrackingHttpClient = new WorkItemTrackingHttpClient(new Uri(collectionUri), new VssBasicCredential("", System.Configuration.ConfigurationManager.AppSettings["PATToken"])))
{
// Exception is coming on below line
List<WorkItem> results = workItemTrackingHttpClient.GetWorkItemsAsync(ids, fields).Result;
return results;
}
}

Acumatica Web Services API Login

I am attempting to perform some basic integration using Acumatica's web services. Unfortunatly, I'm having problems logging in. According to their documentation, this process should look something like:
apitest.Screen context = new apitest.Screen();
context.CookieContainer = new System.Net.CookieContainer();
context.AllowAutoRedirect = true;
context.EnableDecompression = true;
context.Timeout = 1000000;
context.Url = "http://localhost/WebAPIVirtual/Soap/APITEST.asmx";
LoginResult result = context.Login("admin", "E618");
Simple enough. However, after creating and importing a WSDL file from Acumatica into Visual Studio, I found I don't have a Screen object. I do, however have a ScreenSoapClient object, which has a similar Login() method.
ScreenSoapClient context = new Acumatica.ScreenSoapClient("ScreenSoap");
LoginResult result = context.Login("username", "password");
That part works. In fact, the LoginResult give me a session ID. However, if I try to make any calls to the service, such as:
CR401000Content cr401000 = context.CR401000GetSchema();
I get an error: System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> PX.Data.PXNotLoggedInException: Error #185: You are not currently logged in.
While the version of Acumatica we're using does appear to be slightly newer, I'm unsure why the Screen() object isn't available. Consequently, if I try a bad username/password, Login() does fail (as it should). From what I can the tell, the ScreenSoapClient class is using service model details from web.config, so it's getting the endpoint address and other details there.
Is there something I'm missing or doing wrong?
As i see, you use WCF to create your service reference.
So you should enable cookies in service binding:
var binding = new BasicHttpBinding()
{
AllowCookies = true
};
var address = new EndpointAddress("http://localhost/WebAPIVirtual/Soap/APITEST.asmx");
var c = new ServiceReference1.ScreenSoapClient(binding, address);
Or, you can use old asmx web service reference (http://msdn.microsoft.com/en-us/library/bb628649.aspx).
Then everything will be same as in Acumatica`s documentation.
As noted in a comment above, I was able to make contact with a representative from Acumatica. He had me remove then recreate the service references in our project and try again. That apparently did the trick and the "Error #185: You are not currently logged in" error went away.

Retrieve list item using CSOM on SharePoint online isn't working

m developing an app model on SharePoint online using the provider hosted model.
From clientwebpart, I want to access a Sharepoint list item. I can access list a object but can't get the list item (always empty). I already followed the sample code at "Apps for SharePoint sample pack - SharePoint 2013 Perform basic data access operations by using CSOM in apps", but still does not work.
Here is my code:
SharePointContextToken contextToken;
Uri sharepointUrl;
string accessToken;
TokenHelper.TrustAllCertificates();
string contextTokenString = TokenHelper.GetContextTokenFromRequest(Request);
if (contextTokenString != null)
{
contextToken = TokenHelper.ReadAndValidateContextToken(contextTokenString, Request.Url.Authority);
sharepointUrl = new Uri(Request.QueryString["SPHostUrl"]);
accessToken = TokenHelper.GetAccessToken(contextToken, sharepointUrl.Authority).AccessToken;
using (ClientContext clientContext = TokenHelper.GetClientContextWithAccessToken(sharepointUrl.ToString(), accessToken))
{
Web web = clientContext.Web;
ListCollection lists = web.Lists;
List selectedList = lists.GetByTitle("LeaveCategory");
clientContext.Load<ListCollection>(lists); // this lists object is loaded successfully
clientContext.Load<List>(selectedList); // this list object is loaded successfully
clientContext.ExecuteQuery();
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml = #"<View><Query><Where><IsNotNull><FieldRef Name='ID' /></IsNotNull></Where></Query><ViewFields><FieldRef Name='ID' /></ViewFields></View>";
Microsoft.SharePoint.Client.ListItemCollection listItems = selectedList.GetItems(camlQuery);
clientContext.Load<Microsoft.SharePoint.Client.ListItemCollection>(listItems); // problem here, this list items is return empty
clientContext.ExecuteQuery();
}
}
Is there any trivial mistake that I am making?
Also, I am trying to create fresh new project and follow instruction of How to: Create a basic provider-hosted app for SharePoint, and appending code toretrieve list item, but it still returns 0 item.
Did anyone ever succeeded achieving this?
Its working now,
its because we must add specific permission for the app at file AppManifest.xml
I add "List" at scope and give it permission "FullControl"
After doing only below along with List scope full permissions, its worked for me:
In the Scope cell, choose Web from the drop down list.
In the Permission cell, choose Read from the drop down list.

Categories