Is it possible to execute an SPDataSource object query in a console app for testing?
e.g.:
SPDataSource source = new SPDataSource
{
UseInternalName = true,
DataSourceMode = SPDataSourceMode.List,
SelectCommand = "<View/>"
};
source.SelectParameters.Add("WebId", TypeCode.String, "rootweb");
source.SelectParameters.Add("ListName", TypeCode.String, "Contacts");
var c = source.GetView();
var d = c.Select();
I think the context info is missing but can't figure out how to add it?
I just looked at it in Refelector and it ends up creating a class called SPDataSourceView which depends on SPContext.
I have never been able to creat an SPContext from a console application because of constructors marked as internal.
One option would be to put your class into a Web Service that is deployed to your SharePoint Farm. Then have your console application call this Web Service. However you might be better off using one of the Out of Box SharePoint Web Services.
I´m not sure what you´re after here, I mean
Testing your SPDataSource in console app (nothing to do like said by JD)
Getting data from sharepoint in a datasource manner.
If your´re going for solution 2 you could use a linqdatasource instead of the spdatasource.
See my post on this if that´s what your´re looking for.
Related
We're moving most of our web presence to our SharePoint server in the cloud. Our current setup uses a MVC Web API for data retrieval from DB. We do not want to host the API under a separate domain and thus need to move the API under SharePoint domain as well. There is no relaxation in this requirement.
Is there a way to publish my API to SharePoint? Or is there a SharePoint specific API project template in Visual Studio? If not what are my options?
EDIT Initially I have asked that MVC API needs to be part of the SharePoint 2013. But now things are such that API can reside anywhere - inside or outside - of SharePoint, as long as it is accessible from the root domain - which so far it seems not allowed (Error message: Calls to WebProxy without an app context are not allowed."). Still trying to see if this is possible, and if yes, how?
It sounds like the proxy you want to create is already part of SharePoint JSOM. Have a look at these:
http://msdn.microsoft.com/en-us/library/office/fp179895(v=office.15).aspx
http://msdn.microsoft.com/en-us/library/office/jj245162(v=office.15).aspx
This will allow you to overcome cross origin issues. The SP.WebProxy and SP.WebRequestInfo allow you to use javascript to make a call outside of the domain where the javascript executes.
What really happens behind the scenes is that SharePoint's javascript API sends the request to your sharepoint.com tenancy server, which will then invoke the service from the SharePoint server, and return the response back to your javascript. You can implement it like so in a sharepoint-hosted app:
// this javascript executes from my-company.sharepoint.com
var responseDocument = undefined;
$('#cross').click(function () {
var ctx = SP.ClientContext.get_current();
var request = new SP.WebRequestInfo();
request.set_url('https://www.somewebapi.com/my/custom/route');
request.set_method("GET");
responseDocument = SP.WebProxy.invoke(ctx, request); // executes on sp server
ctx.executeQueryAsync(onSuccess, onError);
});
function onSuccess() {
var response = responseDocument.get_body();
alert('success ' + response);
}
function onError(err) {
alert(JSON.stringify(err));
}
...and since the remote api hosted at the other domain is called from the server, you don't have to worry about any of the cross-domain issues.
Update
To answer your update, please check the results from this link.
Have you added the remote endpoint to your AppManifest.xml?
SharePoint doesn't give you a chance to define you own routes. Thats why you can not use old fashioned SharePoint solution to publish asp.net web api. You may consider using apps for SharePoint. It's like separate App with some connections to SharePoint.
Ultimately switched to JSONP solution. Installed the WebApiContrib.Formatting.JsonP in my MVC Web API project in Visual Studio, and modified SharePoint JavaScript, that calls the API, to include ?callback=? (callback is equal to question mark). Everything stays the same. No SharePoint's proxy caller needed! No SharePoint app needed!
This is regarding SharePoint 2010 Integration with MSCRM 2011.
While creating a record in CRM, trying to create a Custom Document location for that record and a similar folder in sharepoint, So that when user clicks on document link in the entity record it does not prompt user to create folder in Sharpoint (Trying to avoid sharepoint noise for better user experience)
I have implemented through post create asynchronous plug-in. (I did this through console program working fine). Build the plugenter code here-in and deployed to CRM.
When creating a record it error out with a message like "An internal server 500 error - Could not load the assembly with public key token etc…blab bla bla…”
But when I am debugging the plug-in it failed at the first line of command where I am instantiating sharePoint method Create client context of sharepoint, it says [System.Security.SecurityException]={“That assembly does not allow partially trusted callers”.}
As per google, per this issue it should be having one attribute “Allow partial users” in assembly info file. As per my understanding, this should be done in because the request goes from CRM plug-in to SharePoint dll. I mean share point dlls are not allowing request from my assembly. How can we change that?
I have referenced Microsoft.SharePoint.client.dll and Microsoft.SharePoint.Client.Runtime.dll
What is the alternate to overcome this issue?
Appreciate if some one can help me ..Thanks In advance.
Here is my code for SharePoint
ClientContext clientContext = new ClientContext(siteUrl)
CredentialCache cc = new CredentialCache();
Cc.Add(new Uri(siteUrl), "NTLM", CredentialCache.DefaultNetworkCredentials);
clientContext.Credentials = cc;
clientContext.AuthenticationMode = ClientAuthenticationMode.Default;
Web web = clientContext.Web;
SP.List list = web.Lists.GetByTitle(listName);
ListItemCreationInformation newItem = new ListItemCreationInformation();
newItem.UnderlyingObjectType = FileSystemObjectType.Folder;
newItem.FolderUrl = siteUrl + "/" + folderlogicalName;
if (!relativePath.Equals(string.Empty))
newItem.FolderUrl += "/" + relativePath;
newItem.LeafName = newfolderName;
SP.ListItem item = list.AddItem(newItem);
item.Update();
clientContext.ExecuteQuery();
Where I am passing the siteurl, folderlogicalname,relativepath and new foldername as parameters.
This works fine from my Console application. But when converted to CRM plug-in it gives the above specified issue
I've seen a similar issue before.
CRM plugins run inside a sandbox, so all assemblies and .NET libraries used must allow partial trust callers (since the CRM sandbox runs under partial trust). It works in the console because you are executing the code as a full trust user in that context.
This issue is not necessarily your code, but could be a dependency or a .NET library itself does not allow partial trust callers - in your case it sounds like the Sharepoint library is the culprit (but a stack trace of the error should reveal exactly where the cause is).
Since you don't have access to the source library causing the problem, to overcome the error you will likely have to create a wrapper. However, the problem is the wrapper cannot directly reference the problem library or you will get the same issue. So to get around this, you may have to create a web service which acts as your wrapper and then call the web service in your CRM plugin. This way the full trust code is executed by the web service (which is full trust) and then returns the result to your calling CRM plugin.
Here is more info on the error.
Thanks Jason. This works for me.
I Would like to add additional few points to the answer.
1. I have added the sharepoint dlls to the bin folder of CRM 2011 site.
2. Also deployed the same dlls in the folder whereever Async job is running to make my Async plug-in to work.
Thanks once again for the cooperation
My problem is simple. I have a registered Sharepoint site/domain (say https://secretText-my.sharepoint.com/personal/blabla) and I want to fetch the changelogs as described here Sharepoint Change log
So my question boils down to >>> How can I use this Changelog API to fetch data for a remote Sharepoint site?
How can I achieve this? I have tried Client Object Model and everything related but my goal is to use Sharepoint Change log.
I am hoping for something like,
using (ClientContext ctx = ClaimClientContext.GetAuthenticatedContext("https://secretText-my.sharepoint.com/personal/blabla"))
{
if (ctx != null)
{
ctx.Load(ctx.Web); // Query for Web
ctx.ExecuteQuery(); // Execute
ctx.Load(ctx.Site);
ctx.ExecuteQuery();
SPSite site = new SPSite(ctx.Site.Id);
SPContentDatabase db = site.ContentDatabase;
// Get the first batch of changes,
SPChangeCollection changes = db.GetChanges();
//USE this 'site' object to fetch the change logs
.
.
.
My aim is to somehow instantiate this SPSite object which would then help me get the data I want. Although this code seems a bit too ambitious(or totally wrong) but please don't hold it against me, I couldn't find any solution to this.
Much appreciated!
After a lot of Google searches and after reading so many answers, I have come to know that it isn't possible to connect to a remote Sharepoint server through the Server API. As that API works only when SP server is on the same network (same machine or intranet)
The only solution is to use Client Object Model. It provides(maps) quite a lot operations that the Server API gives.
To connect to the remote site I have used the samples provided at the MSDN site for Client Object Model. Here
I'm writing an application in which I have to log on to a CRM 2011 server from ASP.NET code. I quickly found this article:
http://msdn.microsoft.com/en-us/library/cc156363.aspx
The problem I'm having is in this bit of code from that article:
//Create the Service
CrmService service = new CrmService();
service.Credentials = System.Net.CredentialCache.DefaultCredentials;
service.CrmAuthenticationTokenValue = token;
service.Url = crmurl;
Visual Studio can't resolve CrmService. So I tried to add a web reference to this project and point the web reference at the CRM service I'm using. The URL I'm getting from Settings->Customizations in CRM, and I'm using the Organization Service endpoint. However, after I add that reference CrmService is still unresolvable. What am I doing wrong?
First off, you have linked a CRM 4 MSDN article, some things have changed so you might want try this one instead: Authenticate Users with Microsoft Dynamics CRM Web Services.
Then as an alternative you may want to try the CrmConnection class, its a helper library in Microsoft.Xrm.Client. It means you can use a connection string approach to authenticate with CRM (and let the class takes care of all the hard work).
var connection = CrmConnection.Parse("Url=http://crm.contoso.com/xrmContoso; Domain=CONTOSO; Username=jsmith; Password=passcode;");
var service = new OrganizationService(connection);
var context = new CrmOrganizationServiceContext(connection);
You can also keep the connection strings in config files makes life significantly easier.
Related articles:
Simplified Connection to Microsoft Dynamics CRM.
Sample: Simplified Connection Quick Start using Microsoft Dynamics CRM.
If you're using standard AD authentication with a local environment this answer should work fine: How to Authenticate to CRM 2011?
Actually, the login procedure is heavily dependent on the authentication provider you're targeting. I'm currently in the process of structuring that info in a pedagogic way on my blog so you're welcome to check it out and nag if it's too techy.
There are at the moment four such ways.
Active directory
Live id
Federation
Online federation
Which is applicable in your case, you should know already. If not, there's code for that too uploaded just a few days ago.
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
...
public AuthenticationProviderType GetAuthenticationProviderType(Uri address)
{
IServiceManagement<IOrganizationService> organizationServiceManagement
= ServiceConfigurationFactory.CreateManagement
<IOrganizationService>(address);
return organizationServiceManagement.AuthenticationType;
}
Assuming that you're aiming for AD, you're in luck. It's the easiest.
Uri organizationUrl = new Uri("http ... Organization.svc");
OrganizationServiceProxy organizationService = new OrganizationServiceProxy(
organizationUrl, null, null, null);
If you're aiming for Live Id - that's stingy. I'm still trying to set up a graspable example. The ones at MSDN are just too heavy and confusing. At least when one's dense and lazy like me. More info at mentioned but undisclosed location.
This is a question for a WSS/SharePoint guru.
Consider this scenario: I have an ASP.Net web service which links our corporate CRM system and WSS-based intranet together. What I am trying to do is provision a new WSS site collection whenever a new client is added to the CRM system. In order to make this work, I need to programmatically add the managed path to the new site collection. I know that this is possible via the Object Model, but when I try it in my own web service, it fails. Sample code extract below:
Dim _ClientSiteUrl As String = "http://myintranet/clients/sampleclient"
Using _RootWeb As SPSite = New SPSite("http://myintranet")
Dim _ManagedPaths As SPPrefixCollection = _RootWeb.WebApplication.Prefixes
If Not (_ManagedPaths.Contains(_ClientSiteUrl)) Then
_ManagedPaths.Add(_ClientSiteUrl, SPPrefixType.ExplicitInclusion)
End If
End Using
This code fails with a NullReferenceException on SPUtility.ValidateFormDigest(). Research suggested that this may be due to insufficient privileges, I tried running the code within an elevated privileges block using SPSecurity.RunWithElevatedPrivileges(AddressOf AddManagedPath), where AddManagedPath is a Sub procedure containing the above code sample.
This then fails with an InvalidOperationException, "Operation is not valid due to the current state of the object."
Where am I going wrong?
One workaround I have managed to do is to call out to STSADM.EXE via Process.Start(), supplying the requisite parameters, and this works.
Update: whilst developing the web service, I am running it using the built-in Visual Studio 2005 web server - what security context will this be running under? Can I change the security context by putting entries in web.config?
Update: I think the problem is definitely to do with not running the web service within the correct SharePoint security context. I decided to go with the workaround I suggested and shell out to STSADM, although to do this, the application pool identity that the web service runs under must be a member of the SharePoint administrators.
Update
I think you have proved that the issue is not with the code.
SPSecurity.RunWithElevatedPrivileges: Normally the code in the SharePoint web application executes with the privileges of the user taking the action. The RunWithElevatedPrivileges runs the code in the context of the SharePoint web application pools account (i think)
The description on MSDN could go into the details a tiny bit more.
The issue with the call may be that the web service is not actually running the code within a SharePoint process, so explaining why it cannot elevate (wild guess alert).
Have a crack at changing the user of your web services application pool and see if that gives any joy.
It is likely to be a permissions issue.
Maybe try:
Dim clientSiteUrl As String = "http://myintranet/clients/sampleclient"
Using SPSite = new SPSite(clientSiteUrl)
webApp As SPWebApplication = SPWebApplication.Lookup(new Uri(clientSiteUrl));
If Not (webApp.Prefixes.Contains(clientSiteUrl)) Then
webApp.Prefixes.Add(clientSiteUrl, SPPrefixType.ExplicitInclusion)
End If
End Using
This is not exact code.
Since the above code is not the exact code, here is the exact working code for a Web Application scopped feature in the Feature Activated event:
On feature activation at the Mange web application features page, activate feature will create a new Explicit managed path in the specified web application (I want to replace the hard coding, maybe with Properties.Feature.Parent, or something similar.)
using (SPSite site = new SPSite("http://dev-moss07-eric/PathHere")) {
SPWebApplication webApp = SPWebApplication.Lookup(new Uri("http://dev-moss07-eric"));
if (webApp.Prefixes.Contains("PathHere"))
{
//
}
else
{
webApp.Prefixes.Add("PathHere", SPPrefixType.ExplicitInclusion);
}
}
Code can probably be improved, but its my attempt at converting the above code.
If you want to create a managed path (explicit) and a site collection at that path, do the following:
using (SPSite site = new SPSite("http://dev-moss07-eric")) {
SPWebApplication webApp = SPWebApplication.Lookup(new Uri("http://dev-moss07-eric"));
if (webApp.Prefixes.Contains("ManagedPathHere"))
{
//
}
else
{
webApp.Prefixes.Add("ManagedPathHere", SPPrefixType.ExplicitInclusion);
}
using (SPWeb web = site.OpenWeb())
{
SPWebApplication webApplication = web.Site.WebApplication;
try
{
webApplication.Sites.Add("ManagedPathHere","Site Title Here","This site is used for hosting styling assets.", 1033, "STS#1", "6scdev\\eric.schrader", "Eric Schrader", "eric.schrader#6sc.com");
}
catch (Exception ex)
{
//ex.ToString;
}
}
}