diff --git a/.gitignore b/.gitignore
index 839b78456..d31be9e13 100644
--- a/.gitignore
+++ b/.gitignore
@@ -189,4 +189,6 @@ FakesAssemblies/
# Ignore config because api keys are stored here (copy example configs to these files)
web.config
app.config
+settings.json
Nexmo.Api.Test.Unit/private.key
+project.lock.json
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5ee11aa0e..b51a40e18 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,27 @@
-
+# 2.0.0 (2016-10-24)
+
+* Dependency marking for netstandard1.6
+
+# 2.0.0-rc2 (2016-10-22)
+
+* Fix JWT generation (key import fail) on OSX/Linux
+
+# 2.0.0-rc1 (2016-10-16)
+
+* NumberInsight basic + standard support
+* NumberVerify control call
+* JWT token generation
+* Application API support
+* Application-based call API support
+* .NET Standard 1.6 support
+* __[BREAKING]__ Moved configuration from app.config to settings.json
+* __[BREAKING]__ Nexmo.Api.Voice static class has been deprecated - you must move to the new Voice calls inside the new Nexmo.Api.Voice namespace. See [the Nexmo docs](https://docs.nexmo.com/voice/voice-api) for details.
+
+JWT notes:
+
+* When registering a new application, make sure you save the private key. This library does not (currently) take care of this for you.
+* Make sure your saved private key is ASCII (not UTF-8, no BOM) - http://stackoverflow.com/questions/1068650/using-awk-to-remove-the-byte-order-mark
+
# 1.0.0 (2016-03-19)
* Initial release with nuget package
\ No newline at end of file
diff --git a/NetFrameworkSamples.sln b/NetFrameworkSamples.sln
new file mode 100644
index 000000000..345ad08ff
--- /dev/null
+++ b/NetFrameworkSamples.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 14
+VisualStudioVersion = 14.0.25420.1
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nexmo.Web.Sample", "Nexmo.Web.Sample\Nexmo.Web.Sample.csproj", "{3B32C093-EBED-4D60-B2FC-046F8FCE11D9}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ Release452|Any CPU = Release452|Any CPU
+ Release46|Any CPU = Release46|Any CPU
+ Release461|Any CPU = Release461|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {3B32C093-EBED-4D60-B2FC-046F8FCE11D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3B32C093-EBED-4D60-B2FC-046F8FCE11D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3B32C093-EBED-4D60-B2FC-046F8FCE11D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3B32C093-EBED-4D60-B2FC-046F8FCE11D9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3B32C093-EBED-4D60-B2FC-046F8FCE11D9}.Release452|Any CPU.ActiveCfg = Release452|Any CPU
+ {3B32C093-EBED-4D60-B2FC-046F8FCE11D9}.Release452|Any CPU.Build.0 = Release452|Any CPU
+ {3B32C093-EBED-4D60-B2FC-046F8FCE11D9}.Release46|Any CPU.ActiveCfg = Release46|Any CPU
+ {3B32C093-EBED-4D60-B2FC-046F8FCE11D9}.Release46|Any CPU.Build.0 = Release46|Any CPU
+ {3B32C093-EBED-4D60-B2FC-046F8FCE11D9}.Release461|Any CPU.ActiveCfg = Release461|Any CPU
+ {3B32C093-EBED-4D60-B2FC-046F8FCE11D9}.Release461|Any CPU.Build.0 = Release461|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/Nexmo.Api.Test.Integration/AccountTest.cs b/Nexmo.Api.Test.Integration/AccountTest.cs
index 726dec1b5..d20a58f14 100644
--- a/Nexmo.Api.Test.Integration/AccountTest.cs
+++ b/Nexmo.Api.Test.Integration/AccountTest.cs
@@ -1,5 +1,4 @@
-using System.Configuration;
-using System.Linq;
+using System.Linq;
using NUnit.Framework;
namespace Nexmo.Api.Test.Integration
@@ -44,7 +43,7 @@ public void should_get_numbers()
{
var response = Account.GetNumbers();
Assert.AreEqual(1, response.count);
- Assert.AreEqual(ConfigurationManager.AppSettings["nexmo_number"], response.numbers[0].msisdn);
+ Assert.AreEqual(Configuration.Instance.Settings["nexmo_number"], response.numbers[0].msisdn);
}
}
}
\ No newline at end of file
diff --git a/Nexmo.Api.Test.Integration/CallTest.cs b/Nexmo.Api.Test.Integration/CallTest.cs
index c75b1d237..2a3018ec3 100644
--- a/Nexmo.Api.Test.Integration/CallTest.cs
+++ b/Nexmo.Api.Test.Integration/CallTest.cs
@@ -1,5 +1,4 @@
-using System.Configuration;
-using Nexmo.Api.Voice;
+using Nexmo.Api.Voice;
using NUnit.Framework;
namespace Nexmo.Api.Test.Integration
@@ -17,13 +16,13 @@ public void should_call()
new Call.Endpoint
{
type = "phone",
- number = ConfigurationManager.AppSettings["test_number"]
+ number = Configuration.Instance.Settings["test_number"]
}
},
from = new Call.Endpoint
{
type = "phone",
- number = ConfigurationManager.AppSettings["nexmo_number"]
+ number = Configuration.Instance.Settings["nexmo_number"]
},
answer_url = new[]
{
@@ -69,13 +68,13 @@ public void should_call_then_stream_then_end_stream()
new Call.Endpoint
{
type = "phone",
- number = ConfigurationManager.AppSettings["test_number"]
+ number = Configuration.Instance.Settings["test_number"]
}
},
from = new Call.Endpoint
{
type = "phone",
- number = ConfigurationManager.AppSettings["nexmo_number"]
+ number = Configuration.Instance.Settings["nexmo_number"]
},
answer_url = new[]
{
diff --git a/Nexmo.Api.Test.Integration/Nexmo.Api.Test.Integration.csproj b/Nexmo.Api.Test.Integration/Nexmo.Api.Test.Integration.csproj
index 8eff2426e..deab146c7 100644
--- a/Nexmo.Api.Test.Integration/Nexmo.Api.Test.Integration.csproj
+++ b/Nexmo.Api.Test.Integration/Nexmo.Api.Test.Integration.csproj
@@ -51,13 +51,59 @@
MinimumRecommendedRules.ruleset
+
+ ..\packages\jose-jwt.2.0.1\lib\net40\jose-jwt.dll
+ True
+
+
+ ..\packages\Microsoft.Extensions.Configuration.1.0.0\lib\netstandard1.1\Microsoft.Extensions.Configuration.dll
+ True
+
+
+ ..\packages\Microsoft.Extensions.Configuration.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.Extensions.Configuration.Abstractions.dll
+ True
+
+
+ ..\packages\Microsoft.Extensions.Configuration.FileExtensions.1.0.0\lib\net451\Microsoft.Extensions.Configuration.FileExtensions.dll
+ True
+
+
+ ..\packages\Microsoft.Extensions.Configuration.Json.1.0.0\lib\net451\Microsoft.Extensions.Configuration.Json.dll
+ True
+
+
+ ..\packages\Microsoft.Extensions.FileProviders.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.Extensions.FileProviders.Abstractions.dll
+ True
+
+
+ ..\packages\Microsoft.Extensions.FileProviders.Physical.1.0.0\lib\net451\Microsoft.Extensions.FileProviders.Physical.dll
+ True
+
+
+ ..\packages\Microsoft.Extensions.FileSystemGlobbing.1.0.0\lib\net451\Microsoft.Extensions.FileSystemGlobbing.dll
+ True
+
+
+ ..\packages\Microsoft.Extensions.Primitives.1.0.0\lib\netstandard1.0\Microsoft.Extensions.Primitives.dll
+ True
+
+
+ ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll
+ True
+
+
+ ..\packages\Nexmo.Csharp.Client.2.0.0\lib\net452\Nexmo.Api.dll
+ True
+
..\packages\NUnit.3.2.0\lib\net45\nunit.framework.dll
True
-
+
+
+
@@ -77,17 +123,14 @@
-
- App.config
+
+ settings.json
+
+
+ settings.json.example
-
-
- {EE7DA727-2AE3-4C76-809A-56B7433004FE}
- Nexmo.Api
-
-
-
\ No newline at end of file
diff --git a/Nexmo.Api/Nexmo.Api.nuspec b/Nexmo.Api/Nexmo.Api.nuspec
index c89b4cca8..40740482c 100644
--- a/Nexmo.Api/Nexmo.Api.nuspec
+++ b/Nexmo.Api/Nexmo.Api.nuspec
@@ -2,27 +2,54 @@
Nexmo.Csharp.Client
- 1.0.0
+ 2.0.0
Nexmo API Client
Nexmo
Nexmo
- https://github.com/Nexmo/csharp-client/blob/master/LICENSE.md
- https://github.com/Nexmo/csharp-client
+ https://github.com/Nexmo/nexmo-dotnet/blob/master/LICENSE.md
+ https://github.com/Nexmo/nexmo-dotnet
https://dashboard.nexmo.com/apple-touch-icon.png
false
- Official C#/.NET wrapper for the nexmo API
- Initial release.
+ Official C#/.NET wrapper for the Nexmo API
+
+ 2.0.0:
+ * Dependency marking for netstandard1.6
+ RC2:
+ * Fix JWT generation (key import fail) on OSX/Linux
+ RC1:
+ * NumberInsight basic + standard support
+ * NumberVerify control call
+ * JWT token generation
+ * Application API support
+ * Application-based call API support
+ * .NET Standard 1.6 support
+ * [BREAKING] Moved configuration from app.config to settings.json
+ * [BREAKING] Nexmo.Api.Voice static class has been deprecated - you must move to the new Voice calls inside the new Nexmo.Api.Voice namespace. See [the Nexmo docs](https://docs.nexmo.com/voice/voice-api) for details.
+
© Nexmo 2016
SMS voice telephony phone nexmo
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
\ No newline at end of file
diff --git a/Nexmo.Api/Nexmo.Api.xproj b/Nexmo.Api/Nexmo.Api.xproj
new file mode 100644
index 000000000..a86db5f5c
--- /dev/null
+++ b/Nexmo.Api/Nexmo.Api.xproj
@@ -0,0 +1,22 @@
+
+
+
+ 14.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+ 41ef17c9-8d2e-4c7b-b2ee-3bd1a4cc1a1b
+ Nexmo.Api
+ .\obj
+ .\bin\
+
+
+ 2.0
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Nexmo.Api/PemParse.cs b/Nexmo.Api/PemParse.cs
index 45e5ffaa0..5995dde7d 100644
--- a/Nexmo.Api/PemParse.cs
+++ b/Nexmo.Api/PemParse.cs
@@ -51,6 +51,7 @@ THE SOFTWARE.
using System;
using System.IO;
+using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Text;
@@ -61,7 +62,7 @@ public class PemParse
private const string pemprivheader = "-----BEGIN RSA PRIVATE KEY-----";
private const string pemprivfooter = "-----END RSA PRIVATE KEY-----";
- public static RSACryptoServiceProvider DecodePEMKey(string pemstr)
+ public static RSA DecodePEMKey(string pemstr)
{
if (!pemstr.StartsWith(pemprivheader) || !pemstr.EndsWith(pemprivfooter)) return null;
var pemprivatekey = DecodeOpenSSLPrivateKey(pemstr);
@@ -145,93 +146,120 @@ private static byte[] DecodeOpenSSLPrivateKey(string instr)
//////////}
}
- public static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey)
+ public static RSA DecodeRSAPrivateKey(byte[] privkey)
{
byte[] MODULUS, E, D, P, Q, DP, DQ, IQ;
// --------- Set up stream to decode the asn.1 encoded RSA private key ------
- var mem = new MemoryStream(privkey);
- var binr = new BinaryReader(mem); //wrap Memory Stream with BinaryReader for easy reading
- byte bt = 0;
- ushort twobytes = 0;
- var elems = 0;
- try
+ using (var mem = new MemoryStream(privkey))
+ using (var binr = new BinaryReader(mem)) //wrap Memory Stream with BinaryReader for easy reading
{
- twobytes = binr.ReadUInt16();
- if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
- binr.ReadByte(); //advance 1 byte
- else if (twobytes == 0x8230)
- binr.ReadInt16(); //advance 2 bytes
- else
- return null;
-
- twobytes = binr.ReadUInt16();
- if (twobytes != 0x0102) //version number
- return null;
- bt = binr.ReadByte();
- if (bt != 0x00)
+ byte bt = 0;
+ ushort twobytes = 0;
+ var elems = 0;
+ try
+ {
+ twobytes = binr.ReadUInt16();
+ if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
+ binr.ReadByte(); //advance 1 byte
+ else if (twobytes == 0x8230)
+ binr.ReadInt16(); //advance 2 bytes
+ else
+ return null;
+
+ twobytes = binr.ReadUInt16();
+ if (twobytes != 0x0102) //version number
+ return null;
+ bt = binr.ReadByte();
+ if (bt != 0x00)
+ return null;
+
+
+ //------ all private key components are Integer sequences ----
+ elems = GetIntegerSize(binr);
+ MODULUS = binr.ReadBytes(elems);
+
+ elems = GetIntegerSize(binr);
+ E = binr.ReadBytes(elems);
+
+ elems = GetIntegerSize(binr);
+ D = binr.ReadBytes(elems);
+
+ elems = GetIntegerSize(binr);
+ P = binr.ReadBytes(elems);
+
+ elems = GetIntegerSize(binr);
+ Q = binr.ReadBytes(elems);
+
+ elems = GetIntegerSize(binr);
+ DP = binr.ReadBytes(elems);
+
+ elems = GetIntegerSize(binr);
+ DQ = binr.ReadBytes(elems);
+
+ elems = GetIntegerSize(binr);
+ IQ = binr.ReadBytes(elems);
+
+ //Console.WriteLine("showing components ..");
+ //if (verbose)
+ //{
+ // showBytes("\nModulus", MODULUS);
+ // showBytes("\nExponent", E);
+ // showBytes("\nD", D);
+ // showBytes("\nP", P);
+ // showBytes("\nQ", Q);
+ // showBytes("\nDP", DP);
+ // showBytes("\nDQ", DQ);
+ // showBytes("\nIQ", IQ);
+ //}
+
+ // ------- create RSACryptoServiceProvider instance and initialize with public key -----
+#if NETSTANDARD1_6
+ RSA RSA;
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) ||
+ RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+ {
+ RSA = new RSAOpenSsl();
+ }
+ else
+ {
+ RSA = new RSACng();
+ }
+ var RSAparams = new RSAParameters
+ {
+ Modulus = MODULUS,
+ Exponent = E,
+ D = D,
+ P = P,
+ Q = Q,
+ DP = DP,
+ DQ = DQ,
+ InverseQ = IQ
+ };
+ RSA.ImportParameters(RSAparams);
+ return RSA;
+#else
+ var RSA = new RSACryptoServiceProvider();
+ var RSAparams = new RSAParameters
+ {
+ Modulus = MODULUS,
+ Exponent = E,
+ D = D,
+ P = P,
+ Q = Q,
+ DP = DP,
+ DQ = DQ,
+ InverseQ = IQ
+ };
+ RSA.ImportParameters(RSAparams);
+ return RSA;
+#endif
+ }
+ catch (Exception)
+ {
+ // TODO: log this!
return null;
-
-
- //------ all private key components are Integer sequences ----
- elems = GetIntegerSize(binr);
- MODULUS = binr.ReadBytes(elems);
-
- elems = GetIntegerSize(binr);
- E = binr.ReadBytes(elems);
-
- elems = GetIntegerSize(binr);
- D = binr.ReadBytes(elems);
-
- elems = GetIntegerSize(binr);
- P = binr.ReadBytes(elems);
-
- elems = GetIntegerSize(binr);
- Q = binr.ReadBytes(elems);
-
- elems = GetIntegerSize(binr);
- DP = binr.ReadBytes(elems);
-
- elems = GetIntegerSize(binr);
- DQ = binr.ReadBytes(elems);
-
- elems = GetIntegerSize(binr);
- IQ = binr.ReadBytes(elems);
-
- //Console.WriteLine("showing components ..");
- //if (verbose)
- //{
- // showBytes("\nModulus", MODULUS);
- // showBytes("\nExponent", E);
- // showBytes("\nD", D);
- // showBytes("\nP", P);
- // showBytes("\nQ", Q);
- // showBytes("\nDP", DP);
- // showBytes("\nDQ", DQ);
- // showBytes("\nIQ", IQ);
- //}
-
- // ------- create RSACryptoServiceProvider instance and initialize with public key -----
- var RSA = new RSACryptoServiceProvider();
- var RSAparams = new RSAParameters();
- RSAparams.Modulus = MODULUS;
- RSAparams.Exponent = E;
- RSAparams.D = D;
- RSAparams.P = P;
- RSAparams.Q = Q;
- RSAparams.DP = DP;
- RSAparams.DQ = DQ;
- RSAparams.InverseQ = IQ;
- RSA.ImportParameters(RSAparams);
- return RSA;
- }
- catch (Exception)
- {
- return null;
- }
- finally
- {
- binr.Close();
+ }
}
}
diff --git a/Nexmo.Api/Properties/AssemblyInfo.cs b/Nexmo.Api/Properties/AssemblyInfo.cs
index 41fd72c6e..4d9b61b32 100644
--- a/Nexmo.Api/Properties/AssemblyInfo.cs
+++ b/Nexmo.Api/Properties/AssemblyInfo.cs
@@ -34,5 +34,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyVersion("2.0.0.0")]
+[assembly: AssemblyFileVersion("2.0.0.0")]
diff --git a/Nexmo.Api/Request/ApiRequest.cs b/Nexmo.Api/Request/ApiRequest.cs
index a75645f02..dc2d48193 100644
--- a/Nexmo.Api/Request/ApiRequest.cs
+++ b/Nexmo.Api/Request/ApiRequest.cs
@@ -1,44 +1,36 @@
using System;
using System.Collections.Generic;
-using System.Configuration;
using System.IO;
+using System.Linq;
using System.Net;
+using System.Reflection;
using System.Text;
-using System.Web;
using Newtonsoft.Json;
+using System.Net.Http;
namespace Nexmo.Api.Request
{
internal static class ApiRequest
- {
- private static IHttpWebRequestFactory _webRequestFactory = new NetWebRequestFactory();
- public static IHttpWebRequestFactory WebRequestFactory
- {
- get
- {
- return _webRequestFactory;
- }
- set { _webRequestFactory = value; }
- }
-
+ {
internal static Dictionary GetParameters(object parameters)
{
+ var paramType = parameters.GetType().GetTypeInfo();
var apiParams = new Dictionary();
- foreach (var property in parameters.GetType().GetProperties())
+ foreach (var property in paramType.GetProperties())
{
string jsonPropertyName = null;
- if (property.GetCustomAttributes(typeof(JsonPropertyAttribute), false).Length > 0)
+ if (property.GetCustomAttributes(typeof(JsonPropertyAttribute), false).Any())
{
jsonPropertyName =
- ((JsonPropertyAttribute)property.GetCustomAttributes(typeof(JsonPropertyAttribute), false)[0])
+ ((JsonPropertyAttribute)property.GetCustomAttributes(typeof(JsonPropertyAttribute), false).First())
.PropertyName;
}
- if (null == parameters.GetType().GetProperty(property.Name).GetValue(parameters, null)) continue;
+ if (null == paramType.GetProperty(property.Name).GetValue(parameters, null)) continue;
apiParams.Add(string.IsNullOrEmpty(jsonPropertyName) ? property.Name : jsonPropertyName,
- parameters.GetType().GetProperty(property.Name).GetValue(parameters, null).ToString());
+ paramType.GetProperty(property.Name).GetValue(parameters, null).ToString());
}
return apiParams;
}
@@ -50,11 +42,11 @@ public static Uri GetBaseUriFor(Type component, string url = null)
|| typeof(Application) == component
|| typeof(Voice.Call) == component)
{
- baseUri = new Uri(ConfigurationManager.AppSettings["Nexmo.Url.Api"]);
+ baseUri = new Uri(Configuration.Instance.Settings["Nexmo.Url.Api"]);
}
else
{
- baseUri = new Uri(ConfigurationManager.AppSettings["Nexmo.Url.Rest"]);
+ baseUri = new Uri(Configuration.Instance.Settings["Nexmo.Url.Rest"]);
}
return string.IsNullOrEmpty(url) ? baseUri : new Uri(baseUri, url);
}
@@ -62,11 +54,11 @@ public static Uri GetBaseUriFor(Type component, string url = null)
public static string DoRequest(Uri uri, Dictionary parameters)
{
var sb = new StringBuilder();
- parameters.Add("api_key", ConfigurationManager.AppSettings["Nexmo.api_key"]);
- parameters.Add("api_secret", ConfigurationManager.AppSettings["Nexmo.api_secret"]);
+ parameters.Add("api_key", Configuration.Instance.Settings["Nexmo.api_key"]);
+ parameters.Add("api_secret", Configuration.Instance.Settings["Nexmo.api_secret"]);
foreach (var key in parameters.Keys)
{
- sb.AppendFormat("{0}={1}&", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(parameters[key]));
+ sb.AppendFormat("{0}={1}&", WebUtility.UrlEncode(key), WebUtility.UrlEncode(parameters[key]));
}
return DoRequest(new Uri(uri, "?" + sb));
@@ -76,12 +68,12 @@ public static StringBuilder GetQueryStringBuilderFor(object parameters)
{
var apiParams = GetParameters(parameters);
- apiParams.Add("api_key", ConfigurationManager.AppSettings["Nexmo.api_key"]);
- apiParams.Add("api_secret", ConfigurationManager.AppSettings["Nexmo.api_secret"]);
+ apiParams.Add("api_key", Configuration.Instance.Settings["Nexmo.api_key"]);
+ apiParams.Add("api_secret", Configuration.Instance.Settings["Nexmo.api_secret"]);
var sb = new StringBuilder();
foreach (var key in apiParams.Keys)
{
- sb.AppendFormat("{0}={1}&", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(apiParams[key]));
+ sb.AppendFormat("{0}={1}&", WebUtility.UrlEncode(key), WebUtility.UrlEncode(apiParams[key]));
}
return sb;
}
@@ -95,62 +87,71 @@ public static string DoRequest(Uri uri, object parameters)
public static string DoRequest(Uri uri)
{
- var req = _webRequestFactory.CreateHttp(uri);
- var resp = req.GetResponse();
- string json;
- using (var sr = new StreamReader(resp.GetResponseStream()))
- {
- json = sr.ReadToEnd();
- }
+ var req = new HttpRequestMessage
+ {
+ RequestUri = uri,
+ Method = HttpMethod.Get,
+ };
+
+ var sendTask = Configuration.Instance.Client.SendAsync(req);
+ sendTask.Wait();
+ var readTask = sendTask.Result.Content.ReadAsStreamAsync();
+ readTask.Wait();
+ string json;
+ using (var sr = new StreamReader(readTask.Result))
+ {
+ json = sr.ReadToEnd();
+ }
return json;
}
- public static NexmoResponse DoRequest(string method, Uri uri, Dictionary parameters)
+ private static NexmoResponse DoRequest(string method, Uri uri, Dictionary parameters)
{
var sb = new StringBuilder();
// if parameters is null, assume that key and secret have been taken care of
if (null != parameters)
{
- parameters.Add("api_key", ConfigurationManager.AppSettings["Nexmo.api_key"]);
- parameters.Add("api_secret", ConfigurationManager.AppSettings["Nexmo.api_secret"]);
+ parameters.Add("api_key", Configuration.Instance.Settings["Nexmo.api_key"]);
+ parameters.Add("api_secret", Configuration.Instance.Settings["Nexmo.api_secret"]);
foreach (var key in parameters.Keys)
{
- sb.AppendFormat("{0}={1}&", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(parameters[key]));
+ sb.AppendFormat("{0}={1}&", WebUtility.UrlEncode(key), WebUtility.UrlEncode(parameters[key]));
}
}
- var req = _webRequestFactory.CreateHttp(uri);
-
- req.Method = method;
- var data = Encoding.ASCII.GetBytes(sb.ToString());
+ var req = new HttpRequestMessage
+ {
+ RequestUri = uri,
+ Method = new HttpMethod(method),
+ };
- req.ContentType = "application/x-www-form-urlencoded";
- req.ContentLength = data.Length;
- var requestStream = req.GetRequestStream();
- requestStream.Write(data, 0, data.Length);
- requestStream.Close();
+ var data = Encoding.ASCII.GetBytes(sb.ToString());
+ req.Content = new ByteArrayContent(data);
+ req.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/x-www-form-urlencoded");
- try
- {
- var resp = req.GetResponse();
- string json;
- using (var sr = new StreamReader(resp.GetResponseStream()))
- {
- json = sr.ReadToEnd();
- }
+ var sendTask = Configuration.Instance.Client.SendAsync(req);
+ sendTask.Wait();
+
+ if (!sendTask.Result.IsSuccessStatusCode)
+ {
return new NexmoResponse
{
- Status = resp.GetResponseStatusCode(),
- JsonResponse = json
- };
- }
- catch (WebException ex)
- {
- return new NexmoResponse
- {
- Status = ((HttpWebResponse)ex.Response).StatusCode
- };
- }
+ Status = sendTask.Result.StatusCode
+ };
+ }
+
+ string json;
+ var readTask = sendTask.Result.Content.ReadAsStreamAsync();
+ readTask.Wait();
+ using (var sr = new StreamReader(readTask.Result))
+ {
+ json = sr.ReadToEnd();
+ }
+ return new NexmoResponse
+ {
+ Status = sendTask.Result.StatusCode,
+ JsonResponse = json
+ };
}
public static NexmoResponse DoPostRequest(Uri uri, object parameters)
@@ -158,16 +159,6 @@ public static NexmoResponse DoPostRequest(Uri uri, object parameters)
var apiParams = GetParameters(parameters);
return DoPostRequest(uri, apiParams);
}
- public static NexmoResponse DoPutRequest(Uri uri, object parameters)
- {
- var apiParams = GetParameters(parameters);
- return DoPutRequest(uri, apiParams);
- }
- public static NexmoResponse DoDeleteRequest(Uri uri, object parameters)
- {
- var apiParams = GetParameters(parameters);
- return DoDeleteRequest(uri, apiParams);
- }
public static NexmoResponse DoPostRequest(Uri uri, Dictionary parameters) => DoRequest("POST", uri, parameters);
public static NexmoResponse DoPutRequest(Uri uri, Dictionary parameters) => DoRequest("PUT", uri, parameters);
diff --git a/Nexmo.Api/Request/IHttpWebRequest.cs b/Nexmo.Api/Request/IHttpWebRequest.cs
deleted file mode 100644
index cfdc57d30..000000000
--- a/Nexmo.Api/Request/IHttpWebRequest.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System.IO;
-
-namespace Nexmo.Api.Request
-{
- public interface IHttpWebRequest
- {
- string Method { get; set; }
- string ContentType { get; set; }
- long ContentLength { get; set; }
- IWebResponse GetResponse();
- Stream GetRequestStream();
- void SetBearerToken(string token);
- }
-}
\ No newline at end of file
diff --git a/Nexmo.Api/Request/IHttpWebRequestFactory.cs b/Nexmo.Api/Request/IHttpWebRequestFactory.cs
deleted file mode 100644
index 9e260abe1..000000000
--- a/Nexmo.Api/Request/IHttpWebRequestFactory.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System;
-
-namespace Nexmo.Api.Request
-{
- public interface IHttpWebRequestFactory
- {
- IHttpWebRequest CreateHttp(Uri uri);
- }
-}
diff --git a/Nexmo.Api/Request/IWebResponse.cs b/Nexmo.Api/Request/IWebResponse.cs
deleted file mode 100644
index 69ba54aba..000000000
--- a/Nexmo.Api/Request/IWebResponse.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using System.IO;
-using System.Net;
-
-namespace Nexmo.Api.Request
-{
- public interface IWebResponse
- {
- Stream GetResponseStream();
- HttpStatusCode GetResponseStatusCode();
- }
-}
\ No newline at end of file
diff --git a/Nexmo.Api/Request/NetWebRequestFactory.cs b/Nexmo.Api/Request/NetWebRequestFactory.cs
deleted file mode 100644
index 520beacb9..000000000
--- a/Nexmo.Api/Request/NetWebRequestFactory.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System;
-using System.Net;
-
-namespace Nexmo.Api.Request
-{
- public class NetWebRequestFactory : IHttpWebRequestFactory
- {
- public IHttpWebRequest CreateHttp(Uri uri)
- {
- return new WebRequestAdapter((HttpWebRequest) WebRequest.Create(uri));
- }
- }
-}
\ No newline at end of file
diff --git a/Nexmo.Api/Request/VersionedApiRequest.cs b/Nexmo.Api/Request/VersionedApiRequest.cs
index 14def087d..68dbeb639 100644
--- a/Nexmo.Api/Request/VersionedApiRequest.cs
+++ b/Nexmo.Api/Request/VersionedApiRequest.cs
@@ -1,25 +1,14 @@
using System;
-using System.Configuration;
using System.IO;
using System.Net;
using System.Text;
-using System.Web;
using Newtonsoft.Json;
+using System.Net.Http;
namespace Nexmo.Api.Request
{
internal static class VersionedApiRequest
{
- private static IHttpWebRequestFactory _webRequestFactory = new NetWebRequestFactory();
- public static IHttpWebRequestFactory WebRequestFactory
- {
- get
- {
- return _webRequestFactory;
- }
- set { _webRequestFactory = value; }
- }
-
private static StringBuilder GetQueryStringBuilderFor(object parameters)
{
var apiParams = ApiRequest.GetParameters(parameters);
@@ -27,20 +16,32 @@ private static StringBuilder GetQueryStringBuilderFor(object parameters)
var sb = new StringBuilder();
foreach (var key in apiParams.Keys)
{
- sb.AppendFormat("{0}={1}&", HttpUtility.UrlEncode(key), HttpUtility.UrlEncode(apiParams[key]));
+ sb.AppendFormat("{0}={1}&", WebUtility.UrlEncode(key), WebUtility.UrlEncode(apiParams[key]));
}
return sb;
}
private static string DoRequest(Uri uri)
{
- var req = _webRequestFactory.CreateHttp(uri);
+ var req = new HttpRequestMessage
+ {
+ RequestUri = uri,
+ Method = HttpMethod.Get,
+ };
// attempt bearer token auth
- req.SetBearerToken(Jwt.CreateToken(ConfigurationManager.AppSettings["Nexmo.Application.Id"], ConfigurationManager.AppSettings["Nexmo.Application.Key"]));
+ req.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer",
+ Jwt.CreateToken(Configuration.Instance.Settings["Nexmo.Application.Id"], Configuration.Instance.Settings["Nexmo.Application.Key"]));
+
+ var sendTask = Configuration.Instance.Client.SendAsync(req);
+ sendTask.Wait();
+
+ //if (!sendTask.Result.IsSuccessStatusCode)
+ // throw new Exception("Error while retrieving resource.");
- var resp = req.GetResponse();
string json;
- using (var sr = new StreamReader(resp.GetResponseStream()))
+ var readTask = sendTask.Result.Content.ReadAsStreamAsync();
+ readTask.Wait();
+ using (var sr = new StreamReader(readTask.Result))
{
json = sr.ReadToEnd();
}
@@ -49,39 +50,42 @@ private static string DoRequest(Uri uri)
public static NexmoResponse DoRequest(string method, Uri uri, object payload)
{
- var req = _webRequestFactory.CreateHttp(uri);
+ var req = new HttpRequestMessage
+ {
+ RequestUri = uri,
+ Method = new HttpMethod(method),
+ };
// attempt bearer token auth
- req.SetBearerToken(Jwt.CreateToken(ConfigurationManager.AppSettings["Nexmo.Application.Id"], ConfigurationManager.AppSettings["Nexmo.Application.Key"]));
+ req.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer",
+ Jwt.CreateToken(Configuration.Instance.Settings["Nexmo.Application.Id"], Configuration.Instance.Settings["Nexmo.Application.Key"]));
- req.Method = method;
- req.ContentType = "application/json";
var data = Encoding.ASCII.GetBytes(JsonConvert.SerializeObject(payload));
- req.ContentLength = data.Length;
- var requestStream = req.GetRequestStream();
- requestStream.Write(data, 0, data.Length);
- requestStream.Close();
+ req.Content = new ByteArrayContent(data);
+ req.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");
- try
+ var sendTask = Configuration.Instance.Client.SendAsync(req);
+ sendTask.Wait();
+
+ if (!sendTask.Result.IsSuccessStatusCode)
{
- var resp = req.GetResponse();
- string json;
- using (var sr = new StreamReader(resp.GetResponseStream()))
- {
- json = sr.ReadToEnd();
- }
return new NexmoResponse
{
- Status = resp.GetResponseStatusCode(),
- JsonResponse = json
+ Status = sendTask.Result.StatusCode
};
}
- catch (WebException ex)
+
+ string json;
+ var readTask = sendTask.Result.Content.ReadAsStreamAsync();
+ readTask.Wait();
+ using (var sr = new StreamReader(readTask.Result))
{
- return new NexmoResponse
- {
- Status = ((HttpWebResponse)ex.Response).StatusCode
- };
+ json = sr.ReadToEnd();
}
+ return new NexmoResponse
+ {
+ Status = sendTask.Result.StatusCode,
+ JsonResponse = json
+ };
}
public static string DoRequest(Uri uri, object parameters)
diff --git a/Nexmo.Api/Request/WebRequestAdapter.cs b/Nexmo.Api/Request/WebRequestAdapter.cs
deleted file mode 100644
index 49946031b..000000000
--- a/Nexmo.Api/Request/WebRequestAdapter.cs
+++ /dev/null
@@ -1,46 +0,0 @@
-using System.IO;
-using System.Net;
-
-namespace Nexmo.Api.Request
-{
- public class WebRequestAdapter : IHttpWebRequest
- {
- private readonly WebRequest _request;
-
- public WebRequestAdapter(WebRequest request)
- {
- _request = request;
- }
-
- public string Method
- {
- get { return _request.Method; }
- set { _request.Method = value; }
- }
- public string ContentType
- {
- get { return _request.ContentType; }
- set { _request.ContentType = value; }
- }
- public long ContentLength
- {
- get { return _request.ContentLength; }
- set { _request.ContentLength = value; }
- }
-
- public IWebResponse GetResponse()
- {
- return new WebResponseAdapter(_request.GetResponse());
- }
-
- public Stream GetRequestStream()
- {
- return _request.GetRequestStream();
- }
-
- public void SetBearerToken(string token)
- {
- _request.Headers.Add("Authorization", $"Bearer {token}");
- }
- }
-}
\ No newline at end of file
diff --git a/Nexmo.Api/Request/WebResponseAdapter.cs b/Nexmo.Api/Request/WebResponseAdapter.cs
deleted file mode 100644
index 31339231b..000000000
--- a/Nexmo.Api/Request/WebResponseAdapter.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-using System.IO;
-using System.Net;
-
-namespace Nexmo.Api.Request
-{
- public class WebResponseAdapter : IWebResponse
- {
- private readonly WebResponse _response;
-
- public WebResponseAdapter(WebResponse response)
- {
- _response = response;
- }
-
- public Stream GetResponseStream()
- {
- return _response.GetResponseStream();
- }
-
- public HttpStatusCode GetResponseStatusCode()
- {
- return ((HttpWebResponse) _response).StatusCode;
- }
- }
-}
\ No newline at end of file
diff --git a/Nexmo.Api/SMS.cs b/Nexmo.Api/SMS.cs
index c1121dbc6..30fe38fd8 100644
--- a/Nexmo.Api/SMS.cs
+++ b/Nexmo.Api/SMS.cs
@@ -190,7 +190,7 @@ public static SMSResponse Send(SMSRequest request)
{
if (string.IsNullOrEmpty(request.from))
{
- request.from = System.Configuration.ConfigurationManager.AppSettings["Nexmo.sender_id"];
+ request.from = Configuration.Instance.Settings["Nexmo.sender_id"];
}
var jsonstring = ApiRequest.DoRequest(ApiRequest.GetBaseUriFor(typeof(SMSResponse), "/sms/json"), request);
diff --git a/Nexmo.Api/ShortCode.cs b/Nexmo.Api/ShortCode.cs
index 76928c0f8..c291e7429 100644
--- a/Nexmo.Api/ShortCode.cs
+++ b/Nexmo.Api/ShortCode.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Web;
using Newtonsoft.Json;
using Nexmo.Api.Request;
@@ -43,7 +42,7 @@ public static SMS.SMSResponse RequestAlert(AlertRequest request, Dictionary
-
-
-
-
\ No newline at end of file
diff --git a/Nexmo.Api/project.json b/Nexmo.Api/project.json
new file mode 100644
index 000000000..e810b5bdf
--- /dev/null
+++ b/Nexmo.Api/project.json
@@ -0,0 +1,32 @@
+{
+ "version": "1.0.0-*",
+
+ "dependencies": {
+ "Microsoft.Extensions.Configuration": "1.0.*",
+ "Microsoft.Extensions.Configuration.Json": "1.0.*",
+ "System.Net.Http": "4.*",
+ "System.Runtime.Extensions": "4.*",
+
+ "Newtonsoft.Json": "9.0.*",
+ "jose-jwt": "2.0.*"
+ },
+
+ "frameworks": {
+ "net452": {
+ },
+ "net46": {
+ },
+ "net461": {
+ },
+ "net462": {
+ },
+ "netstandard1.6": {
+ "dependencies": {
+ "NETStandard.Library": "1.6.0",
+ "System.Security.Cryptography.Algorithms": "4.2.0",
+ "System.Security.Cryptography.OpenSsl": "4.0.0",
+ "System.Security.Cryptography.Cng": "4.2.0"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Nexmo.Samples.Coverage/Nexmo.Samples.Coverage.xproj b/Nexmo.Samples.Coverage/Nexmo.Samples.Coverage.xproj
new file mode 100644
index 000000000..11063449c
--- /dev/null
+++ b/Nexmo.Samples.Coverage/Nexmo.Samples.Coverage.xproj
@@ -0,0 +1,19 @@
+
+
+
+ 14.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+ 797bd6e3-6749-4b10-81bc-2587f635b94a
+ Nexmo.Samples.Coverage
+ .\obj
+ .\bin\
+ v4.5.2
+
+
+ 2.0
+
+
+
\ No newline at end of file
diff --git a/Nexmo.Samples.Coverage/Program.cs b/Nexmo.Samples.Coverage/Program.cs
new file mode 100644
index 000000000..39e21cd2e
--- /dev/null
+++ b/Nexmo.Samples.Coverage/Program.cs
@@ -0,0 +1,98 @@
+using System;
+using System.Linq;
+using Nexmo.Api;
+using Nexmo.Api.Voice;
+
+namespace Nexmo.Samples.Coverage
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ ApiRequestCoverageTest();
+
+ //RemoveUnusedApplications();
+ }
+
+ ///
+ /// This is a quick sanity check with 90%+ code coverage of the ApiRequest classes
+ ///
+ private static void ApiRequestCoverageTest()
+ {
+ Console.WriteLine("Account.GetBalance() = {0}", Account.GetBalance());
+ Console.WriteLine("Account.GetNumbers() = {0}", Account.GetNumbers().count);
+
+ /////
+
+ var niResp = NumberInsight.Request(new NumberInsight.NumberInsightRequest
+ {
+ Number = Configuration.Instance.Settings["test_number"],
+ Callback = "https://abcdefg.ngrok.io/ni/"
+ });
+ Console.WriteLine("NumberInsight.Request() = {0}", niResp.status);
+
+ /////
+
+ var appRequest = new ApplicationRequest
+ {
+ name = "coveragetest",
+ type = "voice",
+ answer_url = "https://abcdefg.ngrok.io/api/voice",
+ event_url = "https://abcdefg.ngrok.io/api/voice",
+ };
+
+ var appResp = Application.Create(appRequest);
+ Console.WriteLine("Application.Create() = {0}", appResp.id);
+
+ var appList = Application.List();
+ Console.WriteLine("Application.List() = {0}", appList.Count);
+ var filteredAppList = Application.List(10, 0, appResp.id);
+ Console.WriteLine("Application.List(10, 0, appResp.id) = {0}", filteredAppList.Count);
+ appRequest.id = appResp.id;
+ appRequest.name = "updcoveragetest";
+ var appUpdateResp = Application.Update(appRequest);
+ Console.WriteLine("Application.Update(appRequest) = {0}", appUpdateResp.name);
+ var isDeleted = Application.Delete(appUpdateResp.id);
+ Console.WriteLine("Application.Delete(id) = {0}", isDeleted);
+
+ /////
+
+ var results = Call.Do(new Call.CallCommand
+ {
+ to = new[]
+ {
+ new Call.Endpoint
+ {
+ type = "phone",
+ number = Configuration.Instance.Settings["test_number"]
+ }
+ },
+ @from = new Call.Endpoint
+ {
+ type = "phone",
+ number = Configuration.Instance.Settings["nexmo_number"]
+ },
+ answer_url = new[]
+ {
+ "https://nexmo-community.github.io/ncco-examples/first_call_talk.json"
+ }
+ });
+ Console.WriteLine("Call.Do() = {0}", results.status);
+ var callListResults = Call.List();
+ Console.WriteLine("Call.List() = {0}", callListResults.count);
+ }
+
+ private static void RemoveUnusedApplications()
+ {
+ var appList = Application.List();
+ Console.WriteLine("BEFORE: Application.List() = {0}", appList.Count);
+ foreach (var app in appList.Where(a => a.id != Configuration.Instance.Settings["Nexmo.Application.Id"]))
+ {
+ Console.WriteLine(app.id);
+ Application.Delete(app.id);
+ }
+ Console.WriteLine("AFTER: Application.List() = {0}", Application.List().Count);
+ }
+ }
+}
+
diff --git a/Nexmo.Samples.Coverage/Properties/AssemblyInfo.cs b/Nexmo.Samples.Coverage/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..122e642b0
--- /dev/null
+++ b/Nexmo.Samples.Coverage/Properties/AssemblyInfo.cs
@@ -0,0 +1,19 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Nexmo")]
+[assembly: AssemblyProduct("Nexmo.Samples.Coverage")]
+[assembly: AssemblyTrademark("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("797bd6e3-6749-4b10-81bc-2587f635b94a")]
diff --git a/Nexmo.Samples.Coverage/project.json b/Nexmo.Samples.Coverage/project.json
new file mode 100644
index 000000000..395acbece
--- /dev/null
+++ b/Nexmo.Samples.Coverage/project.json
@@ -0,0 +1,28 @@
+{
+ "version": "1.0.0-*",
+ "buildOptions": {
+ "emitEntryPoint": true
+ },
+
+ "dependencies": {
+ "Microsoft.NETCore.App": {
+ //"type": "platform",
+ "version": "1.0.1"
+ },
+ "Nexmo.Api": "2.0.*"
+ },
+
+ "frameworks": {
+ "netcoreapp1.0": {
+ "imports": "dnxcore50",
+ "dependencies": {
+ "NETStandard.Library": "1.6.0"
+ }
+ }
+ },
+ "runtimes": {
+ "win7-x64": {},
+ "osx": {},
+ "linux": {}
+ }
+}
diff --git a/Nexmo.Samples.Voice.FirstTTS/App.config.example b/Nexmo.Samples.Voice.FirstTTS/App.config.example
deleted file mode 100644
index 3c944d626..000000000
--- a/Nexmo.Samples.Voice.FirstTTS/App.config.example
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/Nexmo.Samples.Voice.FirstTTS/Nexmo.Samples.Voice.FirstTTS.csproj b/Nexmo.Samples.Voice.FirstTTS/Nexmo.Samples.Voice.FirstTTS.csproj
deleted file mode 100644
index 3d2cb42e9..000000000
--- a/Nexmo.Samples.Voice.FirstTTS/Nexmo.Samples.Voice.FirstTTS.csproj
+++ /dev/null
@@ -1,68 +0,0 @@
-
-
-
-
- Debug
- AnyCPU
- {C515B039-AC1F-44F2-9703-B61B4A1DE449}
- Exe
- Properties
- Nexmo.Samples.Voice.FirstTTS
- Nexmo.Samples.Voice.FirstTTS
- v4.5.2
- 512
- true
-
-
- AnyCPU
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
-
-
- AnyCPU
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {EE7DA727-2AE3-4C76-809A-56B7433004FE}
- Nexmo.Api
-
-
-
-
-
\ No newline at end of file
diff --git a/Nexmo.Samples.Voice.FirstTTS/Nexmo.Samples.Voice.FirstTTS.xproj b/Nexmo.Samples.Voice.FirstTTS/Nexmo.Samples.Voice.FirstTTS.xproj
new file mode 100644
index 000000000..3004e3721
--- /dev/null
+++ b/Nexmo.Samples.Voice.FirstTTS/Nexmo.Samples.Voice.FirstTTS.xproj
@@ -0,0 +1,19 @@
+
+
+
+ 14.0.25420
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+ 9668e570-8dc4-4cb2-9058-7508223cab49
+ Nexmo.Samples.Voice.FirstTTS
+ .\obj
+ .\bin\
+
+
+
+ 2.0
+
+
+
\ No newline at end of file
diff --git a/Nexmo.Samples.Voice.FirstTTS/Program.cs b/Nexmo.Samples.Voice.FirstTTS/Program.cs
index 8cbc011f2..c77ed6e2f 100644
--- a/Nexmo.Samples.Voice.FirstTTS/Program.cs
+++ b/Nexmo.Samples.Voice.FirstTTS/Program.cs
@@ -1,6 +1,6 @@
using System;
-using System.Configuration;
using System.Net;
+using Nexmo.Api;
using Nexmo.Api.Voice;
namespace Nexmo.Samples.Voice.FirstTTS
@@ -9,11 +9,15 @@ public class Program
{
private static void Main(string[] args)
{
+ // https://github.com/dotnet/corefx/issues/4476
+ // https://github.com/dotnet/corefx/issues/7623
+#if net452
ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;
+#endif
// Set up some variables
- var applicationId = ConfigurationManager.AppSettings["Nexmo.Application.Id"];
- const string phoneNumberToCall = "15555551212";
+ var applicationId = Configuration.Instance.Settings["Nexmo.Application.Id"];
+ var phoneNumberToCall = Configuration.Instance.Settings["test_number"];
// Make a TTS Call to a phone number
@@ -34,7 +38,7 @@ private static void Main(string[] args)
from = new Call.Endpoint
{
type = "phone",
- number = "15554443333"
+ number = Configuration.Instance.Settings["nexmo_number"]
},
answer_url = new[]
{
diff --git a/Nexmo.Samples.Voice.FirstTTS/Properties/AssemblyInfo.cs b/Nexmo.Samples.Voice.FirstTTS/Properties/AssemblyInfo.cs
index ed0f7b950..85ebed0a8 100644
--- a/Nexmo.Samples.Voice.FirstTTS/Properties/AssemblyInfo.cs
+++ b/Nexmo.Samples.Voice.FirstTTS/Properties/AssemblyInfo.cs
@@ -32,5 +32,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyVersion("2.0.0.0")]
+[assembly: AssemblyFileVersion("2.0.0.0")]
diff --git a/Nexmo.Samples.Voice.FirstTTS/project.json b/Nexmo.Samples.Voice.FirstTTS/project.json
new file mode 100644
index 000000000..c2940d194
--- /dev/null
+++ b/Nexmo.Samples.Voice.FirstTTS/project.json
@@ -0,0 +1,29 @@
+{
+ "version": "1.0.0-*",
+ "buildOptions": {
+ "emitEntryPoint": true
+ },
+ "dependencies": {
+ "Nexmo.Api": "2.0.*"
+ },
+
+ "frameworks": {
+ "net452": {
+ },
+ "netcoreapp1.0": {
+ "imports": "dnxcore50",
+ "dependencies": {
+ //"NETStandard.Library": "1.6.0",
+ "Microsoft.NETCore.App": {
+ //"type": "platform",
+ "version": "1.0.*"
+ }
+ }
+ }
+ },
+ "runtimes": {
+ "win7-x64": {},
+ "osx": {},
+ "linux": {}
+ }
+}
\ No newline at end of file
diff --git a/Nexmo.Samples.Voice.FirstTTS/settings.json.example b/Nexmo.Samples.Voice.FirstTTS/settings.json.example
new file mode 100644
index 000000000..06e7e819a
--- /dev/null
+++ b/Nexmo.Samples.Voice.FirstTTS/settings.json.example
@@ -0,0 +1,9 @@
+{
+ "Nexmo.Url.Rest": "https://rest.nexmo.com",
+ "Nexmo.Url.Api": "https://api.nexmo.com",
+ "Nexmo.Application.Id": "ffffffff-ffff-ffff-ffff-ffffffffffff",
+ "Nexmo.Application.Key": "c:\\path\\to\\your\\application\\private.key",
+
+ "nexmo_number": "15555551212",
+ "test_number": "15557771212"
+}
\ No newline at end of file
diff --git a/Nexmo.Web.Sample/Nexmo.Web.Sample.csproj b/Nexmo.Web.Sample/Nexmo.Web.Sample.csproj
index 69d383c56..1a6f1aca8 100644
--- a/Nexmo.Web.Sample/Nexmo.Web.Sample.csproj
+++ b/Nexmo.Web.Sample/Nexmo.Web.Sample.csproj
@@ -61,6 +61,10 @@
MinimumRecommendedRules.ruleset
+
+ ..\packages\jose-jwt.2.0.2\lib\net40\jose-jwt.dll
+ True
+
..\packages\Microsoft.AspNet.Identity.Core.2.2.1\lib\net45\Microsoft.AspNet.Identity.Core.dll
True
@@ -70,6 +74,38 @@
True
+
+ ..\packages\Microsoft.Extensions.Configuration.1.0.0\lib\netstandard1.1\Microsoft.Extensions.Configuration.dll
+ True
+
+
+ ..\packages\Microsoft.Extensions.Configuration.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.Extensions.Configuration.Abstractions.dll
+ True
+
+
+ ..\packages\Microsoft.Extensions.Configuration.FileExtensions.1.0.0\lib\net451\Microsoft.Extensions.Configuration.FileExtensions.dll
+ True
+
+
+ ..\packages\Microsoft.Extensions.Configuration.Json.1.0.0\lib\net451\Microsoft.Extensions.Configuration.Json.dll
+ True
+
+
+ ..\packages\Microsoft.Extensions.FileProviders.Abstractions.1.0.0\lib\netstandard1.0\Microsoft.Extensions.FileProviders.Abstractions.dll
+ True
+
+
+ ..\packages\Microsoft.Extensions.FileProviders.Physical.1.0.0\lib\net451\Microsoft.Extensions.FileProviders.Physical.dll
+ True
+
+
+ ..\packages\Microsoft.Extensions.FileSystemGlobbing.1.0.0\lib\net451\Microsoft.Extensions.FileSystemGlobbing.dll
+ True
+
+
+ ..\packages\Microsoft.Extensions.Primitives.1.0.0\lib\netstandard1.0\Microsoft.Extensions.Primitives.dll
+ True
+
False
..\packages\Microsoft.Owin.3.0.1\lib\net45\Microsoft.Owin.dll
@@ -114,11 +150,16 @@
False
..\packages\Microsoft.Owin.Security.Twitter.3.0.1\lib\net45\Microsoft.Owin.Security.Twitter.dll
-
- ..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll
+
+ ..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll
+ True
+
+
+ ..\packages\Nexmo.Csharp.Client.2.0.0\lib\net452\Nexmo.Api.dll
True
+
@@ -227,14 +268,12 @@
+
+ Always
+
+
-
-
- {ee7da727-2ae3-4c76-809a-56b7433004fe}
- Nexmo.Api
-
-
10.0
$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
diff --git a/Nexmo.Web.Sample/Views/Web.config b/Nexmo.Web.Sample/Views/Web.config
index 7d28e8e55..342caa3e2 100644
--- a/Nexmo.Web.Sample/Views/Web.config
+++ b/Nexmo.Web.Sample/Views/Web.config
@@ -9,7 +9,7 @@
-
+
diff --git a/Nexmo.Web.Sample/Web.config.example b/Nexmo.Web.Sample/Web.config.example
index 55658d3e9..e877a0ce6 100644
--- a/Nexmo.Web.Sample/Web.config.example
+++ b/Nexmo.Web.Sample/Web.config.example
@@ -17,6 +17,7 @@
+
@@ -41,44 +42,24 @@
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
diff --git a/Nexmo.Web.Sample/packages.config b/Nexmo.Web.Sample/packages.config
index 04bcb6932..ebc05d735 100644
--- a/Nexmo.Web.Sample/packages.config
+++ b/Nexmo.Web.Sample/packages.config
@@ -1,5 +1,6 @@
+
@@ -11,6 +12,14 @@
+
+
+
+
+
+
+
+
@@ -23,6 +32,17 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Nexmo.Web.Sample/settings.json.example b/Nexmo.Web.Sample/settings.json.example
new file mode 100644
index 000000000..780103ef0
--- /dev/null
+++ b/Nexmo.Web.Sample/settings.json.example
@@ -0,0 +1,12 @@
+{
+ "Nexmo.Url.Rest": "https://rest.nexmo.com",
+ "Nexmo.Url.Api": "https://api.nexmo.com",
+ "Nexmo.api_key": "deadbeef",
+ "Nexmo.api_secret": "deadbeef",
+
+ "Nexmo.Application.Id": "ffffffff-ffff-ffff-ffff-ffffffffffff",
+ "Nexmo.Application.Key": "c:\\path\\to\\your\\application\\private.key",
+
+ "nexmo_number": "15555551212",
+ "test_number": "15557771212"
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index da71c16ab..00535907d 100644
--- a/README.md
+++ b/README.md
@@ -25,20 +25,24 @@ To install the C# client library using NuGet:
Alternatively:
* Download or build (see developer instructions) the Nexmo.Api.dll.
-* If you have downloaded a release, ensure you are referencing the
-Newtonsoft.Json.dll dependency by either including it with your project's
-NuGet dependencies or manually referencing it.
+* If you have downloaded a release, ensure you are referencing the required dependencies by
+either including them with your project's NuGet dependencies or manually referencing them.
* Reference the assembly in your code.
Configuration:
--------------
-* Provide your API key, secret, and nexmo URLs in appSettings:
+* Provide the nexmo URLs, API key, secret, and application credentials (for JWT) in ```settings.json```:
-```XML
-
-
-
-
+```json
+{
+ "Nexmo.Url.Rest": "https://rest.nexmo.com",
+ "Nexmo.Url.Api": "https://api.nexmo.com",
+ "Nexmo.api_key": "deadbeef",
+ "Nexmo.api_secret": "deadbeef",
+
+ "Nexmo.Application.Id": "ffffffff-ffff-ffff-ffff-ffffffffffff",
+ "Nexmo.Application.Key": "c:\\path\\to\\your\\application\\private.key"
+}
```
Examples
@@ -48,7 +52,7 @@ The following examples show how to:
* [Receive a message](#receiving-a-message)
* [Initiate a call](#initiating-a-call)
-### Sending A Message
+### Sending a Message
Use [Nexmo's SMS API][doc_sms] to send a SMS message.
@@ -75,13 +79,30 @@ public ActionResult Get([FromUri]SMS.SMSDeliveryReceipt response)
### Initiating a Call
Use [Nexmo's Call API][doc_voice] to initiate a voice call.
+
+__NOTE:__ You must have a valid Application ID and key in order to make voice calls! Use ```Nexmo.Api.Application``` to register. See the [Application API][doc_app] documentation for details.
+
```C#
-var result = Voice.Call(new Voice.CallCommand
+using Nexmo.Api.Voice;
+
+Call.Do(new Call.CallCommand
{
- to = "17775551212",
- answer_url = "https://abcdefgh.ngrok.io/content/voiceDemo.xml",
- status_url = "https://abcdefgh.ngrok.io/api/voice",
- from = "15555551212",
+ to = new[]
+ {
+ new Call.Endpoint {
+ type = "phone",
+ number = "15555551212"
+ }
+ },
+ from = new Call.Endpoint
+ {
+ type = "phone",
+ number = "15557772424"
+ },
+ answer_url = new[]
+ {
+ "https://nexmo-community.github.io/ncco-examples/first_call_talk.json"
+ }
});
```
@@ -130,16 +151,30 @@ API Coverage
* [X] Event Based Alerts
* [X] Sending Alerts
* [X] Campaign Subscription Management
-* Voice
- * [X] Outbound Calls
- * [X] Inbound Call
- * [X] Text-To-Speech Call
- * [X] Text-To-Speech Prompt
+* Application
+ * [X] Create
+ * [X] List
+ * [X] Update
+ * [X] Delete
+* Call
+ * [X] Outbound
+ * [X] Get
+ * [X] List
+ * [X] Edit
+ * [X] TTS
+ * [X] Stream
+ * [X] DTMF
Contributing
------------
-We are currently targeting the 4.5.2 - 4.6.1 frameworks and using Visual Studio 2015 Update 1.
+Targeted frameworks:
+
+* 4.5.2
+* 4.6, 4.6.1, 4.6.2
+* .NET Standard 1.6
+
+Visual Studio 2015 is required (Community should be fine). Update 3 is recommended.
1. Get latest code either by cloning the repository or downloading a snapshot of the source.
2. Open "Nexmo.Api.sln"
@@ -147,6 +182,14 @@ We are currently targeting the 4.5.2 - 4.6.1 frameworks and using Visual Studio
Pull requests are welcome!
+Thanks
+------
+
+Special thanks to our contributors:
+
+* [jdpearce](https://github.com/jdpearce)
+* [jonferreira](https://github.com/jonferreira)
+
License
-------
@@ -155,5 +198,6 @@ This library is released under the [MIT License][license]
[create_account]: https://docs.nexmo.com/tools/dashboard#setting-up-your-nexmo-account
[signup]: https://dashboard.nexmo.com/sign-up?utm_source=DEV_REL&utm_medium=github&utm_campaign=csharp-client-library
[doc_sms]: https://docs.nexmo.com/api-ref/sms-api?utm_source=DEV_REL&utm_medium=github&utm_campaign=csharp-client-library
-[doc_voice]: https://docs.nexmo.com/voice/call?utm_source=DEV_REL&utm_medium=github&utm_campaign=csharp-client-library
+[doc_voice]: https://docs.nexmo.com/voice/voice-api?utm_source=DEV_REL&utm_medium=github&utm_campaign=csharp-client-library
+[doc_app]: https://docs.nexmo.com/tools/application-api?utm_source=DEV_REL&utm_medium=github&utm_campaign=csharp-client-library
[license]: LICENSE.md
\ No newline at end of file