GithubHelp home page GithubHelp logo

.net-sdk's Introduction

Build Status NuGet

.NET SDK for the DreamFactory REST API

The .NET SDK provides classes and interfaces to access the DreamFactory REST API.

Quick links

Solution structure

The Visual Studio solution has these projects:

  • DreamFactory : the API library
  • DreamFactory.AddressBook : ASP.NET MVC web app demonstrating API usage in a real world example.
  • DreamFactory.Demo : console program demonstrating API usage (with some integration tests)
  • DreamFactory.Tests : Unit Tests (MSTest)

The solution folder also contains:

  • ReSharper settings file (team-shared),
  • NuGet package specification file,
  • this README file.

Distribution

The package can be either installed from nuget.org or simply built from the source code with Visual Studio.

install-package DreamFactoryNet

Alternatively, check this article on how to manage NuGet packages in Visual Studio: https://docs.nuget.org/consume/installing-nuget

Dependencies

The API has been built with unirest-net library. Although the underlying HTTP layer can be substituted (see further), it's recommended to use the default implementation.

unirest-net, in turn, has the following dependencies:

  • Microsoft.Bcl (≥ 1.1.10)
  • Microsoft.Bcl.Build (≥ 1.0.21)
  • Microsoft.Bcl.Async (≥ 1.0.168)
  • Newtonsoft.Json (≥ 7.0.1)
  • Microsoft.Net.Http (≥ 2.2.29)

Supported platforms

  • ASP.NET 4.5, 4,6
  • ASP.NET 5
  • Android (Xamarin)
  • iOS (Xamarin)
  • WinRT and WinRT Phone (Windows 8 and Phone 8.1)
  • Windows Phone Silverlight 8

At this moment UAP10.0 (Universal App Platform) is not supported because of the dependancy on unirest-net that doesn't support that target.

Demo

To run the demos, you need to install DreamFactory stack version 2.0+ on your machine.

Running the Address Book Demo

Configure the DreamFactory instance to run the app:

  • Enable CORS for development purposes.

    • In the admin console, navigate to the Config tab and click on CORS in the left sidebar.
    • Click Add.
    • Set Origin, Paths, and Headers to *.
    • Set Max Age to 0.
    • Allow all HTTP verbs and check the Enabled box.
    • Click update when you are done.
    • More info on setting up CORS is available here.
  • Create a default role for new users and enable open registration

    • In the admin console, click the Roles tab then click Create in the left sidebar.
    • Enter a name for the role and check the Active box.
    • Go to the Access tab.
    • Add a new entry under Service Access (you can make it more restrictive later).
      • set Service = All
      • set Component = *
      • check all HTTP verbs under Access
      • set Requester = API
    • Click Create Role.
    • Click the Services tab, then edit the user service. Go to Config and enable Allow Open Registration.
    • Set the Open Reg Role Id to the name of the role you just created.
    • Make sure Open Reg Email Service Id is blank, so that new users can register without email confirmation.
    • Save changes.
  • Import the package file for the app.

    • From the Apps tab in the admin console, click Import and locate add_dotnet.dfpkg file in DreamFactory.AddressBook/App_Package folder. The Address Book package contains the application description, schemas, and sample data.
    • Leave storage service and folder blank because this app will be running locally.
    • Click the Import button. If successful, your app will appear on the Apps tab. You may have to refresh the page to see your new app in the list.
  • Make sure you have a SQL database service named 'db'. Depending on how you installed DreamFactory you may or may not have a 'db' service already available on your instance. You can add one by going to the Services tab in the admin console and creating a new SQL service. Make sure you set the name to 'db'.

  • The demo also requires a couple of constants to be specified in DreamFactoryContext.cs file located in the DreamFactory.AddressBook project. Open the file and modify the settings to match your setup.

	public const string BaseAddress = "http://localhost:8080";
	public const string AppName = "<app_name>";
	public const string AppApiKey= "<app_api_key>";
	public const RestApiVersion Version = RestApiVersion.V2;
	public const string DbServiceName = "db";
	public const string FileServiceName = "files";

You can now run the app by starting the DreamFactory.AddressBook project in your browser. When the app starts up you can register a new user, or log in as an existing user (ex. admin you've set up first time you opened DreamFactory admin app).

Running the Console Demo

Console demo requires a test user to be specified in Program.cs file. Open the file and modify the settings to match your setup.

	internal const string BaseAddress = "http://localhost:8080";
	internal const string AppName = "<app_name>";
	internal const string AppApiKey = "<app_api_key>";
	internal const string Email = "<user_email>";
	internal const string Password = "<user_password>";

Note that the test user must have a role which allows any HTTP verbs on any services/resources.

  • Open DreamFactoryNet solution in Visual Studio 2012 or newer;
  • Open Program.cs and modify the settings;
  • In Solution Explorer window find DreamFactory.Demo project, right-click on it and select Set as StartUp project;
  • In Visual Studio main menu, select DEBUG -> Run without debugging;
  • A console window will appear with demo output;
  • If the demo has been completed successfully, you will see the total number of tests executed.

API

Basics

The API provides the following functions:

  1. Simple HTTP API, for making arbitrary HTTP requests;
  2. DreamFactory API (closely matching the Swagger definition),
  3. Various extensions and builders to simplify managing DreamFactory models.

All network-related API calls are asynchronous, they all have Async suffix. The IO-bound calls (HTTP request and stream IO) have ConfigureAwait(false).

Errors handling

  • On wrong arguments (preconditions), expect ArgumentException to be thrown.
  • On Bad HTTP status codes, expect DreamFactoryException to be thrown.

DreamFactoryException is normally supplied with a reasonable message provided by DreamFactory server, unless it fails with an HTML page returned with the response.

  • On content serialization errors (JSON by default), expect Json.NET exceptions to be thrown.

Serialization may fail if returned objects do not match the strongly-typed entities defined with the API. This may happen in particular when DreamFactory services change their contract in a breaking way.

HTTP API overview

Regular users would not deal with this API subset unless they have outstanding needs to perform advanced queries. However, it is very likely that these users will step down this API while debugging, therefore it is recommended to know the basics.

HTTP layer is defined with the following interfaces:

  • IHttpFacade with the single method SendAsync(),
  • IHttpRequest representing an HTTP request,
  • IHttpResponse representing an HTTP response,

The SDK comes with unirest-net implementation of IHttpFacade - the UnirestHttpFacade class. A user can define its own implementation to use it with DreamFactory API. Providing a custom IHttpFacade instance could be useful for mocking purposes and IoC.

IHttpRequest supports HTTP tunneling, by providing SetTunneling(HttpMethod) function. This function modifies the request instance in according with the tunneling feature supported by DreamFactory.

Here is an example:

	string url = "https://www.random.org/cgi-bin/randbyte?nbytes=16&format=h";
	IHttpRequest request = new HttpRequest(HttpMethod.Get, url);
	IHttpFacade httpFacade = new UnirestHttpFacade();
	IHttpResponse response = await httpFacade.SendAsync(request);
	Console.WriteLine("Response CODE = {0}, BODY = {1}", response.Code, response.Body);

DreamFactory API overview

Each DreamFactory's service has a corresponding interface that exposes all functions you could find in Swagger definition. Some functions, however, were split and some were reduced to remain reasonable and consistent to .NET users.

The service instances are created with IRestContext.Factory methods:

	IRestContext context = new RestContext(BaseAddress);
	IUserApi userApi = context.Factory.CreateUserApi();
	Session session = await userApi.LoginAsync("demo", "api_key", "[email protected]", "qwerty");
	Console.WriteLine("Logged in as {0}", session.display_name);

Specify service name for creating an interface to a named service:

	IRestContext context = new RestContext(BaseAddress);
	IFilesApi filesApi = context.Factory.CreateFilesApi("files");
	await filesApi.CreateFileAsync(...);

Serialization

The API supports pluggable serialization. This SDK comes with the default JsonContentSerializer which is using Json.NET. To use your custom serializer, consider using the other RestContext constructor accepting a user-defined IContentSerializer instance.

By default Json.NET resolves property names as they are defined in the class unless specified otherwise with JsonPropertyAttribute.

SQL query parameters

Most DreamFactory resources persist in the system database, e.g. Users, Apps, Services. When calling CRUD API methods accessing these resources be prepared to deal with related SQL query parameters. All such APIs accept a SqlQuery class instance. You can populate any fields of this class, but do check swagger contract for the service you about to use. The API implementation will set any non-null fields as query parameters.

Default SqlQuery constructor populates the single property: *fields=**. This results in all fields to be read.

REST API versioning

Supported API versions defined by RestApiVersion enumeration. V2 is used by default. The SDK uses version for building the complete URL, e.g. /rest for V1 and /api/v2 for V2. Note that building the URL is done transparently to the users.

IRestContext interface

Besides the IRestContext.Factory object which is designed to construct service instances, the interface offers few discovery functions:

  • GetServicesAsync()
  • GetResourcesAsync()

See the demo program for usage details.

User API

See IUserApi and DEMO

All API calls require Application-Name header as well as Application-Api-Key to be set and many others require Session-ID header. Here is how these headers are managed by SDK:

  • Both Application-Name and Application-Api-Key are being set when initializng RestContaxt.
  • Session-ID header is set upon IUserApi.LoginAsync() or ISystemApi.LoginAdminAsync() completion,
  • Session-ID header gets removed upon IUserApi.LogoutAsync() or ISystemApi.LogoutAdminAsync() completion,
  • Session-ID header gets updated if another login is made during ChangePasswordAsync() or ChangeAdminPasswordAsync() call.

To use/set another Application-Name and Application-Api-Key you have to instantiate new RestContaxt.

CustomSettings API

See ICustomSettingsApi and DEMO

The API can be created for user and system namespace. Please refer to the demo for sample API usage.

Files API

See IFilesApi and DEMO

Summary on supported features:

  • CRUD operations on folders and files,
  • Bulk files upload/download in ZIP format,
  • Text and binary files read/write.

Reading/Writing of metadata associated with file entities (folder, file) are not supported.

Database API

See IDatabaseApi and DEMO

Notes on schema management

To simplify TableSchema construction, SDK offers TableSchemaBuilder class that implement Code First approach:

	// Your custom POCO
	class StaffRecord
	{
		public int Uid { get; set; }
		public string FirstName { get; set; }
		public string LastName { get; set; }
		public int Age { get; set; }
	}

	// Create tabe schema from StaffRecord type
	ITableSchemaBuilder builder = new TableSchemaBuilder();
	builder.WithName(TableName).WithFieldsFrom<StaffRecord>().WithKeyField("uid").Build();

For more advanced scenarios and relationship building you should build up your own TableSchema object:

	TableSchema schema = new TableSchema();
    schema.Name = "<table_name>";
    schema.Field = new List<FieldSchema>
    {
        // fields...
        new FieldSchema
        {
            Name = "<foreign_key_column_name>",
            Type = "reference",
            AllowNull = false,
            RefTable = "<related_table_name>",
            RefFields = "<related_table_column_name>"
        },
        // more fields...
    };
    
    await databaseApi.CreateTableAsync(staffSchema);

API does not offer schema operations on dedicated fields. Use UpdateTableAsync method to update any table's schema.

Notes on table records operations
  • Input are user-defined POCO classes that must match the corresponding table's schema;
  • Output is instance of DatabaseResourceWrapper containing records and metadata if it was requested.
Notes on stored procedures/functions

When calling a stored procedure or function, some overloads use a collection of StoreProcParams instances. To simplify creating such a collection, consider using StoreProcParamsBuilder class. When response (or return values) is expected, a user must define TStoredProcResponse POCO that shall have fields for OUT-parameters and for wrapper. It's recommended to read the technical notes on stored procedures: https://github.com/dreamfactorysoftware/dsp-core/wiki/SQL-Stored-Procedures

Email API

See IEmailApi and DEMO

Sending an email will require EmailRequest object to be built. For an advanced use, construct this object manually by providing all essential information. For a simple use, consider using EmailRequestBuilder class that lets you building a request in few simple steps:

EmailRequest request = new EmailRequestBuilder()
							.AddTo("[email protected]")
							.WithSubject("Hello")
							.WithBody("Hello, world!")
							.Build();

System API

See ISystemApi and DEMO

Current limitations
  • Reading/writing of metadata related to system records are not supported.
  • Some related entities are not retrieved (see related query parameter).
  • Some related entities are retrieved as objects and are not strongly typed.
  • Some related entities that are strongly typed do not have any properties.

.net-sdk's People

Contributors

makosovic avatar pinebit avatar

Stargazers

 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

.net-sdk's Issues

generic foreign key

Is there a way to create classes that implement the generic foreign key pattern? using inheritance or the table builder. this is a example of what I want to do

Table task have a field name owner of type person , Internal employee and outsource employee inherits from the type person, so the table task can hold a person, a internal employee or an outsource employee in his owner field

query a view

Hi, is there a way to query a mysql view with the dream factory sdk?

catch error from database

what would happened if an operation in the database breaks a rule (such as field unique or field required) what kind of exception will I get? I'm asking because I don't know where should I place the validations for the records on the U.I or the database level. I guess it will be better to use the database level and just handle the exception ? please advise

Support latest DF version - Update SDK

I'm developing Xamarin app with latest dreamfactory version that has support for username based authentication. Any plans to update this .net sdk to support and upgrade to new features of dreamfactory? It seems this sdk is not in active development

implement transactions

Hi i think the sdk will be more useful if you implement transactions for the db api, right now the only way to have a transaction behavior is a stored procedure

Add validation to an existing schema

Hi I have a desktop app for which I need to create a mobile client, the desktop app have all its validation rules on the UI and non in the database. so I wonder what would happened to the schema if I add validations using dream factory? will it alter the database to add the rules I create using the SDK?

Error when query related data

Hi Marko, I try to query the related data but I got an error in the following scenarios

-.net code
SqlQuery tquery = new SqlQuery { Filter = "GCRecord is null", Order = "Oid", Fields = "*",Related= "imagedetail_by_PostBase", IncludeCount = true };
DatabaseResourceWrapper TResult = await databaseApi.GetRecordsAsync("postbase", tquery);

-error on .net
400 - Invalid relationship 'imagedetail_by_postbase' requested

if I try to get the related data of a many to many I got the following error

-.net code
SqlQuery tquery = new SqlQuery { Filter = "GCRecord is null", Order = "Oid", Fields = "*",Related= "tag_by_tagtags_postbasepostbases", IncludeCount = true };
DatabaseResourceWrapper TResult = await databaseApi.GetRecordsAsync("postbase", tquery);

-error on .net
500 - The Response content must be a string or object implementing __toString(), "boolean" given.

if i try to do the same on dream factory side I get this (this is the request http://localhost:80/api/v2/LaGuiaApi/_table/postbase?related=imagedetail_by_PostBase)

The Response content must be a string or object implementing __toString(), "boolean" given.",

here I include the schema of the table postbase
PostBase.pdf

mongodb example

Hi can you please include a mongodb example ? I would like to know how to do the CRUD operations and queries using the .net sdk

Error uploading a picture from xamarin forms (files API)

Hi I'm trying to upload a picture using files api but everytime it start uploading i get the following error

Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection.

i guess the problem is the size of the files since i don't get the problem with text files

Exception thrown when querying SP with multiple record sets

We are receiving the following exception when I execute an MS Sql (2012) SP that returns multiple result sets. I modified the DatabaseDemo.cs for testing purposed to call this SP.

here is the relevant code with exception.

StoredProcParam[] parameters = new[]
{
new StoredProcParam
{
Name = "pBeginDT",
ParamType = "IN",
Length = 8,
Value = "20161001",
Type = "datetime"
},
new StoredProcParam
{
Name = "pEndDT",
ParamType = "IN",
Length = 8,
Value = "20161019",
Type = "datetime"
}

            };

        var result = await databaseApi.CallStoredProcAsync<ExpandoObject>("GetDailyEnrollmentStats", parameters)

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.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
at System.Threading.Tasks.Task.Wait()
at DreamFactory.Demo.Program.<>c__DisplayClass5_0.

b__0(IRunnable test) in C:\code\evital.net-sdk\DreamFactory.Demo\Program.cs:line 53
at System.Array.ForEach[T](T[] array, Action1 action) at DreamFactory.Demo.Program.Main() in C:\code\evital.net-sdk\DreamFactory.Demo\Program.cs:line 49 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: HResult=-2147467262 Message=Unable to cast object of type 'System.Collections.Generic.List1[System.Object]' to type 'System.Dynamic.ExpandoObject'.
Source=Newtonsoft.Json
StackTrace:
at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)
at DreamFactory.Serialization.JsonContentSerializer.Deserialize[TObject](String content) in C:\code\evital.net-sdk\DreamFactory\Serialization\JsonContentSerializer.cs:line 49
at DreamFactory.Api.Implementation.DatabaseApi.d__221.MoveNext() in C:\code\evital.net-sdk\DreamFactory\Api\Implementation\DatabaseApi.Stored.cs:line 143 --- 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 DreamFactory.Demo.Demo.DatabaseDemo.d__2.MoveNext() in C:\code\evital.net-sdk\DreamFactory.Demo\Demo\DatabaseDemo.cs:line 102
InnerException:

Address book example

Hi can you please provide more information about the development method you used to create the address book example it looks like a mix of MVVM and asp.net MVC.

I want to migrate a system that I already have running using DevExpress xaf to dream factory and asp.net I just trying to figure out the a good pattern to use in the migration

errors when using the dbapi and a mongo db database service

Hi Marko
in the .net sdk example I change the database demo to use mongodb service instead of db, the example run almost perfect but the delete and update operations are not working, I guess is more a problem of the rest api ,than the sdk. I will post this on the community as well, let me know if there is a way around this 2 problems in the .net sdk

error when deleting an object
500 - Failed to delete records from 'staff'.
Array to string conversion

error when updating an object

400 - Required id field(s) not found in record 0: Array
(
[Uid] => 0
[FirstName] => Andrei 2
[LastName] => Smirnov
[Age] => 35
[Active] => 1
)

Database Api Transaction

Hi, I have a master detail scenario where I would like to save all master and detail records on a single transaction , does the sdk provide this functionality?

Currently I'm using POCO objects and they are not related to each other

If there is not possible to use transactions, I think use a store procedure to do the CRUD on a master detail object would be ok. is there a sample to call store procedures with parameters?

NoSQL example

Hi would you be so kind to include a no example may be couch or mongo, we are trying to figure out if we will use relation database or nosql database in our next project and a sample from you would really help us to decide

Error while tring to install nuget package on xamarin forms

Hi I'm no able to install the neuget package on xamarin forms android or iOS project, I'm currently using a shared project and xamarin forms 1.4

Attempting to resolve dependency 'Unirest-API (≥ 1.0.6.8)'.
Attempting to resolve dependency 'Microsoft.Bcl (≥ 1.1.9)'.
Attempting to resolve dependency 'Microsoft.Bcl.Build (≥ 1.0.14)'.
Attempting to resolve dependency 'Microsoft.Net.Http (≥ 2.2.28)'.
Attempting to resolve dependency 'Newtonsoft.Json (≥ 6.0.8)'.
Installing 'Microsoft.Net.Http 2.2.28'.
Successfully installed 'Microsoft.Net.Http 2.2.28'.
Installing 'Newtonsoft.Json 6.0.8'.
Successfully installed 'Newtonsoft.Json 6.0.8'.
'Unirest-API 1.0.6.8' already installed.
'DreamFactoryNet 1.0.2' already installed.
Adding 'Microsoft.Net.Http 2.2.28' to Tinker.PanteraFramework.Forms.Droid.
Successfully added 'Microsoft.Net.Http 2.2.28' to Tinker.PanteraFramework.Forms.Droid.
Adding 'Newtonsoft.Json 6.0.8' to Tinker.PanteraFramework.Forms.Droid.
Successfully added 'Newtonsoft.Json 6.0.8' to Tinker.PanteraFramework.Forms.Droid.
Executing script file 'C:\Users\Joche\documents\visual studio 2013\Projects\Tinker.PanteraFramework\packages\Newtonsoft.Json.6.0.8\tools\install.ps1'.
Adding 'Unirest-API 1.0.6.8' to Tinker.PanteraFramework.Forms.Droid.
Successfully added 'Unirest-API 1.0.6.8' to Tinker.PanteraFramework.Forms.Droid.
Adding 'DreamFactoryNet 1.0.2' to Tinker.PanteraFramework.Forms.Droid.
Uninstalling 'Newtonsoft.Json 6.0.8'.
Successfully uninstalled 'Newtonsoft.Json 6.0.8'.
Uninstalling 'Microsoft.Net.Http 2.2.28'.
Successfully uninstalled 'Microsoft.Net.Http 2.2.28'.
Install failed. Rolling back...
Could not install package 'DreamFactoryNet 1.0.2'. You are trying to install this package into a project that targets 'MonoAndroid,Version=v5.0', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.

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.