ShipRush

ShipRush SDK

Bin

NETFX_35

de-DE

ShipRush.Language.resources.zip

es-MX

ShipRush.Language.resources.zip

fr-CA

ShipRush.Language.resources.zip

ru-RU

ShipRush.Language.resources.zip

Common.Logging.Core

Common.Logging.Core.PBD.zip

Common.Logging.Core.DLL.zip

Common.Logging.Core.XML.zip

Log4net

log4net.DLL.zip

NewtonSoft.Json

Newtonsoft.Json.DLL.zip

Newtonsoft.Json.XML.zip

Ninject

Ninject.DLL.zip

Ninject.XML.zip

Protobuf-net

protobuf-net.DLL.zip

protobuf-net.PDB.zip

protobuf-net.XML.zip

Language

ShipRush.Language.DLL.zip

ShipRush.Language.PDB.zip

SDK

ShipRush.SDK.DLL.zip

ShipRush.SDK.PDB.zip

ShipRush.SDK.Proxies.DLL.zip

ShipRush.SDK.Proxies.PDB.zip

Release

de-DE

ShipRush.Language.resources.DLL.zip

es-MX

ShipRush.Language.resources.DLL.zip

fr-CA

ShipRush.Language.resources.DLL.zip

ru-RU

ShipRush.Language.resources.DLL.zip

Common.Logging.Core

Common.Logging.Core.DLL.zip

Common.Logging.Core.PDB.zip

Common.Logging.Core.XML.zip

Log4net

log4net.DLL.zip

Newtonsoft.Json

Newtonsoft.Json.DLL.zip

Newtonsoft.Json.XML.zip

Ninject

Ninject.Common.DLL.zip

Ninject.Common.XML.zip

Ninject.Platform.DLL.zip

Ninject.Platform.XML.zip

Protobuf-net

protobuf-net.DLL.zip

protobuf-net.PDB.zip

protobuf-net.XML.zip

Language

ShipRush.Language.DLL.zip

ShipRush.Language.PDB.zip

SDK

ShipRush.SDK.DLL.zip

ShipRush.SDK.PDB.zip

ShipRush.SDK.Proxies.DLL.zip

ShipRush.SDK.Proxies.PDB.zip

Properties: Assembly Information

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: AssemblyTitle("ShipRush.SDK")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Descartes Systems")]
[assembly: AssemblyProduct("ShipRush.SDK")]
[assembly: AssemblyCopyright("(c) Z-Firm LLC ALL RIGHTS RESERVED")]
[assembly: AssemblyTrademark("ShipRush is a registered trademark of Z-Firm LLC")]
[assembly: AssemblyCulture("")]

// 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("721fa4a6-2a6c-44fa-83c2-49bbbf8d189b")]

// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// 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("4.0.14.0471")]
[assembly: AssemblyFileVersion("4.0.14.0471")]

Transport

APIs and SDKs are listed next.

APIs

Command

/*
{ $Revision: #4 $ }
{ $Date: 2013/05/02 $ }
{ $Author: alexh $ }
{ *************************************************************************** }
{ * * }
{ * This file contains information that is the confidential and * }
{ * proprietary property of Z-Firm LLC, and may not be copied, published, * }
{ * disclosed, or transmitted to others, or used for any purpose without * }
{ * the express written authorization of an authorized managing member of * }
{ * Z-Firm LLC. * }
{ * * }
{ * The unauthorized taking, use or disclosure of any of Z-Firm LLC's * }
{ * trade secrets can be punishable as a crime under the United States * }
{ * Economic Espionage Act and other applicable State statutes. * }
{ * The unauthorized taking, use or disclosure of the Z-Firm’s * }
{ * trade secrets can also result in civil liability under applicable * }
{ * State laws. For willful infringement, Z-Firm LLC can recover * }
{ * triple the amount of its damages and its attorneys' fees in * }
{ * collecting such damages. * }
{ * * }
{ * Copyright 2010 Z-Firm LLC. All Rights Reserved. * }
{ * * }
{ *************************************************************************** }
*/

namespace ShipRush.SDK.Transport
{
/// <summary>
/// Defines an API command
/// </summary>
public class APICommand
{

public string CommandUrl { get; set; }
public string ServiceUrl { get; set; }
public string Method { get; set; }
public string FullUrl { get; set; }

public APICommand(string method, string serviceUrl, string commandUrl)
{
this.Method = method;
this.CommandUrl = commandUrl;
this.ServiceUrl = serviceUrl;
}

public APICommand(string method, string fullUrl)
{
this.Method = method;
this.FullUrl = fullUrl;
}


}
}

Commands

/*
{ $Revision: #4 $ }
{ $Date: 2013/05/02 $ }
{ $Author: alexh $ }
{ *************************************************************************** }
{ * * }
{ * This file contains information that is the confidential and * }
{ * proprietary property of Z-Firm LLC, and may not be copied, published, * }
{ * disclosed, or transmitted to others, or used for any purpose without * }
{ * the express written authorization of an authorized managing member of * }
{ * Z-Firm LLC. * }
{ * * }
{ * The unauthorized taking, use or disclosure of any of Z-Firm LLC's * }
{ * trade secrets can be punishable as a crime under the United States * }
{ * Economic Espionage Act and other applicable State statutes. * }
{ * The unauthorized taking, use or disclosure of the Z-Firm’s * }
{ * trade secrets can also result in civil liability under applicable * }
{ * State laws. For willful infringement, Z-Firm LLC can recover * }
{ * triple the amount of its damages and its attorneys' fees in * }
{ * collecting such damages. * }
{ * * }
{ * Copyright 2010 Z-Firm LLC. All Rights Reserved. * }
{ * * }
{ *************************************************************************** }
*/

namespace ShipRush.SDK.Transport
{
/// <summary>
/// Collection of availiable API Commands.
/// </summary>
public class APICommands
{

// Account management
public static readonly APICommand CREATE_USER = new APICommand("POST", "accountservice.svc", "account/createuser");
public static readonly APICommand UPDATE_USER = new APICommand("POST", "accountservice.svc", "account/updateuser");
public static readonly APICommand CHECK_CREATE_USER = new APICommand("POST", "accountservice.svc", "account/checkcreateuser");
public static readonly APICommand LOGIN = new APICommand("POST", "accountservice.svc", "user/getsessiontoken");
public static readonly APICommand ADD_TEST_DATA = new APICommand("POST", "accountservice.svc", "user/addtestdata");
public static readonly APICommand GET_USER = new APICommand("POST", "accountservice.svc", "user/get");
public static readonly APICommand GET_MYSHIPRUSH_TIME = new APICommand("POST", "accountservice.svc", "time/get");
public static readonly APICommand GET_SESSION_TOKEN = new APICommand("POST", "accountservice.svc", "user/getsessiontoken");
public static readonly APICommand GET_USER_TOKEN = new APICommand("POST", "accountservice.svc", "user/getusertoken");

public static readonly APICommand CREATE_WEBSTORE = new APICommand("POST", "accountservice.svc", "webstore/create");
public static readonly APICommand GET_WEBSTORE = new APICommand("POST", "accountservice.svc", "webstore/get");
public static readonly APICommand DELETE_WEBSTORE = new APICommand("POST", "accountservice.svc", "webstore/delete");
public static readonly APICommand GET_AVAILABLE_WEBSTORE_TYPES = new APICommand("POST", "accountservice.svc", "webstore/types");

public static readonly APICommand CREATE_SHIPPINGACCOUNT = new APICommand("POST", "accountservice.svc", "shippingaccount/create");
public static readonly APICommand GET_SHIPPINGACCOUNT = new APICommand("POST", "accountservice.svc", "shippingaccount/get");
public static readonly APICommand SEND_EMAIL = new APICommand("POST", "accountservice.svc", "account/sendemail");

public static readonly APICommand CREATE_SHIPPINGACCOUNT_GETEULAS = new APICommand("POST", "accountservice.svc", "shippingaccount/create_geteulas");
public static readonly APICommand CREATE_SHIPPINGACCOUNT_COMPLETE = new APICommand("POST", "accountservice.svc", "shippingaccount/create_complete");

public static readonly APICommand ADD_SHIPMENT_HISTORY = new APICommand("POST", "shipmentservice.svc", "shipments/history/add");
public static readonly APICommand ADD_SHIPMENT_PENDING = new APICommand("POST", "shipmentservice.svc", "shipments/pending/add");
public static readonly APICommand ADD_SHIPMENT_FAVORITE = new APICommand("POST", "shipmentservice.svc", "shipments/favorites/add");
public static readonly APICommand ADD_SHIPMENT_AND_INDEX = new APICommand("POST", "shipmentservice.svc", "shipments/addandindex/shipments2");

public static readonly APICommand GET_SHIPMENTS = new APICommand("POST", "shipmentservice.svc", "shipments/get");
public static readonly APICommand UPDATE_SHIPMENT = new APICommand("POST", "shipmentservice.svc", "shipments/update");
public static readonly APICommand UPDATE_SHIPMENT_BULK = new APICommand("POST", "shipmentservice.svc", "shipments/updatebulk");

public static readonly APICommand GET_PACKINGLIST = new APICommand("POST", "PackingListService.svc", "packinglist/get");
public static readonly APICommand PACKINGLIST_CONFIG = new APICommand("GET", "PackingListService.svc", "packinglist/config");

public static readonly APICommand REGISTER_DESKTOPTOOLKIT = new APICommand("POST", "accountservice.svc", "desktop/register");
public static readonly APICommand REGISTER_PRINTERS = new APICommand("POST", "accountservice.svc", "print/registerprinters");
public static readonly APICommand SETUP_ZEBRA_PRINTER = new APICommand("POST", "accountservice.svc", "print/setupprinter");
public static readonly APICommand GET_PRINTERS = new APICommand("POST", "accountservice.svc", "print/getprinters");
public static readonly APICommand ADD_PRINT_JOB = new APICommand("POST", "accountservice.svc", "print/addprintjob");
public static readonly APICommand UPDATE_PRINT_JOB = new APICommand("POST", "accountservice.svc", "print/updateprintjob");
public static readonly APICommand GET_PRINT_JOBS = new APICommand("POST", "accountservice.svc", "print/getprintjobs");
public static readonly APICommand EMPTY_PRINT_QUEUE = new APICommand("POST", "accountservice.svc", "print/emptyprintqueue");

// notification
public static readonly APICommand NOTIFICATION_CONFIGURE = new APICommand("POST", "AccountService.svc", "notification/configure");
public static readonly APICommand NOTIFICATION_REMOVE = new APICommand("POST", "AccountService.svc", "notification/remove");
public static readonly APICommand NOTIFICATION_STATUS = new APICommand("POST", "AccountService.svc", "notification/status");
public static readonly APICommand NOTIFICATION_SUBSCRIBE = new APICommand("POST", "AccountService.svc", "notification/subscribe");
public static readonly APICommand NOTIFICATION_UNSUBSCRIBE = new APICommand("POST", "AccountService.svc", "notification/unsubscribe");
public static readonly APICommand NOTIFICATION_GETSUBSCRIBTIONS = new APICommand("POST", "AccountService.svc", "notification/getsubscriptions");
public static readonly APICommand NOTIFICATION_GETSUBSCRIBTIONSTATISTICS = new APICommand("POST", "AccountService.svc", "notification/getsubscriptionstratistics");

// {usertoken}/{webstoreId}/order/add
public static APICommand ADD_ORDER(string userId, string webstoreId)
{
return new APICommand("POST", "integrationservice.svc", string.Format("{0}/{1}/order/add", userId, webstoreId));
}

// Internal APIs (also part of Web Shipping APIs)
public static readonly APICommand CREATE_SHIPPINGACCOUNTANDREGISTER = new APICommand("POST", "accountservice.svc", "shippingaccount/createandregister");
public static readonly APICommand GET_SHIPPINGACCOUNTS = new APICommand("POST", "accountservice.svc", "shippingaccounts/get");
public static readonly APICommand GET_SETTING = new APICommand("POST", "accountservice.svc", "setting/get");
public static readonly APICommand SET_SETTING = new APICommand("POST", "accountservice.svc", "setting/set");
public static readonly APICommand GET_SHIPPINGACCOUNT_BALANCE = new APICommand("POST", "accountservice.svc", "shippingaccount/getbalance");
public static readonly APICommand ADD_FUNDS = new APICommand("POST", "accountservice.svc", "shippingaccount/addfunds");

// Web Shipping APIs
public static readonly APICommand GET_SETTINGS = new APICommand("POST", "accountservice.svc", "settings/get");
public static readonly APICommand SET_SETTINGS = new APICommand("POST", "accountservice.svc", "settings/set");

public static readonly APICommand SHIPMENT_SHIP = new APICommand("POST", "shipmentservice.svc", "shipment/ship");
public static readonly APICommand SHIPMENT_VOID = new APICommand("POST", "shipmentservice.svc", "shipment/void");
public static readonly APICommand SHIPMENT_RATE = new APICommand("POST", "shipmentservice.svc", "shipment/rate");
public static readonly APICommand SHIPMENT_EOD = new APICommand("POST", "shipmentservice.svc", "shipment/eod");
public static readonly APICommand SHIPMENT_RATESHOPPING = new APICommand("POST", "shipmentservice.svc", "shipment/rateshopping");
public static readonly APICommand VALIDATE_ADDRESS = new APICommand("POST", "shipmentservice.svc", "shipment/validateaddress");
public static readonly APICommand SHIPMENT_TRACKING = new APICommand("POST", "shipmentservice.svc", "shipment/tracking");

public static readonly APICommand SHIPMENT_REQUESTPICKUP = new APICommand("POST", "shipmentservice.svc", "shipment/pickup");
public static readonly APICommand SHIPMENT_CANCELPICKUP = new APICommand("POST", "shipmentservice.svc", "shipment/cancelpickup");

public static readonly APICommand SHIPMENT_INSURANCE_RATE = new APICommand("POST", "shipmentservice.svc", "shipment/insurance/rate");
public static readonly APICommand SHIPMENT_INSURANCE_SHIP = new APICommand("POST", "shipmentservice.svc", "shipment/insurance/ship");
public static readonly APICommand SHIPMENT_INSURANCE_VOID = new APICommand("POST", "shipmentservice.svc", "shipment/insurance/void");
public static readonly APICommand ACCOUNT_GET_INSURANCE_SETTINGS = new APICommand("POST", "accountservice.svc", "insurance/get_settings");

public static readonly APICommand SHIPMENT_LOOKUP_SERVICES = new APICommand("POST", "shipmentservice.svc", "shipment/lookup/services");
public static readonly APICommand SHIPMENT_LOOKUP_PACKAGING = new APICommand("POST", "shipmentservice.svc", "shipment/lookup/packaging");
public static readonly APICommand SHIPMENT_LOOKUP_SHIPMENTOPTIONS = new APICommand("POST", "shipmentservice.svc", "shipment/lookup/shipmentoptions");

// Inventory Management
public static readonly APICommand CATALOG_ADD_TEST_DATA = new APICommand("POST", "catalogservice.svc", "catalog/addtestdata");
public static readonly APICommand CATALOG_GET_CATALOG = new APICommand("POST", "catalogservice.svc", "catalog/get");
public static readonly APICommand CATALOG_GET_CATALOG_ITEM = new APICommand("POST", "catalogservice.svc", "catalog/getbyid");

public static readonly APICommand INVENTORY_GET_INVENTORYLOCATIONS = new APICommand("POST", "catalogservice.svc", "inventory/locations/get");
public static readonly APICommand INVENTORY_GET_INVENTORY= new APICommand("POST", "catalogservice.svc", "inventory/get");
public static readonly APICommand INVENTORY_UPDATE_INVENTORY = new APICommand("POST", "catalogservice.svc", "inventory/update");
}
}

Errors

/*
{ $Revision: #2 $ }
{ $Date: 2020/03/20 $ }
{ $Author: alex $ }
{ *************************************************************************** }
{ * * }
{ * This file contains information that is the confidential and * }
{ * proprietary property of Z-Firm LLC, and may not be copied, published, * }
{ * disclosed, or transmitted to others, or used for any purpose without * }
{ * the express written authorization of an authorized managing member of * }
{ * Z-Firm LLC. * }
{ * * }
{ * The unauthorized taking, use or disclosure of any of Z-Firm LLC's * }
{ * trade secrets can be punishable as a crime under the United States * }
{ * Economic Espionage Act and other applicable State statutes. * }
{ * The unauthorized taking, use or disclosure of the Z-Firm’s * }
{ * trade secrets can also result in civil liability under applicable * }
{ * State laws. For willful infringement, Z-Firm LLC can recover * }
{ * triple the amount of its damages and its attorneys' fees in * }
{ * collecting such damages. * }
{ * * }
{ * Copyright 2010 Z-Firm LLC. All Rights Reserved. * }
{ * * }
{ *************************************************************************** }
*/

namespace ShipRush.SDK.Transport
{
public class APIError
{
public string Message { get; set; }
public string Details { get; set; }
public string CallContextId { get; set; }
public string ComputerName { get; set; }
}
}

Param

/*
{ $Revision: #4 $ }
{ $Date: 2013/05/02 $ }
{ $Author: alexh $ }
{ *************************************************************************** }
{ * * }
{ * This file contains information that is the confidential and * }
{ * proprietary property of Z-Firm LLC, and may not be copied, published, * }
{ * disclosed, or transmitted to others, or used for any purpose without * }
{ * the express written authorization of an authorized managing member of * }
{ * Z-Firm LLC. * }
{ * * }
{ * The unauthorized taking, use or disclosure of any of Z-Firm LLC's * }
{ * trade secrets can be punishable as a crime under the United States * }
{ * Economic Espionage Act and other applicable State statutes. * }
{ * The unauthorized taking, use or disclosure of the Z-Firm’s * }
{ * trade secrets can also result in civil liability under applicable * }
{ * State laws. For willful infringement, Z-Firm LLC can recover * }
{ * triple the amount of its damages and its attorneys' fees in * }
{ * collecting such damages. * }
{ * * }
{ * Copyright 2010 Z-Firm LLC. All Rights Reserved. * }
{ * * }
{ *************************************************************************** }
*/

using System;
using System.Web;

namespace ShipRush.SDK.Transport
{
/// <summary>
/// Contains the Name/Value api parameter
/// </summary>
public class APIParam
{
private string key;
private string value;

public string Key { get { return this.key; } }
public string Value { get { return this.value; } }

/// <summary>
/// Initializes a new instance of the <see cref="APIParam"/> class.
/// </summary>
/// <param name="key">The key.</param>
/// <param name="value">The value.</param>
public APIParam(string key, string value)
{
this.key = key;
this.value = value;
}


/// <summary>
/// Returns a <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"></see> that represents the current <see cref="T:System.Object"></see>.
/// </returns>
public override string ToString()
{
if (string.IsNullOrEmpty(this.value))
{
return string.Empty;
}
return HttpUtility.UrlEncode(this.key) + "=" + HttpUtility.UrlEncode(this.value);
}
}
}

SDKs

/*
{ $Revision: #74 $ }
{ $Date: 2010/06/15 $ }
{ $Author: alex $ }
{ ************************************************************************** }
{ * * }
{ * This file contains information that is the confidential and * }
{ * proprietary property of Z-Firm LLC, and may not be copied, published, * }
{ * disclosed, or transmitted to others, or used for any purpose without * }
{ * the express written authorization of an authorized managing member of * }
{ * Z-Firm LLC. * }
{ * * }
{ * The unauthorized taking, use or disclosure of any of Z-Firm LLC's * }
{ * trade secrets can be punishable as a crime under the United States * }
{ * Economic Espionage Act and other applicable State statutes. * }
{ * The unauthorized taking, use or disclosure of the Z-Firm’s * }
{ * trade secrets can also result in civil liability under applicable * }
{ * State laws. For willful infringement, Z-Firm LLC can recover * }
{ * triple the amount of its damages and its attorneys' fees in * }
{ * collecting such damages. * }
{ * * }
{ * Copyright 2009-2016 Z-Firm LLC. All Rights Reserved. * }
{ * * }
{ ************************************************************************** }
*/

using System;
using System.Collections.Generic;
using System.Text;
//using System.Windows.Forms;
using System.Xml;
using System.Web;
using System.IO;
using System.Net;
using System.Xml.Serialization;
using ShipRush.SDK.Proxies;
using ShipRush.SDK.Transport;
using ShipRush.SDK.Utils;
using System.IO.Compression;
using Newtonsoft.Json;

namespace ShipRush.SDK.Transport
{
public class ShipRushSDK
{
public static string ServiceUrl { get; set; }
public static string UserAgent { get; set; }
public static string DeveloperToken { get; set; }
public static string UserToken { get; set; }
public static string ShippingToken { get; set; }
public static string UserId { get; set; }
public static string AccountId { get; set; }
public static string SessionToken { get; set; }
public static int ClientSdkVersion { get; set; }
// It is important to use http compression ! Compression is required on production.
public static bool EnableHttpCompression { get; set; }


private const int shipRushAPICallTimeout60Seconds = 60*1000;

public static string ContentEncoding { get; set; }
public static long ContentLength { get; set; }

// v2 API for the OpenAPI/API Portal project
public static bool IsJsonAPI { get; set; }

static ShipRushSDK()
{
ClientSdkVersion = SdkVersion.Current;
EnableHttpCompression = true;
SetIsProduction(false);
UserAgent = "C# SDK " + SdkVersion.Current;
}

public ShipRushSDK()
{
ClientSdkVersion = SdkVersion.Current;
EnableHttpCompression = true;
SetIsProduction(false);
// The shipping API REQUIRES the user agent header.
// And it is an appropriate thing to pass in all situations.
UserAgent = "ShipRush Web C# SDK version " + SdkVersion.Current;
}

public static void SetIsProduction(bool isProduction)
{
ServiceUrl = isProduction ? "http://api.my.shiprush.com/" : "http://sandbox.api.my.shiprush.com/";
}

/// <summary>
/// Makes the parameter POST string.
/// </summary>
/// <param name="parms">The Parameters.</param>
/// <returns>The paremeters ready for a http post.</returns>
private static string MakeParameterPOSTString(APIParam[] parms)
{
if (parms == null) return "";

StringBuilder parameters = new StringBuilder();
List<string> paramStrings = new List<string>();

// Put all of the parameters in query string form.
foreach (APIParam parm in parms)
{
string paramStr = parm.ToString();

// Only add the parameter if the value isnt null
if (!string.IsNullOrEmpty(paramStr))
{
paramStrings.Add(paramStr);
}
}

parameters.Append(string.Join("&", paramStrings.ToArray()));

return parameters.ToString();
}

// Serializes any object to the stream using standard XmlSerializer
// All rules and limitations of XmlSerializer serializer applies
private static void ObjectToXMLStream<T>(T obj, Stream stream)
{
XmlSerializer xs = new XmlSerializer(typeof(T));
XmlTextWriter xmlTextWriter = new XmlTextWriter(stream, Encoding.UTF8);
xs.Serialize(xmlTextWriter, obj);
xmlTextWriter.Flush();
}

private static void ObjectToJsonStream<T>(T obj, Stream stream)
{
var asString = JsonConvert.SerializeObject(obj, Newtonsoft.Json.Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
var writer = new StreamWriter(stream, Encoding.UTF8);
writer.Write(asString);
writer.Flush();
}


public static T ExecuteCommand<T>(APICommand apiCommand, string parms)
{
return ExecuteCommand<object, T>(apiCommand, parms, null);
}

public static void ExecuteCommand<K>(APICommand apiCommand, K request)
{
ExecuteCommand<K, object>(apiCommand, null, request);
}

public static T ExecuteCommand<T>(APICommand apiCommand)
{
return ExecuteCommand<object, T>(apiCommand, null, null);
}

public static T ExecuteCommand<K, T>(APICommand apiCommand, K postData)
{
return ExecuteCommand<K, T>(apiCommand, null, postData);
}

public static Stream ExecuteCommand<K>(APICommand apiCommand, APIParam[] parms, K postData)
{
return ExecuteCommand<K>(apiCommand, MakeParameterPOSTString(parms), postData);
}

public static T ExecuteCommand<K, T>(APICommand apiCommand, string parms, K postData)
{
Stream stream = ExecuteCommand<K>(apiCommand, parms, postData);
// Command that returns "void" will be called with generic type T set to "object"
// Such commands need to return null. All other calls should deserialize response stream
if ((typeof(T) == typeof(object)))
{
return default(T);
}
else if (typeof(T) == typeof(Stream))
{
MemoryStream result = new MemoryStream();
CopyStream(stream, result);
result.Position = 0;
return (T)((object)result);
}
else
{
return UniversalDeserialize<T>(stream);
}
}

private static T UniversalDeserialize<T>(Stream stream)
{
if (IsJsonAPI)
{
var reader = new StreamReader(stream);
var asString = reader.ReadToEnd();
return JsonConvert.DeserializeObject<T>(asString);
}
else
{
XmlSerializer xs = new XmlSerializer(typeof(T));
return (T)xs.Deserialize(stream);
}
}

private static void UniversalSerialize<K>(K postData, Stream postDataStream)
{
if (IsJsonAPI)
ObjectToJsonStream(postData, postDataStream);
else
ObjectToXMLStream(postData, postDataStream);
}

public static Stream ExecuteCommand<K>(APICommand apiCommand, string parms, K postData)
{
Stream postDataStream = null;
// If posting data specified then serialize it using XmlSerializer and save it to the request stream
if (postData != null)
{
if (postData is Stream)
{
postDataStream = postData as Stream;
}
else
{
postDataStream = new MemoryStream();
UniversalSerialize(postData, postDataStream);
}
postDataStream.Position = 0;
}
return ExecuteCommandRaw(apiCommand, parms, postDataStream);
}

public static Stream ExecuteCommandRaw(APICommand apiCommand, string parms, Stream postData)
{
// API command may have full URL with credentials already included
string requestFullUrl = GetFullUrl(apiCommand);
if (!string.IsNullOrEmpty(parms)) requestFullUrl += parms;
UriBuilder uri = new UriBuilder(requestFullUrl);

// Create a Web Request
HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(uri.ToString());

// Add access headers that identify developer and user account.
// Some API calls (like CreateAccount) require only DeveloperToken,
// but there is no harm in adding UserToken with empty data for these calls -
// so we are always adding both headers unconditionally rather then maintain list of
// API calls the require only one access token
if (!string.IsNullOrEmpty(UserToken)) httpRequest.Headers.Add(AuthHeaders.shipRush_User_Token, UserToken);
if (!string.IsNullOrEmpty(DeveloperToken)) httpRequest.Headers.Add(AuthHeaders.shipRush_Developer_Token, DeveloperToken);
if (!string.IsNullOrEmpty(ShippingToken)) httpRequest.Headers.Add(AuthHeaders.shipRush_Shipping_Token, ShippingToken);
if (!string.IsNullOrEmpty(SessionToken)) httpRequest.Headers.Add(AuthHeaders.shipRush_Session_Token, SessionToken);
if (ClientSdkVersion > 0) httpRequest.Headers.Add(AuthHeaders.shipRush_Version, ClientSdkVersion.ToString());

// Case 72423: We need to know how many customers are on OSX, to prioritize upgrade to 64-bit
var operatingSystemHeaderValue = Environment.OSVersion.VersionString + ", " + Environment.OSVersion.Platform.ToString();
httpRequest.Headers.Add(AuthHeaders.shipRush_OS, operatingSystemHeaderValue);

httpRequest.Method = apiCommand.Method;
httpRequest.ContentType = IsJsonAPI
? "application/json"
: "application/xml";
httpRequest.UserAgent = UserAgent;

// The My.ShipRush api may (in the future) require that requesting systems support compression.
// Be sure to implement your system such that it accepts compressed responses.
if (EnableHttpCompression)
{
httpRequest.Headers["Accept-Encoding"] = "gzip, deflate";
}

// Getting "Only one usage of each socket address (protocol/network address/port) is normally permitted" under load?
// Read these articles
// http://blogs.msdn.com/dgorti/archive/2005/09/18/470766.aspx
// http://blog.magenic.com/blogs/jons/archive/2007/05/04/The-Tao-of-Microsoft-WCF-CustomBinding-Configuration-Elements.aspx
// http://blog.developers.ie/cgreen/archive/2007/04/24/2745.aspx

httpRequest.KeepAlive = false;
httpRequest.ProtocolVersion = HttpVersion.Version11;
httpRequest.Timeout = shipRushAPICallTimeout60Seconds;

if (postData != null)
{
using (Stream requestStream = httpRequest.GetRequestStream())
{
CopyStream(postData, requestStream);
}
}
else
{
if (apiCommand.Method == "POST")
httpRequest.ContentLength = 0;
}

// Performing HTTP command
try
{
using (WebResponse httpResponse = httpRequest.GetResponse())
{
Stream responseStream = httpResponse.GetResponseStream();
MemoryStream memoryStream = new MemoryStream();
CopyStream(responseStream, memoryStream);
memoryStream.Position = 0;
responseStream = memoryStream;

ContentEncoding = httpResponse.Headers["Content-Encoding"];
ContentEncoding = string.IsNullOrEmpty(ContentEncoding) ? "none" : ContentEncoding;
ContentLength = memoryStream.Length;

switch (ContentEncoding)
{
case "deflate":
responseStream = new DeflateStream((Stream)responseStream, CompressionMode.Decompress);
break;
case "gzip":
responseStream = new GZipStream((Stream)responseStream, CompressionMode.Decompress);
break;
default:
break;
}

Stream responseMemoryStream = new MemoryStream();
CopyStream(responseStream, responseMemoryStream);
responseMemoryStream.Position = 0;
return responseMemoryStream;
}
}
catch (WebException e)
{
if (e.Response != null) // Only do the parsing if there is a response from the server
{
using (StreamReader sr = new StreamReader(e.Response.GetResponseStream(), Encoding.UTF8))
{
UniversalHandleError(requestFullUrl, e, sr);
throw new ShipRushException(e.Message);
}
}
// No response from ShipRush web service - generic HTTP error
throw new ApplicationException(string.Format("{0}. {1}", e.Message, requestFullUrl));
}
}

private static void UniversalHandleError(string requestFullUrl, WebException exception, StreamReader stream)
{
if (IsJsonAPI)
JsonHandleError(requestFullUrl, exception, stream);
else
XmlHandleError(requestFullUrl, exception, stream);
}

private static void JsonHandleError(string requestFullUrl, WebException exception, StreamReader stream)
{
var errorMessage = string.Format($"API Error: Unable to call '{requestFullUrl}': {exception.Message}");

using (JsonTextReader jsonReader = new JsonTextReader(stream))
{
JsonSerializer ser = new JsonSerializer();
var errorResponse = ser.Deserialize<APIError>(jsonReader);
// Structured error from billing server will replace "Unable to 'XXX'" error message
if (errorResponse != null && !string.IsNullOrEmpty(errorResponse.Message))
{
errorMessage = errorResponse.Message;
throw new ShipRushException($"{errorMessage} ({errorResponse.CallContextId})");
}
}

throw new ShipRushException(errorMessage);
}

private static void XmlHandleError(string requestFullUrl, WebException exception, StreamReader stream)
{
XmlDocument doc = new XmlDocument() { XmlResolver = null }; // AH: Case 75013
try
{
doc.Load(stream);
}
catch (Exception)
{
// It appears that response is a non-XML document, just throw original error
// with added message text
using (StreamReader testReader = new StreamReader(exception.Response.GetResponseStream(), Encoding.UTF8))
{
string responseText = testReader.ReadToEnd();
throw new ShipRushException(string.Format("{0} {1} {2}", exception.Message, responseText, requestFullUrl));
}
}
XmlNode responseNode = doc.SelectSingleNode("Error");
if (responseNode != null)
{
XmlNode errMsgNode = responseNode.SelectSingleNode("Message");
if (errMsgNode != null)
throw new ShipRushException(errMsgNode.InnerText);
}
}

public static string GetFullUrl(APICommand apiCommand)
{
if (!string.IsNullOrEmpty(apiCommand.FullUrl))
return apiCommand.FullUrl;

return IsJsonAPI
? ServiceUrl + apiCommand.ServiceUrl + "/v2/" + apiCommand.CommandUrl
: ServiceUrl + apiCommand.ServiceUrl + "/" + apiCommand.CommandUrl;
}

private static void CopyStream(Stream from, Stream to)
{
if (!from.CanRead)
{
throw new ArgumentException("from Stream must implement the Read method.");
}

if (!to.CanWrite)
{
throw new ArgumentException("to Stream must implement the Write method.");
}

const int SIZE = 1024 * 1024;
byte[] buffer = new byte[SIZE];

int read = 0;
while ((read = from.Read(buffer, 0, buffer.Length)) > 0)
{
to.Write(buffer, 0, read);
}
}

#if !MONO


public static void PushFileAsDownload(string contentType, Stream content, string filename, HttpResponse response)
{
response.ContentType = contentType;
response.AppendHeader("Content-Disposition", "attachment; filename=" + filename);
Serialization.CopyStream(content, response.OutputStream);
response.End();
}

#endif
}
}

Threadsafe

/*
{ $Revision: #3 $ }
{ $Date: 2019/08/12 $ }
{ $Author: alexh $ }
{ ************************************************************************** }
{ * * }
{ * This file contains information that is the confidential and * }
{ * proprietary property of Z-Firm LLC, and may not be copied, published, * }
{ * disclosed, or transmitted to others, or used for any purpose without * }
{ * the express written authorization of an authorized managing member of * }
{ * Z-Firm LLC. * }
{ * * }
{ * The unauthorized taking, use or disclosure of any of Z-Firm LLC's * }
{ * trade secrets can be punishable as a crime under the United States * }
{ * Economic Espionage Act and other applicable State statutes. * }
{ * The unauthorized taking, use or disclosure of the Z-Firm’s * }
{ * trade secrets can also result in civil liability under applicable * }
{ * State laws. For willful infringement, Z-Firm LLC can recover * }
{ * triple the amount of its damages and its attorneys' fees in * }
{ * collecting such damages. * }
{ * * }
{ * Copyright 2009-2016 Z-Firm LLC. All Rights Reserved. * }
{ * * }
{ ************************************************************************** }
*/

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Xml;
using System.Web;
using System.IO;
using System.Net;
using System.Xml.Serialization;
using ShipRush.SDK.Proxies;
using ShipRush.SDK.Transport;
using ShipRush.SDK.Utils;
using System.IO.Compression;

namespace ShipRush.SDK.Transport
{
public class ShipRushSDK_ThreadSafe
{
public string ServiceUrl { get; set; }
public string UserAgent { get; set; }
public string DeveloperToken { get; set; }
public string UserToken { get; set; }
public string ShippingToken { get; set; }
public string UserId { get; set; }
public string AccountId { get; set; }
public string SessionToken { get; set; }
public int ClientSdkVersion { get; set; }
// It is important to use http compression ! Compression is required on production.
public bool EnableHttpCompression { get; set; }


private const int shipRushAPICallTimeout60Seconds = 60*1000;

public string ContentEncoding { get; set; }
public long ContentLength { get; set; }

public ShipRushSDK_ThreadSafe()
{
ClientSdkVersion = SdkVersion.Current;
EnableHttpCompression = true;
SetIsProduction(false);
// The shipping API REQUIRES the user agent header.
// And it is an appropriate thing to pass in all situations.
UserAgent = "ShipRush Web C# SDK version " + SdkVersion.Current;
}

public void SetIsProduction(bool isProduction)
{
ServiceUrl = isProduction ? "http://api.my.shiprush.com/" : "http://sandbox.api.my.shiprush.com/";
}

/// <summary>
/// Makes the parameter POST string.
/// </summary>
/// <param name="parms">The Parameters.</param>
/// <returns>The paremeters ready for a http post.</returns>
private string MakeParameterPOSTString(APIParam[] parms)
{
if (parms == null) return "";

StringBuilder parameters = new StringBuilder();
List<string> paramStrings = new List<string>();

// Put all of the parameters in query string form.
foreach (APIParam parm in parms)
{
string paramStr = parm.ToString();

// Only add the parameter if the value isnt null
if (!string.IsNullOrEmpty(paramStr))
{
paramStrings.Add(paramStr);
}
}

parameters.Append(string.Join("&", paramStrings.ToArray()));

return parameters.ToString();
}

// Serializes any object to the stream using standard XmlSerializer
// All rules and limitations of XmlSerializer serializer applies
private void ObjectToXMLStream<T>(T obj, Stream stream)
{
XmlSerializer xs = new XmlSerializer(typeof(T));
XmlTextWriter xmlTextWriter = new XmlTextWriter(stream, Encoding.UTF8);
xs.Serialize(xmlTextWriter, obj);
xmlTextWriter.Flush();
}

public T ExecuteCommand<T>(APICommand apiCommand, string parms)
{
return ExecuteCommand<object, T>(apiCommand, parms, null);
}

public void ExecuteCommand<K>(APICommand apiCommand, K request)
{
ExecuteCommand<K, object>(apiCommand, null, request);
}

public T ExecuteCommand<T>(APICommand apiCommand)
{
return ExecuteCommand<object, T>(apiCommand, null, null);
}

public T ExecuteCommand<K, T>(APICommand apiCommand, K postData)
{
return ExecuteCommand<K, T>(apiCommand, null, postData);
}

public Stream ExecuteCommand<K>(APICommand apiCommand, APIParam[] parms, K postData)
{
return ExecuteCommand<K>(apiCommand, MakeParameterPOSTString(parms), postData);
}

public T ExecuteCommand<K, T>(APICommand apiCommand, string parms, K postData)
{
Stream stream = ExecuteCommand<K>(apiCommand, parms, postData);
// Command that returns "void" will be called with generic type T set to "object"
// Such commands need to return null. All other calls should deserialize response stream
if ((typeof(T) == typeof(object)))
{
return default(T);
}
else if (typeof(T) == typeof(Stream))
{
MemoryStream result = new MemoryStream();
CopyStream(stream, result);
result.Position = 0;
return (T)((object)result);
}
else
{
XmlSerializer xs = new XmlSerializer(typeof(T));
return (T)xs.Deserialize(stream);
}
}

public Stream ExecuteCommand<K>(APICommand apiCommand, string parms, K postData)
{
Stream postDataStream = null;
// If posting data specified then serialize it using XmlSerializer and save it to the request stream
if (postData != null)
{
if (postData is Stream)
{
postDataStream = postData as Stream;
}
else
{
postDataStream = new MemoryStream();
ObjectToXMLStream(postData, postDataStream);
}
postDataStream.Position = 0;
}
return ExecuteCommandRaw(apiCommand, parms, postDataStream);
}

public Stream ExecuteCommandRaw(APICommand apiCommand, string parms, Stream postData)
{
// API command may have full URL with credentials already included
string fullUrl = GetFullUrl(apiCommand);
if (!string.IsNullOrEmpty(parms)) fullUrl += parms;
UriBuilder uri = new UriBuilder(fullUrl);

// Create a Web Request
HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(uri.ToString());

// Add access headers that identify developer and user account.
// Some API calls (like CreateAccount) require only DeveloperToken,
// but there is no harm in adding UserToken with empty data for these calls -
// so we are always adding both headers unconditionally rather then maintain list of
// API calls the require only one access token
if (!string.IsNullOrEmpty(UserToken)) httpRequest.Headers.Add(AuthHeaders.shipRush_User_Token, UserToken);
if (!string.IsNullOrEmpty(DeveloperToken)) httpRequest.Headers.Add(AuthHeaders.shipRush_Developer_Token, DeveloperToken);
if (!string.IsNullOrEmpty(ShippingToken)) httpRequest.Headers.Add(AuthHeaders.shipRush_Shipping_Token, ShippingToken);
if (!string.IsNullOrEmpty(SessionToken)) httpRequest.Headers.Add(AuthHeaders.shipRush_Session_Token, SessionToken);
if (ClientSdkVersion > 0) httpRequest.Headers.Add(AuthHeaders.shipRush_Version, ClientSdkVersion.ToString());

httpRequest.Method = apiCommand.Method;
httpRequest.ContentType = "application/xml";
httpRequest.UserAgent = UserAgent;

// The My.ShipRush api may (in the future) require that requesting systems support compression.
// Be sure to implement your system such that it accepts compressed responses.
if (EnableHttpCompression)
{
httpRequest.Headers["Accept-Encoding"] = "gzip, deflate";
}

// Getting "Only one usage of each socket address (protocol/network address/port) is normally permitted" under load?
// Read these articles
// http://blogs.msdn.com/dgorti/archive/2005/09/18/470766.aspx
// http://blog.magenic.com/blogs/jons/archive/2007/05/04/The-Tao-of-Microsoft-WCF-CustomBinding-Configuration-Elements.aspx
// http://blog.developers.ie/cgreen/archive/2007/04/24/2745.aspx

httpRequest.KeepAlive = false;
httpRequest.ProtocolVersion = HttpVersion.Version11;
httpRequest.Timeout = shipRushAPICallTimeout60Seconds;

if (postData != null)
{
using (Stream requestStream = httpRequest.GetRequestStream())
{
CopyStream(postData, requestStream);
}
}
else
{
if (apiCommand.Method == "POST")
httpRequest.ContentLength = 0;
}

// Performing HTTP command
try
{
using (WebResponse httpResponse = httpRequest.GetResponse())
{
Stream responseStream = httpResponse.GetResponseStream();
MemoryStream memoryStream = new MemoryStream();
CopyStream(responseStream, memoryStream);
memoryStream.Position = 0;
responseStream = memoryStream;

ContentEncoding = httpResponse.Headers["Content-Encoding"];
ContentEncoding = string.IsNullOrEmpty(ContentEncoding) ? "none" : ContentEncoding;
ContentLength = memoryStream.Length;

switch (ContentEncoding)
{
case "deflate":
responseStream = new DeflateStream((Stream)responseStream, CompressionMode.Decompress);
break;
case "gzip":
responseStream = new GZipStream((Stream)responseStream, CompressionMode.Decompress);
break;
default:
break;
}

Stream responseMemoryStream = new MemoryStream();
CopyStream(responseStream, responseMemoryStream);
responseMemoryStream.Position = 0;
return responseMemoryStream;
}
}
catch (WebException e)
{
if (e.Response != null) // Only do the parsing if there is a response from the server
{
using (StreamReader sr = new StreamReader(e.Response.GetResponseStream(), Encoding.UTF8))
{
XmlDocument doc = new XmlDocument() { XmlResolver = null }; // AH: Case 75013
try
{
doc.Load(sr);
}
catch (Exception)
{
// It appears that response is a non-XML document, just throw original error
// with added message text
using (StreamReader testReader = new StreamReader(e.Response.GetResponseStream(), Encoding.UTF8))
{
string responseText = testReader.ReadToEnd();
throw new ShipRushException(string.Format( "{0} {1} {2}", e.Message, responseText, fullUrl));
}
}
XmlNode responseNode = doc.SelectSingleNode("Error");
if (responseNode != null)
{
XmlNode errMsgNode = responseNode.SelectSingleNode("Message");
if (errMsgNode != null)
throw new ShipRushException( errMsgNode.InnerText );
}
throw new ShipRushException( e.Message );
}
}
// No response from ShipRush web service - generic HTTP error
throw new ApplicationException(string.Format("{0}. {1}", e.Message, fullUrl));
}
}

public string GetFullUrl(APICommand apiCommand)
{
return (string.IsNullOrEmpty(apiCommand.FullUrl))
?
ServiceUrl + apiCommand.ServiceUrl + "/" + apiCommand.CommandUrl
:
apiCommand.FullUrl;
}

private void CopyStream(Stream from, Stream to)
{
if (!from.CanRead)
{
throw new ArgumentException("from Stream must implement the Read method.");
}

if (!to.CanWrite)
{
throw new ArgumentException("to Stream must implement the Write method.");
}

const int SIZE = 1024 * 1024;
byte[] buffer = new byte[SIZE];

int read = 0;
while ((read = from.Read(buffer, 0, buffer.Length)) > 0)
{
to.Write(buffer, 0, read);
}
}

public void PushFileAsDownload(string contentType, Stream content, string filename, HttpResponse response)
{
response.ContentType = contentType;
response.AppendHeader("Content-Disposition", "attachment; filename=" + filename);
Serialization.CopyStream(content, response.OutputStream);
response.End();
}
}
}

Transient

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Text;
using System.Web;
using System.Xml;
using System.Xml.Serialization;
using ShipRush.SDK.Proxies;
using ShipRush.SDK.Utils;

namespace ShipRush.SDK.Transport
{
public class ShipRushSDKTransient
{
public string ServiceUrl { get; set; }

public string DeveloperToken { get; set; }
public string UserToken { get; set; }
public string SessionToken { get; set; }
public int ClientSdkVersion { get; set; }
public bool EnableHttpCompression { get; set; } // It is important to use http compression !

private const int shipRushAPICallTimeout60Seconds = 60 * 1000;

public string ContentEncoding { get; set; }
public long ContentLength { get; set; }

public ShipRushSDKTransient()
{
ClientSdkVersion = SdkVersion.Current;
EnableHttpCompression = true;
SetIsProduction(false);
}

public void SetIsProduction(bool isProduction)
{
ServiceUrl = isProduction ? "http://api.my.shiprush.com/" : "http://sandbox.api.my.shiprush.com/";
}

/// <summary>
/// Makes the parameter POST string.
/// </summary>
/// <param name="parms">The Parameters.</param>
/// <returns>The paremeters ready for a http post.</returns>
private string MakeParameterPOSTString(APIParam[] parms)
{
if (parms == null) return "";

StringBuilder parameters = new StringBuilder();
List<string> paramStrings = new List<string>();

// Put all of the parameters in query string form.
foreach (APIParam parm in parms)
{
string paramStr = parm.ToString();

// Only add the parameter if the value isnt null
if (!string.IsNullOrEmpty(paramStr))
{
paramStrings.Add(paramStr);
}
}

parameters.Append(string.Join("&", paramStrings.ToArray()));

return parameters.ToString();
}

// Serializes any object to the stream using standard XmlSerializer
// All rules and limitations of XmlSerializer serializer applies
private void ObjectToXMLStream<T>(T obj, Stream stream)
{
XmlSerializer xs = new XmlSerializer(typeof(T));
XmlTextWriter xmlTextWriter = new XmlTextWriter(stream, Encoding.UTF8);
xs.Serialize(xmlTextWriter, obj);
xmlTextWriter.Flush();
}

public T ExecuteCommand<T>(APICommand apiCommand, string parms)
{
return ExecuteCommand<object, T>(apiCommand, parms, null);
}

public void ExecuteCommand<K>(APICommand apiCommand, K request)
{
ExecuteCommand<K, object>(apiCommand, null, request);
}

public T ExecuteCommand<T>(APICommand apiCommand)
{
return ExecuteCommand<object, T>(apiCommand, null, null);
}

public T ExecuteCommand<K, T>(APICommand apiCommand, K postData)
{
return ExecuteCommand<K, T>(apiCommand, null, postData);
}

public Stream ExecuteCommand<K>(APICommand apiCommand, APIParam[] parms, K postData)
{
return ExecuteCommand<K>(apiCommand, MakeParameterPOSTString(parms), postData);
}

public T ExecuteCommand<K, T>(APICommand apiCommand, string parms, K postData)
{
Stream stream = ExecuteCommand<K>(apiCommand, parms, postData);
// Command that returns "void" will be called with generic type T set to "object"
// Such commands need to return null. All other calls should deserialize response stream
if ((typeof(T) == typeof(object)))
{
return default(T);
}
else if (typeof(T) == typeof(Stream))
{
MemoryStream result = new MemoryStream();
CopyStream(stream, result);
result.Position = 0;
return (T)((object)result);
}
else
{
XmlSerializer xs = new XmlSerializer(typeof(T));
return (T)xs.Deserialize(stream);
}
}

public Stream ExecuteCommand<K>(APICommand apiCommand, string parms, K postData)
{
Stream postDataStream = null;
// If posting data specified then serialize it using XmlSerializer and save it to the request stream
if (postData != null)
{
if (postData is Stream)
{
postDataStream = postData as Stream;
}
else
{
postDataStream = new MemoryStream();
ObjectToXMLStream(postData, postDataStream);
}
postDataStream.Position = 0;
}
return ExecuteCommandRaw(apiCommand, parms, postDataStream);
}

public Stream ExecuteCommandRaw(APICommand apiCommand, string parms, Stream postData)
{
// API command may have full URL with credentials already included
string fullUrl = GetFullUrl(apiCommand);
if (!string.IsNullOrEmpty(parms)) fullUrl += parms;
UriBuilder uri = new UriBuilder(fullUrl);

// Create a Web Request
HttpWebRequest httpRequest = (HttpWebRequest)WebRequest.Create(uri.ToString());

// Add access headers that identify developer and user account.
// Some API calls (like CreateAccount) require only DeveloperToken,
// but there is no harm in adding UserToken with empty data for these calls -
// so we are always adding both headers unconditionally rather then maintain list of
// API calls the require only one access token
if (!string.IsNullOrEmpty(UserToken)) httpRequest.Headers.Add(AuthHeaders.shipRush_User_Token, UserToken);
if (!string.IsNullOrEmpty(DeveloperToken)) httpRequest.Headers.Add(AuthHeaders.shipRush_Developer_Token, DeveloperToken);
if (!string.IsNullOrEmpty(SessionToken)) httpRequest.Headers.Add(AuthHeaders.shipRush_Session_Token, SessionToken);
if (ClientSdkVersion > 0) httpRequest.Headers.Add(AuthHeaders.shipRush_Version, ClientSdkVersion.ToString());

httpRequest.Method = apiCommand.Method;
httpRequest.ContentType = "application/xml";

// The My.ShipRush api may (in the future) require that requesting systems support compression.
// Be sure to implement your system such that it accepts compressed responses.
if (EnableHttpCompression)
{
httpRequest.Headers["Accept-Encoding"] = "gzip, deflate";
}

// Getting "Only one usage of each socket address (protocol/network address/port) is normally permitted" under load?
// Read these articles
// http://blogs.msdn.com/dgorti/archive/2005/09/18/470766.aspx
// http://blog.magenic.com/blogs/jons/archive/2007/05/04/The-Tao-of-Microsoft-WCF-CustomBinding-Configuration-Elements.aspx
// http://blog.developers.ie/cgreen/archive/2007/04/24/2745.aspx

httpRequest.KeepAlive = false;
httpRequest.ProtocolVersion = HttpVersion.Version11;
httpRequest.Timeout = shipRushAPICallTimeout60Seconds;

if (postData != null)
{
using (Stream requestStream = httpRequest.GetRequestStream())
{
CopyStream(postData, requestStream);
}
}

// Performing HTTP command
try
{
using (WebResponse httpResponse = httpRequest.GetResponse())
{
Stream responseStream = httpResponse.GetResponseStream();
MemoryStream memoryStream = new MemoryStream();
CopyStream(responseStream, memoryStream);
memoryStream.Position = 0;
responseStream = memoryStream;

ContentEncoding = httpResponse.Headers["Content-Encoding"];
ContentEncoding = string.IsNullOrEmpty(ContentEncoding) ? "none" : ContentEncoding;
ContentLength = memoryStream.Length;

switch (ContentEncoding)
{
case "deflate":
responseStream = new DeflateStream((Stream)responseStream, CompressionMode.Decompress);
break;
case "gzip":
responseStream = new GZipStream((Stream)responseStream, CompressionMode.Decompress);
break;
default:
break;
}

Stream responseMemoryStream = new MemoryStream();
CopyStream(responseStream, responseMemoryStream);
responseMemoryStream.Position = 0;
return responseMemoryStream;
}
}
catch (WebException e)
{
// There is a response from the server
if (e.Response != null)
{
using (StreamReader sr = new StreamReader(e.Response.GetResponseStream(), Encoding.UTF8))
{
var response = sr.ReadToEnd();
XmlDocument doc = new XmlDocument() { XmlResolver = null }; // AH: Case 75013
try
{
doc.LoadXml(response);
}
catch (Exception)
{
// It appears that response is a non-XML document, just throw original error
// with added message text
throw new ShipRushException(string.Format("{0} {1} {2}", e.Message, response, fullUrl));
}
XmlNode responseNode = doc.SelectSingleNode("Error");
if (responseNode != null)
{
XmlNode errMsgNode = responseNode.SelectSingleNode("Message");
if (errMsgNode != null)
throw new ShipRushException(errMsgNode.InnerText);
}
throw new ShipRushException(e.Message);
}
}
// No response from ShipRush web service - generic HTTP error
throw new ApplicationException(string.Format("{0}. {1}", e.Message, fullUrl));
}
}

public string GetFullUrl(APICommand apiCommand)
{
return (string.IsNullOrEmpty(apiCommand.FullUrl))
? ServiceUrl + apiCommand.ServiceUrl + "/" + apiCommand.CommandUrl
: apiCommand.FullUrl;
}

private void CopyStream(Stream from, Stream to)
{
if (!from.CanRead)
{
throw new ArgumentException("from Stream must implement the Read method.");
}

if (!to.CanWrite)
{
throw new ArgumentException("to Stream must implement the Write method.");
}

const int SIZE = 1024 * 1024;
byte[] buffer = new byte[SIZE];

int read = 0;
while ((read = from.Read(buffer, 0, buffer.Length)) > 0)
{
to.Write(buffer, 0, read);
}
}

#if !MONO

public void PushFileAsDownload(string contentType, Stream content, string filename, HttpResponse response)
{
response.ContentType = contentType;
response.AppendHeader("Content-Disposition", "attachment; filename=" + filename);
Serialization.CopyStream(content, response.OutputStream);
response.End();
}

#endif

}
}

Exceptions

using System;

namespace ShipRush.SDK.Transport
{
public class ShipRushException : ApplicationException
{
public ShipRushException(string message) : base(message) { }
}

}

Csproj

SDK

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{2920785A-C8A0-4E9B-A432-67A2EB866C17}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ShipRush.SDK</RootNamespace>
<AssemblyName>ShipRush.SDK</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<SccProjectName>SAK</SccProjectName>
<SccLocalPath>SAK</SccLocalPath>
<SccAuxPath>SAK</SccAuxPath>
<SccProvider>SAK</SccProvider>
<FileUpgradeFlags>
</FileUpgradeFlags>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>3.5</OldToolsVersion>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Certification|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\Certification\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<CodeAnalysisLogFile>bin\Debug\ShipRush.SDK.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
<CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
<CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
<CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
<WarningLevel>4</WarningLevel>
<Optimize>false</Optimize>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Newtonsoft.Json.10.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Transport\APIError.cs" />
<Compile Include="Transport\ShipRushSDK_ThreadSafe.cs" />
<Compile Include="Transport\APICommand.cs" />
<Compile Include="Transport\APICommands.cs" />
<Compile Include="Transport\APIParam.cs" />
<Compile Include="Transport\ShipRushException.cs" />
<Compile Include="Transport\ShipRushSDK.cs" />
<Compile Include="Transport\ShipRushSDKTransient.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ShipRush.SDK.Proxies\ShipRush.SDK.Proxies.csproj">
<Project>{8CE19038-AC9D-46FF-8EF3-A7BA50BF5E1D}</Project>
<Name>ShipRush.SDK.Proxies</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

SDK Vspscc

""
{
"FILE_VERSION" = "9237"
"ENLISTMENT_CHOICE" = "NEVER"
"PROJECT_FILE_RELATIVE_PATH" = ""
"NUMBER_OF_EXCLUDED_FILES" = "0"
"ORIGINAL_PROJECT_FILE_PATH" = ""
"NUMBER_OF_NESTED_PROJECTS" = "0"
"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
}

NET35

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ShipRush.SDK</RootNamespace>
<AssemblyName>ShipRush.SDK</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<OldToolsVersion>3.5</OldToolsVersion>
<TargetFrameworkProfile />
<ProjectGuid>{D9799DD6-3111-4AC9-BFA4-F81C534BA489}</ProjectGuid>
<SccProjectName>SAK</SccProjectName>
<SccLocalPath>SAK</SccLocalPath>
<SccAuxPath>SAK</SccAuxPath>
<SccProvider>SAK</SccProvider>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\NETFX_35\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\NETFX_35\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Certification|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\NETFX_35\Certification\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<CodeAnalysisLogFile>bin\Debug\ShipRush.SDK.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
<CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
<CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
<CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
<WarningLevel>4</WarningLevel>
<Optimize>false</Optimize>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\Newtonsoft.Json.10.0.2\lib\net35\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Transport\APIError.cs" />
<Compile Include="Transport\ShipRushSDK_ThreadSafe.cs" />
<Compile Include="Transport\APICommand.cs" />
<Compile Include="Transport\APICommands.cs" />
<Compile Include="Transport\APIParam.cs" />
<Compile Include="Transport\ShipRushException.cs" />
<Compile Include="Transport\ShipRushSDK.cs" />
<Compile Include="Transport\ShipRushSDKTransient.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ShipRush.SDK.Proxies\ShipRush.SDK.Proxies.NET35.csproj">
<Project>{900c7dfc-6452-4ac7-b34b-a5612704d0c2}</Project>
<Name>ShipRush.SDK.Proxies.NET35</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

NET35 Vspscc

""
{
"FILE_VERSION" = "9237"
"ENLISTMENT_CHOICE" = "NEVER"
"PROJECT_FILE_RELATIVE_PATH" = "relative:ShipRush.SDK"
"NUMBER_OF_EXCLUDED_FILES" = "0"
"ORIGINAL_PROJECT_FILE_PATH" = ""
"NUMBER_OF_NESTED_PROJECTS" = "0"
"SOURCE_CONTROL_SETTINGS_PROVIDER" = "PROVIDER"
}

OSX

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{2920785A-C8A0-4E9B-A432-67A2EB866C17}</ProjectGuid>
<ProjectTypeGuids>{A3F8F2AB-B479-4A4A-A458-A89E7DC349F1};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ShipRush.SDK</RootNamespace>
<AssemblyName>ShipRush.SDK</AssemblyName>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<TargetFrameworkIdentifier>Xamarin.Mac</TargetFrameworkIdentifier>
<FileAlignment>512</FileAlignment>
<OldToolsVersion>3.5</OldToolsVersion>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>__UNIFIED__;__MACOS__;DEBUG;TRACE;MONO</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<UseSGen>false</UseSGen>
<AOTMode>None</AOTMode>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>__UNIFIED__;__MACOS__;TRACE;MONO</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<UseSGen>false</UseSGen>
<AOTMode>None</AOTMode>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Certification|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\Certification\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<DebugType>full</DebugType>
<PlatformTarget>AnyCPU</PlatformTarget>
<CodeAnalysisLogFile>bin\Debug\ShipRush.SDK.dll.CodeAnalysisLog.xml</CodeAnalysisLogFile>
<CodeAnalysisUseTypeNameInSuppression>true</CodeAnalysisUseTypeNameInSuppression>
<CodeAnalysisModuleSuppressionsFile>GlobalSuppressions.cs</CodeAnalysisModuleSuppressionsFile>
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<CodeAnalysisRuleSetDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\\Rule Sets</CodeAnalysisRuleSetDirectories>
<CodeAnalysisIgnoreBuiltInRuleSets>true</CodeAnalysisIgnoreBuiltInRuleSets>
<CodeAnalysisRuleDirectories>;C:\Program Files (x86)\Microsoft Visual Studio 10.0\Team Tools\Static Analysis Tools\FxCop\\Rules</CodeAnalysisRuleDirectories>
<CodeAnalysisIgnoreBuiltInRules>true</CodeAnalysisIgnoreBuiltInRules>
<WarningLevel>4</WarningLevel>
<Optimize>false</Optimize>
<UseSGen>false</UseSGen>
<AOTMode>None</AOTMode>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="System.Web.Services" />
<Reference Include="Newtonsoft.Json">
<HintPath>..\ShipRush.Desktop.Toolbox\packages\Newtonsoft.Json.12.0.3\lib\netstandard2.0\Newtonsoft.Json.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Transport\APICommand.cs" />
<Compile Include="Transport\APICommands.cs" />
<Compile Include="Transport\APIParam.cs" />
<Compile Include="Transport\ShipRushException.cs" />
<Compile Include="Transport\ShipRushSDK.cs" />
<Compile Include="Transport\ShipRushSDKTransient.cs" />
<Compile Include="Transport\APIError.cs" />
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Mac\Xamarin.Mac.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<ItemGroup>
<ProjectReference Include="..\ShipRush.SDK.Proxies\ShipRush.SDK.Proxies.OSX.csproj">
<Project>{8CE19038-AC9D-46FF-8EF3-A7BA50BF5E1D}</Project>
<Name>ShipRush.SDK.Proxies.OSX</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
</Project>

Back to Top