I need to develolp a WPF application that use the OData service of a Project Online Server. When I try to reference the OData service with ODataLib V4, it doesn't work because the OData service is secure.
Anyone know a workaround for this problem ?
I found the solution.
Extract the metadata of Project Online in xml file (https://[your pwa site]/_api/ProjectData/$metadata)
Change the extension of the xml file to .edmx
Execute DataSvcUtil in your Framework directory (DataSvcUtil /in:edmxfile.edmx /out:csfile.cs /language:CSharp)
Add the csfile.cs in your .Net Project
Add the following references in your project :
- Microsoft.SharePoint.Client
- Microsoft.SharePoint.Client.DocumentManagement
- Microsoft.SharePoint.Client.Publishing
- Microsoft.SharePoint.Client.Runtime
- Microsoft.SharePoint.Client.Runtime.Windows
- Microsoft.SharePoint.Client.Taxonomy
- Microsoft.SharePoint.Client.UserProfiles
- Microsoft.SharePoint.Client.WorkflowServices
- Microsoft.SharePoint.WorkflowServices.Activities
- Microsoft SharePoint Solutions Framework
Here, an example of the code :
private const string PSDATA = "https://[your pwa site]";
ProjectOData.ReportingData context =
new ProjectOData.ReportingData(new Uri(PSDATA + "/_api/ProjectData/", UriKind.Absolute)) { IgnoreMissingProperties = true };
var username = <username>;
var password = <password>;
var secureString = new System.Security.SecureString();
foreach (char c in password.ToCharArray())
{
secureString.AppendChar(c);
}
context.Credentials = new SharePointOnlineCredentials(username, secureString);
SharePointOnlineCredentials credentials = new Microsoft.SharePoint.Client.SharePointOnlineCredentials(username, secureString);
var authenticationCookie = credentials.GetAuthenticationCookie(new Uri(PSDATA));
context.SendingRequest += delegate (object sender, SendingRequestEventArgs e)
{
e.RequestHeaders.Clear();
e.RequestHeaders.Add("Cookie", authenticationCookie);
};
var projectQuery1 = from p in context.Projects
select p;
Related
I am making a WinForm application using C#. When i try to connect OneDrive using SharePoint Client Object Model it gives me an error of "Value cannot be null".
Please guide me where i am making mistake. I need guidance on this.
private void GetClientContext()
{
using (ClientContext clientContext = new ClientContext("https://techiesworld-my.sharepoint.com/"))
{
SecureString passWord = new SecureString();
//passtxt.Text = passWord.ToString();
//foreach (char c in passtxt.Text.ToCharArray()) passWord.AppendChar(c);
clientContext.Credentials = new SharePointOnlineCredentials(accountxt.Text, passWord);
Web web = clientContext.Web;
clientContext.Load(web);
clientContext.ExecuteQuery();
MessageBox.Show(web.Title);
}
I am getting exception on clientContext.ExecuteQuery() function.
Context
My core goal is to write an Azure WebApps deployment tool in C#. The process will be roughly
User logs in
User selects subscription
User selects or creates resource group
User selects or creates storage for the web app
User selects or creates web service plan
User selects or creates web app
Tool uploads the web app using Kudu to POST a zip
Since the last step can't be done in the portal, my idea was to do everything in a GUI tool.
I started out using Kudu's ARMClient.Authentication and Microsoft.Azure.ResourceManager 1.0.0-preview. However, when it comes to creating a storage account I get a permissions error (The subscription is not registered to use namespace Microsoft.Storage), so my plan B was to do the authentication myself following Brady Gaster's blog post.
The problem
I've set up an application as documented, and using its clientId and tenantId I'm able to log in and list tenants. But I can't list any subscriptions. (NB I've partly elided the clientId and tenantId in case there are security risks with giving them in full).
string clientId = "f62903b9-ELIDED";
string tenantId = "47b6e6c3-ELIDED";
const string redirectUri = "urn:ietf:wg:oauth:2.0:oob";
const string baseAuthUri = "https://login.microsoftonline.com/";
const string resource = "https://management.core.windows.net/";
var ctx = new AuthenticationContext(baseAuthUri + tenantId);
var authResult = ctx.AcquireToken(resource, clientId, new Uri(redirectUri), PromptBehavior.Auto);
var token = new TokenCredentials(authResult.AccessToken);
var subClient = new SubscriptionClient(token);
var tenants = await subClient.Tenants.ListAsync();
foreach (var tenant in tenants) Console.WriteLine(tenant.TenantId);
var subs = await subClient.Subscriptions.ListAsync();
foreach (var sub in subs) Console.WriteLine(sub.DisplayName);
When I run this it prompts me to login, and lists the tenants corresponding to the subscriptions I own or co-administer. But it doesn't list a single subscription. If I change the IDs to the commonly used (I think officially for Powershell) values
clientId = "1950a258-227b-4e31-a9cf-717495945fc2";
tenantId = "common";
then it's the same.
What is the step I've missed in order to get a list of my subscriptions?
You need to iterate through the tenants, authenticate in tenant and get a subscription list for every tenant.
The following code will output the Subscriptions like Get-AzureRmSubscription powershell cmdlet does.
class Program
{
private static string m_resource = "https://management.core.windows.net/";
private static string m_clientId = "1950a258-227b-4e31-a9cf-717495945fc2"; // well-known client ID for Azure PowerShell
private static string m_redirectURI = "urn:ietf:wg:oauth:2.0:oob"; // redirect URI for Azure PowerShell
static void Main(string[] args)
{
try
{
var ctx = new AuthenticationContext("https://login.microsoftonline.com/common");
// This will show the login window
var mainAuthRes = ctx.AcquireToken(m_resource, m_clientId, new Uri(m_redirectURI), PromptBehavior.Always);
var subscriptionCredentials = new TokenCloudCredentials(mainAuthRes.AccessToken);
var cancelToken = new CancellationToken();
using (var subscriptionClient = new SubscriptionClient(subscriptionCredentials))
{
var tenants = subscriptionClient.Tenants.ListAsync(cancelToken).Result;
foreach (var tenantDescription in tenants.TenantIds)
{
var tenantCtx = new AuthenticationContext("https://login.microsoftonline.com/" + tenantDescription.TenantId);
// This will NOT show the login window
var tenantAuthRes = tenantCtx.AcquireToken(
m_resource,
m_clientId,
new Uri(m_redirectURI),
PromptBehavior.Never,
new UserIdentifier(mainAuthRes.UserInfo.DisplayableId, UserIdentifierType.RequiredDisplayableId));
var tenantTokenCreds = new TokenCloudCredentials(tenantAuthRes.AccessToken);
using (var tenantSubscriptionClient = new SubscriptionClient(tenantTokenCreds))
{
var tenantSubscriptioins = tenantSubscriptionClient.Subscriptions.ListAsync(cancelToken).Result;
foreach (var sub in tenantSubscriptioins.Subscriptions)
{
Console.WriteLine($"SubscriptionName : {sub.DisplayName}");
Console.WriteLine($"SubscriptionId : {sub.SubscriptionId}");
Console.WriteLine($"TenantId : {tenantDescription.TenantId}");
Console.WriteLine($"State : {sub.State}");
Console.WriteLine();
}
}
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
finally
{
Console.WriteLine("press something");
Console.ReadLine();
}
}
}
A couple things you can look into...
1) the error you saw during creating of the storage account is likely due to the Resource Provider not being registered for use with the subscription. Any RP needs to be registered before use, some clients (Portal, PowerShell) will register the RP for you so you never notice it. See: https://msdn.microsoft.com/en-us/library/azure/dn790548.aspx - you should be able to do that from your code if the user has sufficient perms.
2) You may not be getting any subscriptions back because your endpoint (management.core.windows.net) is the endpoint for Azure Service Management not Azure Resource Manager (management.azure.com). If the subscription access is granted via AzureRM and RBAC, the old ASM apis will not see (i.e. have access to) those subscriptions.
I tried authenticating with Google Admin Api-sdk But We get some file missings error which should be created by the Dlls, we are using.
Even after adding all the recommended dlls after going through many article for the same, I din get over to this. Here is the code im using.
protected void Page_Load(object sender, EventArgs e)
{
const string serviceAccountEmail = "<id>#developer.gserviceaccount.com";
const string serviceAccountCertPath = #"E:\Test.p12";
const string serviceAccountCertPassword = "notasecret";
const string userEmail = "admin#mydomain.com";
var certificate = new X509Certificate2(serviceAccountCertPath, serviceAccountCertPassword, X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(serviceAccountEmail)
{
Scopes = new[] { DirectoryService.Scope.AdminDirectoryUser },
User = userEmail
}.FromCertificate(certificate));
var service = new DirectoryService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "User Provisioning",
});
User newuserbody = new User();
UserName newusername = new UserName();
newuserbody.PrimaryEmail = "Harsh#test.com";
newusername.GivenName = "Harsh";
newusername.FamilyName = "Sharma";
newuserbody.Name = newusername;
newuserbody.Password = "test#123";
User results = service.Users.Insert(newuserbody).Execute();
}
}
}
I am using this code for new user provisioning but Google.Apis.Admin.Directory.directory_v1.cs not found while debugging due to this authentication got failed. Please anybody let me know to to get Google.Apis.Admin.Directory.directory_v1.cs file. As much i know i have already added all the dlls added.
The Namespaces i am using are as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Google.Apis.Auth.OAuth2;
using Google.Apis.Services;
using Google.Apis.Util.Store;
using Google.Apis.Admin.Directory.directory_v1;
using Google.Apis.Admin.Directory.directory_v1.Data;
using DotNetOpenAuth.GoogleOAuth2;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using Google.Apis.Auth.OAuth2.Requests;
using Google.Apis.Auth.OAuth2.Responses;
As per the documentation, you need to download an extra NuGet package for each API you want to use. These packages contain the generated code for that particular API.
thanks all for replying,
I managed to run it successfully, I had all the reference, Code was upto the mark as well.
The Only problem was with the admin setting there in the google admin panel.
I manage to correct them as per my request to google API's and it worked fine.
http://blogs.microsoft.co.il/blogs/shair/archive/2011/12/07/tfs-api-part-41-manage-groups-and-members.aspx
He can't get group name belong to a user using WPF base on TeamProjectPicker instant:
private void BtnConnectClick(object sender, RoutedEventArgs e)
{
DisableUi();
var tpp = new TeamProjectPicker(TeamProjectPickerMode.NoProject, false);
tpp.ShowDialog();
if (tpp.SelectedTeamProjectCollection == null) return;
EnableUi();
_tfs = tpp.SelectedTeamProjectCollection;
_css = (ICommonStructureService)_tfs.GetService<ICommonStructureService>();
_gss = (IGroupSecurityService)_tfs.GetService<IGroupSecurityService>();
var allSids = _gss.ReadIdentity(SearchFactor.AccountName,
"Project Collection Valid Users", QueryMembership.Expanded);
listAllUsers.ItemsSource = _gss.ReadIdentities(SearchFactor.Sid, allSids.Members,
QueryMembership.None).Where(a => a.Type == IdentityType.WindowsUser
|| a.Type == IdentityType.WindowsGroup);
listProjects.ItemsSource = _css.ListAllProjects();
}
I can't do it when implement this function on asp.net MVC
You will need to implement your own Project Picker or supply the project collection uri directly to the TfsTeamProjectCollectionfactory.GetProjectCollection method. See the documentation here.
To create your own Project Picker, you can use the TfsConfigurationServerFactory.GetConfigurationServer to connect to a TFS instance. See the documentation here. Then you can query all the Team Project Collections and the underlying Team Projects from there. See the following piece of documentation for more information.
In a Silverlight application I sometimes need to connect to the web site where the application is hosted. To avoid hard coding the web site in my Silverlight application I use code like this:
WebClient webClient = new WebClient();
Uri baseUri = new Uri(webClient.BaseAddress);
UriBuilder uriBuilder = new UriBuilder(baseUri.Scheme, baseUri.Host, baseUri.Port);
// Continue building the URL ...
It feels very clunky to create a WebClient instance just to get access to the URL of the XAP file. Are there any alternatives?
Application.Current.Host.Source retrieves the URI of the XAP.
I use,
Uri baseUri = new Uri(Application.Current.Host.Source, "/");
// Example results:
// http://www.example.com:42/
// or
// https://www.example.com/
No string parsing needed!
You can also use this method to create full Urls, for example,
Uri logoImageUri = new Uri(Application.Current.Host.Source, "/images/logo.jpg");
// Example result:
// http://www.example.com/images/logo.jpg
This will build the root url in ASP.NET. You would then need to pass in baseUrl via Silverlight's InitParams and add "ClientBin\silverlight.xap".
// assemble the root web site path
var baseUrl = Request.Url.Scheme + "://" + Request.Url.Authority + Request.ApplicationPath.TrimEnd ('/') + '/';
In my case, I am not working in the main folder. I am working in h||p://localhost:1234/subfolder. That is no problem while working in Visual Studio IDE. But when moving to the server it fails. The following lines
Application.Current.Host.Source
can be replaced through a public function with result like this:
Public Sub AppPathWeb()
Res = Application.Current.Host.Source.AbsoluteUri.Substring(0, Application.Current.Host.Source.AbsoluteUri.LastIndexOf("/") + 1)
Return New Uri(Res)
End Sub
As Result, I can catch my files like this
MyImage = New Uri(AppPathWeb, "HelloWorld.jpg")
And the result is, that on server the url goes to h||p://mydomain.com/mysubfolder/HelloWorld.jpg"
Good luck
goldengel.ch