GithubHelp home page GithubHelp logo

wadewegner / force.com-toolkit-for-net Goto Github PK

View Code? Open in Web Editor NEW
369.0 74.0 396.0 5.43 MB

The Force.com Toolkits for .NET provides an easy way for .NET developers to interact with the Force.com & Chatter REST APIs using native libraries.

License: BSD 3-Clause "New" or "Revised" License

PowerShell 0.20% C# 99.11% Shell 0.69%

force.com-toolkit-for-net's Introduction

Force.com Toolkit for .NET Build Status

This SDK is now targeting .NET Standard 2.0, .NET 4.5.2, .NET 4.6.2, and .NET 4.7.2.

The Force.com Toolkit for .NET provides an easy way for .NET developers to interact with the Lighting Platform APIs using native libraries.

The Common Libraries for .NET provides functionality used by the Force.com Toolkit for .NET and the Chatter Toolkit for .NET. While you can use the Common Libraries for .NET independently, it is recommended that you use it through one of the toolkits.

NuGet Packages

Published Packages

You can try the libraries immmediately by installing the DeveloperForce.Force and DeveloperForce.Chatter packages:

Package Manager:

Install-Package DeveloperForce.Force
Install-Package DeveloperForce.Chatter

.NET CLI:

dotnet add package DeveloperForce.Force
dotnet add package DeveloperForce.Chatter

Operations

Currently the following operations are supported.

Authentication

To access the Force.com APIs you must have a valid Access Token. Currently there are two ways to generate an Access Token: the Username-Password Authentication Flow and the Web Server Authentication Flow

Username-Password Authentication Flow

The Username-Password Authentication Flow is a straightforward way to get an access token. Simply provide your consumer key, consumer secret, username, and password concatenated with your API Token.

var auth = new AuthenticationClient();

await auth.UsernamePasswordAsync("YOURCONSUMERKEY", "YOURCONSUMERSECRET", "YOURUSERNAME",
                                 "YOURPASSWORDANDTOKEN");

You can also specify a SalesForce API version when creating an authentication client if your use case requires it. The default API Version is currently v36.0

var auth = new AuthenticationClient("v44.0");

You can get the latest API version from your Force.com instance in authentication client.

var auth = new AuthenticationClient();
await auth.GetLatestVersionAsync();

Web-Server Authentication Flow

The Web-Server Authentication Flow requires a few additional steps but has the advantage of allowing you to authenticate your users and let them interact with the Force.com using their own access token.

First, you need to authenticate your user. You can do this by creating a URL that directs the user to the Salesforce authentication service. You'll pass along some key information, including your consumer key (which identifies your Connected App) and a callback URL to your service.

var url =
    Common.FormatAuthUrl(
        "https://login.salesforce.com/services/oauth2/authorize", // if using sandbox org then replace login with test
        ResponseTypes.Code,
        "YOURCONSUMERKEY",
        HttpUtility.UrlEncode("YOURCALLBACKURL"));

After the user logs in you'll need to handle the callback and retrieve the code that is returned. Using this code, you can then request an access token.

await auth.WebServerAsync("YOURCONSUMERKEY", "YOURCONSUMERSECRET", "YOURCALLBACKURL", code);

You can see a demonstration of this in the following sample application: https://github.com/developerforce/Force.com-Toolkit-for-NET/tree/master/samples/WebServerOAuthFlow

Creating the ForceClient

After this completes successfully you will receive a valid Access Token and Instance URL. The Instance URL returned identifies the web service URL you'll use to call the Force.com REST APIs, passing in the Access Token. Additionally, the authentication client will return the API version number, which is used to construct a valid HTTP request.

Using this information, we can now construct our Force.com client.

var instanceUrl = auth.InstanceUrl;
var accessToken = auth.AccessToken;
var apiVersion = auth.ApiVersion;

var client = new ForceClient(instanceUrl, accessToken, apiVersion);
var bulkClient = new BulkForceClient(instanceUrl, accessToken, apiVersion);

Sample Code

Below you'll find a few examples that show how to use the toolkit.

Create

You can create with the following code:

public class Account
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
}

var account = new Account() { Name = "New Account", Description = "New Account Description" };
var id = await client.CreateAsync("Account", account);

You can also create with a non-strongly typed object:

var client = new ForceClient(_consumerKey, _consumerSecret, _username, _password);
var account = new { Name = "New Name", Description = "New Description" };
var id = await client.CreateAsync("Account", account);

Update

You can update an object:

var account = new Account() { Name = "New Name", Description = "New Description" };
var id = await client.CreateAsync("Account", account);

account.Name = "New Name 2";

var success = await client.UpdateAsync("Account", id, account);

Delete

You can delete an object:

var account = new Account() { Name = "New Name", Description = "New Description" };
var id = await client.Create("Account", account);
var success = await client.DeleteAsync("Account", id)

Query

You can query for objects:

public class Account
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
}


var accounts = await client.QueryAsync<Account>("SELECT id, name, description FROM Account");

foreach (var account in accounts.records)
{
    Console.WriteLine(account.Name);
}

You can query for metadata:

var describe = await client.DescribeAsync<JObject>("Account");

foreach (var field in (JArray)describe["fields"))
{
    Console.WriteLine(field["label"]);
}

Bulk Sample Code

Below are some simple examples that show how to use the BulkForceClient

NOTE: The following features are currently not supported

  • CSV data type requests / responses
  • Zipped attachment uploads
  • Serial bulk jobs
  • Query type bulk jobs

Create

You can create multiple records at once with the Bulk client:

public class Account
{
    public string Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
}

var accountsBatch1 = new SObjectList<Account>
{
	new Account {Name = "TestStAccount1"},
	new Account {Name = "TestStAccount2"}
};
var accountsBatch2 = new SObjectList<Account>
{
	new Account {Name = "TestStAccount3"},
	new Account {Name = "TestStAccount4"}
};
var accountsBatch3 = new SObjectList<Account>
{
	new Account {Name = "TestStAccount5"},
	new Account {Name = "TestStAccount6"}
};

var accountsBatchList = new List<SObjectList<Account>>
{
	accountsBatch1,
	accountsBatch2,
	accountsBatch3
};

var results = await bulkClient.RunJobAndPollAsync("Account",
						BulkConstants.OperationType.Insert, accountsBatchList);

The above code will create 6 accounts in 3 batches. Each batch can hold upto 10,000 records and you can use multiple batches for Insert and all of the operations below. For more details on the Salesforce Bulk API, see the documentation.

You can also create objects dynamically using the inbuilt SObject class:

var accountsBatch1 = new SObjectList<SObject>
{
	new SObject
	{
		{"Name" = "TestDyAccount1"}
	},
	new SObject
	{
		{"Name" = "TestDyAccount2"}
	}
};

var accountsBatchList = new List<SObjectList<SObject>>
{
	accountsBatch1
};

var results = await bulkClient.RunJobAndPollAsync("Account",
                       BulkConstants.OperationType.Insert, accountsBatchList);

Update

Updating multiple records follows the same pattern as above, just change the BulkConstants.OperationType to BulkConstants.OperationType.Update

var accountsBatch1 = new SObjectList<SObject>
{
	new SObject
	{
		{"Id" = "YOUR_RECORD_ID"},
		{"Name" = "TestDyAccount1Renamed"}
	},
	new SObject
	{
		{"Id" = "YOUR_RECORD_ID"},
		{"Name" = "TestDyAccount2Renamed"}
	}
};

var accountsBatchList = new List<SObjectList<SObject>>
{
	accountsBatch1
};

var results = await bulkClient.RunJobAndPollAsync("Account",
                       BulkConstants.OperationType.Update, accountsBatchList);

Delete

As above, you can delete multiple records with BulkConstants.OperationType.Delete

var accountsBatch1 = new SObjectList<SObject>
{
	new SObject
	{
		{"Id" = "YOUR_RECORD_ID"}
	},
	new SObject
	{
		{"Id" = "YOUR_RECORD_ID"}
	}
};

var accountsBatchList = new List<SObjectList<SObject>>
{
	accountsBatch1
};

var results = await bulkClient.RunJobAndPollAsync("Account",
                       BulkConstants.OperationType.Delete, accountsBatchList);

Upsert

If your object includes a custom field with the External Id property set, you can use that to perform bulk upsert (update or insert) actions with BulkConstants.OperationType.Upsert. Note that you also have to specify the External Id field name when starting the job.

// Assumes you have a custom field "ExampleId" on your Account object
// that has the "External Id" flag set.

var accountsBatch1 = new SObjectList<SObject>
{
	new SObject
	{
		{"Name" = "TestDyAccount1"},
		{"ExampleId" = "ID00001"}
	},
	new SObject
	{
		{"Name" = "TestDyAccount2"},
		{"ExampleId" = "ID00002"}
	}
};

var accountsBatchList = new List<SObjectList<SObject>>
{
	accountsBatch1
};

var results = await bulkClient.RunJobAndPollAsync("Account", "ExampleId"
                       BulkConstants.OperationType.Upsert, accountsBatchList);

Contributing to the Repository

If you find any issues or opportunities for improving this respository, fix them! Feel free to contribute to this project by forking this repository and make changes to the content. Once you've made your changes, share them back with the community by sending a pull request. Please see How to send pull requests for more information about contributing to Github projects. You will be required to sign a Salesforce CLA for your submission to be considered.

Reporting Issues

If you find any issues with this demo that you can't fix, feel free to report them in the issues section of this repository.

force.com-toolkit-for-net's People

Contributors

alecdtucker avatar avesse avatar bluephlame avatar bregger avatar brentannelson avatar broctopolis avatar bslaterffdc avatar christianpeterek avatar dagood avatar dcarroll avatar eli-precisionlender avatar gnjack avatar johnmigas avatar johntrenwith avatar jrsteele23 avatar marknadig avatar mnltejaswini avatar newky2k avatar peranborkett avatar samtrost-avalara avatar shankararunachalam avatar shanselman avatar sheilak avatar tennyleaz avatar tugberkugurlu avatar vinickgold avatar wadewegner avatar wharri220 avatar zgramana avatar zhaph avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

force.com-toolkit-for-net's Issues

Get rid of all the useless UserAgent overloads

I find it more and more annoying that there are so many UserAgent overloads flying around the toolkit. This is a remnant of when it was three different toolkit solutions. We should remove them and have them set only once to "forcedotcom-toolkit-dotnet" which is tracked and searchable in Splunk.

Unable to login into salesforce with Console Application

image

System.AggregateException was caught
HResult=-2146233088
Message=One or more errors occurred.
Source=mscorlib
StackTrace:
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
at System.Threading.Tasks.Task.Wait()
at SalesforceApplication.Program.Main() in h:\ASP.net\SalesforceApplication\SalesforceApplication\Program.cs:line 29
InnerException: System.NullReferenceException
HResult=-2147467261
Message=Object reference not set to an instance of an object.
Source=SalesforceApplication
StackTrace:
at SalesforceApplication.Program.d__1c.MoveNext() in h:\ASP.net\SalesforceApplication\SalesforceApplication\Program.cs:line 53
InnerException:

Its showing above mentioned exception. Kindly help me on this

CreateAsync Task not completing.

I'm using the DeveloperForce.Force package to integrate a custom view of support cases as an Extranet on a company website. I'm using the following code to add a comment:

var client = await CreateClient();
dynamic comment = new ExpandoObject();
comment.CommentBody = "This is a test comment";
comment.IsPublished = true;
command.ParentId = caseId;

string commentId = await client.CreateAsync("CaseComment", comment);

But the CreateAsync method doesn't seem to want to complete. I can see in SalesForce that the comment has been added to the case though, but I'm unable to receive the Id of the comment so I can finish roundtripping my request back to the client.

We're using ASP.NET MVC, and the request is made to a controller via an AJAX request from the browser client. Interesting, though, read tasks, such as Query<Case> work fine and return results.

Deadlock when calling AuthenticationClient.UsernamePasswordAsync

Hi,

Thanks for you work on the Force Toolkit.
I get some calls made from an OWIN based app (+ WebAPI) to AuthenticationClient.UsernamePasswordAsync resulting in a deadlock since the .ConfigureAwait(false); seems to have been removed (commented) in this method.
I'm wondering why this configuration has been commented as this change is more likely to create deadlock if the code cannot get back to the request context.

Extracting data's of Custom Objects from SFDC

Hi,
I have to extract the data of custom objects created in SFDC..Is it possible to extract the data. If so Can you provide me some sample code??

Kindly help me to solve this issue.

New WebServerAsync overload

Create an overload of WebServerAsync that accepts the TokenRequestEndpointUrl but doesn't request UserAgent.

Like this:

await auth.WebServerAsync(_consumerKey, _consumerSecret, _callbackUrl, code, _tokenRequestEndpointUrl);

Deadlocking when calling UserInfo

I have tried a few things, but often, when calling the UserInfo in a really simple way (jquery getdata, calling the api)

    public async Task<UserInfo> Get([FromUri] string instanceUrl, [FromUri] string accessToken, [FromUri] string apiVersion, [FromUri] string Id)
    {
        var client = new ForceClient(instanceUrl, accessToken, apiVersion);
        UserInfo userInfo = await client.UserInfo<UserInfo>(accessToken, Id).ConfigureAwait(false);
        return userInfo;
    }

it blocks on the userinfo call. I do the same with queries and updates with no issue, but the UserInfo call is causing me a lot of trouble. I am not sure what is causing the deadlock or the issue, I get no errors, just a hung thread.

Invalid parsing of subquery results

I'm trying to do a count of child records. And while this is easy in SQL, Salesforce makes it pretty difficult.

I tried to go the subquery route:
SELECT Id, Name, [other fields], (select ID from [ChildTable]__r) FROM [Parent Table]

This results in JSON being returned in the sub select query:
[{"Id":"a11i0000003oFwHAAU"}]

First, I tried a string field for storing the result and got this error:
Message: "An error has occurred."
ExceptionMessage: "Error reading string. Unexpected token: StartObject. Path 'records[1].WBT_Courses__r', line 29, position 26."
ExceptionType: "Newtonsoft.Json.JsonReaderException"
StackTrace: " at Newtonsoft.Json.JsonReader.ReadAsStringInternal() at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadForType(JsonReader reader, JsonContract contract, Boolean hasConverter) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateList(IList list, JsonReader reader, JsonArrayContract contract, JsonProperty containerProperty, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateList(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, Object existingValue, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, Object target) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(Object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, String id) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, Object existingValue) at Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, Boolean checkAdditionalContent) at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType) at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, JsonSerializerSettings settings) at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings) at Salesforce.Common.ServiceHttpClient.d__11.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at AutoPoint.Web.Services.Salesforce.Controllers.V1Controller.d__30.MoveNext() in [location] --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Threading.Tasks.TaskHelpersExtensions.d__31.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at System.Web.Http.Controllers.ApiControllerActionInvoker.d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__0.MoveNext()"

So I change the property to a JObject:
public JObject WBT_Courses__r { get; set; }

And then I get this error:
Message: "An error has occurred."
ExceptionMessage: "Error setting value to 'WBT_Courses__r' on 'WBT_Track'."

The inner stack trace gives more detail:
InnerException: {
Message: "An error has occurred."
ExceptionMessage: "Unable to cast object of type 'Newtonsoft.Json.Linq.JValue' to type 'Newtonsoft.Json.Linq.JObject'."
ExceptionType: "System.InvalidCastException"
StackTrace: " at SetWBT_Courses__r(Object , Object ) at Newtonsoft.Json.Serialization.DynamicValueProvider.SetValue(Object target, Object value)"
}

So I think, "Ok, I'll change the object type to a JValue":
public JValue WBT_Courses__r { get; set; }

Now I get a similar error. The inner stack trace is amusing:
InnerException: {
Message: "An error has occurred."
ExceptionMessage: "Unable to cast object of type 'Newtonsoft.Json.Linq.JObject' to type 'Newtonsoft.Json.Linq.JValue'."
ExceptionType: "System.InvalidCastException"
StackTrace: " at SetWBT_Courses__r(Object , Object ) at Newtonsoft.Json.Serialization.DynamicValueProvider.SetValue(Object target, Object value)"
}

?? Huh? What am I missing to be able to perform this action?

Signed version of Salesforce assemblies available?

When I use the Saleforce.Force nuget package I get the following compile time errors:

Error 1 Assembly generation failed -- Referenced assembly 'Salesforce.Common' does not have a strong name
Error 2 Assembly generation failed -- Referenced assembly 'Salesforce.Force' does not have a strong name

That's because my assemblies are signed while the Salesforce assemblies are not.

Will there be signed assemblies of the assemblies available in future?

WebServerOAuthFlow HTTP 400 Bad Request

I am trying to use your WebServerOAuthFlow sample with my connected app.

Below my web.config file:

AuthorizationEndpointUrl" value="https://test.salesforce.com/services/oauth2/authorize"
ConsumerKey" value="XXXXX MY CONSUMER KEY XXXXXXXX"
ConsumerSecret" value="XXXXXXMY SECRETXXXXXXXX"
CallbackUrl" value="http://localhost:6054/api/callback"

The Authorization Endpoint Url is test because I am working on a sandbox at moment.

My achievement is to use Oauth from an external ASP.NET MVC application to log only users that have the authorization from salesforce.

Can you help please?

.Net 4.0 - Error compile - type or namespace name 'Salesforce' could not be found

Hi,

Thanks for you work on the DevelopperForce Toolkit.
In the readme document, the framework .Net 4.0 seems compatible with the toolkit.
The goal of my application is to read from Salesforce a table (as Account). The server used to execute the batch is a Windows 2003-R2 operating system.
So, I need to compile my project in .Net 4.0 framework, but when I do it Visual Studio find an error.

Here, you can find the step to reproduce my issues in Visual Studio 2012 :

  • Create an ConsoleApp project in C#
  • I set the target framework to version 4.0
  • By Nuget Package Console, I install the last version of DevelopperForce.Force (version 0.4.6)
  • Build : 0 errors, 16 warnings

The primary reference "Salesforce.Common" could not be resolved because it has an indirect dependency on the framework assembly "System.Collections, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" which could not be resolved in the currently targeted framework. ".NETFramework,Version=v4.0". To resolve this problem, either remove the reference "Salesforce.Common" or retarget your application to a framework version which contains "System.Collections, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a". Test

  • I add the using command line using Salesforce.Force;
  • Build : 1 errors, 16 warnings

The type or namespace name 'Salesforce' could not be found (are you missing a using directive or an assembly reference?)

I would like to know if you have a solution to run/use the toolkit on the .Net framework 4.0 ?

Regards,

Kikisaeba
(french developper)

Developer account login problem

I'm trying to use your library with a Salesforce Developer account.
I can't login.

the code I am using is the following:

// Using Sandbox credentials
var auth = new AuthenticationClient();
await auth.UsernamePasswordAsync(ConsumerKey, ConsumerSecret, Username, Password, "ua", "https://test.salesforce.com/services/oauth2/token");

The error is: expired access/refresh token

Remark: The following is working:

// Using Production credentials
var auth = new AuthenticationClient();
await auth.UsernamePasswordAsync(ConsumerKey, ConsumerSecret, Username, Password);

Allow HttpGetAsync() to page for more than 2k records at a time.

Currently HttpGetAsync utilizes the SF REST API that can only query up to 2k records. We could utilize pagination from that same call to retrieve all records for a query that are not limited to 2k and might have more than 2k records.

Here's an example taken from SF

You can execute a SOQL query that returns all the results in a single response, or if needed, returns part of the results and an
identifier used to retrieve the remaining results.

"If the initial query returns only part of the results, the end of the response will contain a field called nextRecordsUrl that allows you to implement pagination. For example, you might find this attribute at the end of your query:

"nextRecordsUrl" : "/services/data/v20.0/query/01gD0000002HU6KIAW-2000"

In such cases, request the next batch of records and repeat until all records have been retrieved. These requests use nextRecordsUrl, and do not include any parameters.

Example usage for retrieving the remaining query results:

curl https://na1.salesforce.com/services/data/v20.0/query/01gD0000002HU6KIAW-2000 -H "Authorization: Bearer token""

Here's my working example using using CommonLibrariesForNET: https://gist.github.com/fourq/8866605

I the only major change that would impact the library is that the httpGetAsync function signature changed to return Task<IList> instead of Task.

What do you think?

Visual Studio Tooling feedback for integrating Salesforce

Hi,
We're seeking feedback for how developers are using Salesforce when building applications within Visual Studio and would like your help to improve your development experience.

Our initial feedback would be conducted through a 30-45 minute phone call to understand the type of development your doing and how your using Salesforce. We'd like to understand the type of apps your building (web, mobile, desktop, services), what technologies your using to connect to Salesforce (REST, .NET SDK, SOAP) the authentication models your using, and what you'd like to see us improve.

If this matches your development and can spare some time to help improve the experience, please fill out this quick questionnaire so that we can schedule a call with you.

Click here to start the questionnaire.
http://1drv.ms/1hGIl74

Thank you,
Steve Lasker
Program Manager
Microsoft

Wade Wegner
Technical Evangelist
Salesforce

Contradiction in the license file

Hey guys,

While the license looks open-source-esque (this is yet to be fully determined), the second line of the license says "All rights reserved", which is in direct contradiction of the rights granted below. Since this is part of the "Copyright notice" that is referenced on those conditions and the conditions do not actually state that the license needs to be distributed, the only thing a user would see is the text above, which is clearly wrong.

Let me suggest that you guys pick a standard OSI-approved license instead. Ideally, use something like the MIT license or BSD without attributions. If you absolutely must, go with the MIT + attributions (MIT X11) or 3-clause BSD.

support for count() queries

Currently QueryAsync is returning IList. If I use "select count() from ", It does not return any results. Is there any way to get record count with out getting entire result of query?

Unable to retrieve data from salesforce

I tried with the sample provided in the link

image

But i got a new exception msg

System.AggregateException was unhandled
HResult=-2146233088
Message=One or more errors occurred.
Source=mscorlib
StackTrace:
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task1.GetResultCore(Boolean waitCompletionNotification) at System.Threading.Tasks.Task1.get_Result()
at ConsoleApplication1.Program.Main(String[] args) in h:\ASP.net\SalesforceApplication\SalesforceApplication\Program.cs:line 33
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException: Salesforce.Common.ForceException
HResult=-2146233088
Message=API is not enabled for this Organization or Partner
Source=Salesforce.Common
StackTrace:
at Salesforce.Common.ServiceHttpClient.d__1`1.MoveNext()
InnerException:

Kindly provide some soln

Better error messages for invalid queries.

During writing a sample, I made a mistake and used the following line to issue a query:

var accounts = await client.Query<Account>("SELECT ID, Name FROM Account WHERE Name = " + account.Name);

Note the missing 's around the account name. The correct line should be:

var accounts = await client.Query<Account>("SELECT ID, Name FROM Account WHERE Name = '" + account.Name + "'");

The exception message that comes back is:

Cannot deserialize the current JSON array (e.g. [1,2,3]) into type 'Salesforce.C
ommon.Models.ErrorResponse' because the type requires a JSON object (e.g. {"name
":"value"}) to deserialize correctly.

To fix this error either change the JSON to a JSON object (e.g. {"name":"value"}
) or change the deserialized type to an array or a type that implements a collec
tion interface (e.g. ICollection, IList) like List<T> that can be deserialized f
rom a JSON array. JsonArrayAttribute can also be added to the type to force it t
o deserialize from a JSON array.

Is there any way to provide a better error message, or the underlying exception message sent from Salesforce?

UpsertExternalAsync method requires recordId

It is possible I do not understand the SDK, however, it seems like a bug that the SalesForce.Force.ForceClient.UpsertExternalAsync() method requires a recordId parameter (and it can not be null or an empty string).

If I am inserting the record for the first time, I will not know the recordId. (assuming here that the "recordId" is the Id given to the record by SalesForce.)

Username-Password Authentication Flow in sandbox

Hello,
I tried to use the Username-Password Authentication Flow in a Console Application with my Salesforce sandbox but it doesn't work. Here is my code:

// Using Sandbox credentials
var auth = new AuthenticationClient();
await auth.UsernamePasswordAsync(ConsumerKey, ConsumerSecret, Username, Password, "ua", "https://test.salesforce.com/services/oauth2/token");

The error is: expired access/refresh token

Remark: The following is working:

// Using Production credentials
var auth = new AuthenticationClient();
await auth.UsernamePasswordAsync(ConsumerKey, ConsumerSecret, Username, Password);

Fix all the System.Net.Http references

Every time the Microsoft.Net.Http version revs it breaks the .NET 4.5 class projects. This is because the latter are "hard coded" to use the NuGet's version of System.Net.Http to resolve Travis CI & Mono.NET builds.

There has to be a way to solve this issue.

Can't create Windows Store App package

I can't create a Windows Store App package, because it fails the application certification with the following reasons:

Error Found: The debug configuration test detected the following errors:

  • The binary Salesforce.Common.dll is built in debug mode.
  • The binary Salesforce.Force.dll is built in debug mode.

I installed the latest version of the Force.com Toolkit through NuGet.

Import Bulk Data to SFDC using .Net

Hi,
Is it possible to load bulk data either from CSV file or from Database to SFDC through .net coding??
If possible can you help me to achieve this?

Query a custom object with error...

I am querying a custom object (tried both QueryByIdAsync and QueryAsync) and am constantly getting "sObject type '...__c' is not supported...". Should I be calling this a different way? See below for the code example...

My query code is simple:

var sodolineitem = await client.QueryByIdAsync<SODO_Line_Item__c>(SODO_Line_Item__c.SObjectTypeName, "a5D11000000CbJd");

or

var sodolineitem = await client.QueryAsync<SODO_Line_Item__c>("select Id, Product__c, DO_Line_Number__c from SODO_Line_Item__c where Id = " + "\'a5D11000000CbJd\'");

Then:

public class SODO_Line_Item__c
{
        public const String SObjectTypeName = "SODO_Line_Item__c";

        public String Id { get; set; }
        public String Product__c { get; set; }
        public String Productcode__c { get; set; }
        public String DO_Line_Number__c { get; set; }
        public String SO_Line_Number__c { get; set; }
        public String SODO_ID__c { get; set; }
}

Username-Password Authentication thows exception

As the title says ... the exception i get is "expired access/refresh token"
and i simply call await auth.UsernamePasswordAsync(_consumerKey, _consumerSecret, "xxxxx@xxx", "xxxxx", UserAgent, _tokenRequestEndpointUrl);
as per the example.

Am i missing something ?

Error 413 - content too long

While running a long migration script, I found that after a few hundred operations, I was getting a 413 error - content too long. I fired up Fiddler and looked at the data sent to Salesforce. The offending payload's Accept header had hundreds of application/json values in the Accept header. As I looked at the prior entries, it went like this:
Operation #1. Accept: application/json
Operation #2. Accept: application/json, application/json
Operation #3. Accept: application/json, application/json, application/json
... etc. until 413 error

I believe the issue is related to the static member HttpClient _httpClient and this:
_httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

I worked around the issue by reauthenticating every 100 requests, but that's slow.

Regards - Jeff Adkisson

Not able to connect to Sales force

Hi,
when I try to execute the code "Force.com-Toolkit-for-NET / samples / SimpleConsole / Program.cs "
I got an error at this line and my solution get exits from this line:

await auth.UsernamePasswordAsync(ConsumerKey, ConsumerSecret, Username, Password, ".net-api-client", url);

Following is the error msg I got:

An error occurred while sending the request.
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNot
ification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at Salesforce.Common.AuthenticationClient.d__7.MoveNex
t()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNot
ification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()
at SimpleConsole.Program.d__23.MoveNext() in c:\Users\JA270478\Des
ktop\ConsoleApplication1\ConsoleApplication1\Program.cs:line 71
The remote server returned an error: (407) Proxy Authentication Required.
at System.Net.HttpWebRequest.EndGetRequestStream(IAsyncResult asyncResult, Tr
ansportContext& context)
at System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar
)

SOQL queries are not always escaped properly

I am attempting to query for events with the word "Demo" in their type using the following query:

SELECT Type, COUNT(Id) DemoCount FROM Event WHERE Type LIKE '%Demo%' GROUP BY Type

The query works fine in the Force.com Developer Console, but was returning nothing when I tried to submit it using ForceClient's QueryAsync in my program. I captured the network traffic being sent from the program to SalesForce and discovered the following:

GET /services/data/v29.0/query?q=SELECT%20Type,%20COUNT(Id)%20DemoCount%20FROM%20Event%20WHERE%20Type%20LIKE%20'%Demo%25'%20GROUP%20BY%20Type

More specifically,

LIKE%20'%Demo%25'%20

Note that the initial % in the string '%Demo%' is not being URL Encoded at all. To confirm this was the case, I manually changed my query to

SELECT Type, COUNT(Id) DemoCount FROM Event WHERE Type LIKE '%25Demo%' GROUP BY Type

and sure enough it worked fine.

Looking at the documentation for the Uri object that is doing the parsing in ServiceHttpClient, it says that it will only escape percents that are not followed by a valid escape sequence. I guess my "escape sequence" of %de happens to be a valid one, so it ignores that first percent. Personally I would run the query through a simple string replacement to replace all the percents with %25 ahead of time since nobody would really want to put a URI escape sequence in a SOQL query on purpose. If you think this is acceptable I could do a pull request and fix it myself.

(Sorry I'm a bit new to GitHub and don't know if I should file a bug first or just go right for the pull request. Thanks for the great library! :)

Insert/Update Document Object

Does the Force.com-Toolkit support insert/update of the document object? Also does it support querying document objects?

login with sales force

Hi,
I am getting the below error while trying to login Salesforce.com through C#. Can you please help me to solve this issue.

Error:
at Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type
objectType)
at Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectT
ype)
at Newtonsoft.Json.JsonConvert.DeserializeObject(String value, Type type, Jso
nSerializerSettings settings)
at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSeriali
zerSettings settings)
at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value)
at Salesforce.Common.AuthenticationClient.d__7.MoveNex
t()
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNot
ification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.GetResult()

ADFS authentication?

Is it possible to authenticate to salesforce using ADFS? Salesforce is already setup for single signon.

UpsertExternalAsync for new records using External ID not working

Using upsert:

var success = await client.UpsertExternalAsync(Account.SObjectTypeName, "External_Id__c", account.ExternalId, account);

Return the following exception:

One or more errors occurred.
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at System.Threading.Tasks.Task.Wait()
   at RefreshSalesforceOrg.Program.Main() in c:\Visual Studio 2013\Projects\RefreshSalesforceOrg\RefreshSalesforceOrg\Program.cs:
line 31
No such column 'ExternalId' on sobject of type Account
   at Microsoft.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task tas
k)
   at Microsoft.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccess(Task task)
   at Microsoft.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   at Microsoft.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Salesforce.Force.ForceClient.<UpsertExternalAsync>d__13.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at RefreshSalesforceOrg.Program.<AccountsUpsert>d__1.MoveNext() in c:\Visual Studio 2013\Projects\RefreshSalesforceOrg\RefreshSalesforceOrg\Program.cs:line 71

Calling ForceClient.UserInfo returns 404 not found

After we authenticate, we're receiving:

Status Code: 404
Reason Phrase: Not Found
And a message that we can see: "Internal_Error"

We call
AuthenticationClient.WebServerAsync
then
ForceClient.UserInfo

Using instantiated objects, not implying that we're using static method calls etc. I just didn't want to post the entire code block.

It's odd though as if we make the same call immediately after the initial call to UserInfo fails, it works.. it returns a 200 and the expected data.

However, we do run into the case where the 404 happens every single time we call it. It doesn't matter how many times we try to re-run it. It fails. This is what we're hoping to resolve.

Based on what we can see, the authentication process works. We can see the logs under our connected app and we're getting a valid auth token etc. back.

Any thoughts?

DeveloperForce.Force version 0.4.0 has old version of Salesforce.Force.dll

Just wondering if an older version of the dll was used on purpose in the DeveloperForce.Force 0.4.0. I noticed this because the IForceClient is private now in the current version I pulled from Nuget.

Looking at the dll using IL Spy I do see an old version of the IForceClient.
image

One other change that appears to be missing is the static httpclient fix.

image

Merge into a single solution & NuGet package

Originally I designed Chatter & Force toolkits to use the Common Libraries for HTTP calls and common functionality. This was primarily because it was believed that someone using the Force Toolkit wouldn't necessarily want/need the Chatter toolkit. It's become a pain to update, however, as it requires updating the Common Libraries, packaging & publishing the NuGet, and then pulling the NuGets into the Force or Chatter libraries simply to make an update.

I propose we merge the Common Libraries into the Force Toolkit. Then we setup a dependency on the Force Toolkit from the Chatter Toolkit. All in the same solution.

When publishing NuGet packages, however, we'll publish DeveloperForce.Force (which will now include the Common Libraries) and DeveloperForce.Chatter (which takes a dependency on DeveloperForce.Force).

I think this is reasonable and makes sense. It will keep things cleaner, easier to update, and easier to publish.

@dcarroll, I'd like to get your opinion on this issue.

UpsertExternalAsync doesn't return a value ?

Would it be better if it returned the SF Id from the REST response that SF sends back instead of returning true ?

If the record is new, I will have to query again for the SF id which I need to do the rest of the updates that are related to a given sObject...

Thanks,
Greg

Deserializing results from Parent to child query

I am trying to use some polymorphic behavior for nested queries, but facing some issues in deserialized results.

Given below is minified object structure I am using.

public class sObject
{
string Id{get;set;}
}

public class QueryResult
{
public sObject[] records{get;set;}
}

public class Order:sObject
{
public DateTime Date{get;set;}
public QueryResult OrderItems__r {get;set;}
}

public class OrderItem: sObject
{
public float Price {get;set;}
}

Query used:
select Date, (select Id, Price from OrderItems__r) from Order

I am able to execute this query using the toolkit and got results. But I am getting a type conversion error in the following line.
order.OrderItems__r.records.Cast()

I tried modifying the toolkit using some serializer settings while deserializing (JsonSerializerSettings.TypeNameHandling.All), but no luck so far.

Any thoughts on this issue?

UpsertExternalAsync for existing records erases other values not being updated

Using Upsert I have updated a couple of fields of an object. The Upsert works fine and updated the 2 fields i needed. But, it also erased all the other field values. Can you show a code example of how I can use UpdateAsync or UpsertExternalAsync to update just a certain fields without effecting the other fields. Here is the code that am using.
var addr = new Address { Bill62__Street_1__c = "222 Park st" };
var success = await client.UpsertExternalAsync(Address.SObjectTypeName, "Bill62__Legacy_Id__c", "523", addr);

OAuth - Revoke Token

Hi,
I am using your library successfully to integrate an MVC application with the SalesForce Oauth and to fetch data's.

I full used your sample code in WebServerOAuthFlow and all good.

My problem now is how to logoff and make sure the login page is showed again.

I thought that the revoke of the token was enough but not.

This the situation:

  1. a user digit my website address, if not logged in then redirect to Oauth page.
  2. once he login with salesforce the server callback my webapi and I store the logged status in session.
  3. then I have a logoff button with a actionlink that revoke the token of salesforce, empty the session and redirect to the home page.

Till here all fine, but when I reopen the website, the oAuth page redirect me automatically to the home page as seems that the authentication happens automatically.

Any suggestion?

thank you in advance

Unable to retrieve data from salesforce

I tried with the sample provided in the link

image

But i got a new exception msg

System.AggregateException was unhandled
HResult=-2146233088
Message=One or more errors occurred.
Source=mscorlib
StackTrace:
at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
at System.Threading.Tasks.Task1.GetResultCore(Boolean waitCompletionNotification) at System.Threading.Tasks.Task1.get_Result()
at ConsoleApplication1.Program.Main(String[] args) in h:\ASP.net\SalesforceApplication\SalesforceApplication\Program.cs:line 33
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException: Salesforce.Common.ForceException
HResult=-2146233088
Message=API is not enabled for this Organization or Partner
Source=Salesforce.Common
StackTrace:
at Salesforce.Common.ServiceHttpClient.d__1`1.MoveNext()
InnerException:

Kindly provide some soln

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.