diff --git a/Samples/6.WebAPI/Program.cs b/Samples/6.WebAPI/Program.cs index 3f0c46738..9efdb6761 100644 --- a/Samples/6.WebAPI/Program.cs +++ b/Samples/6.WebAPI/Program.cs @@ -92,10 +92,15 @@ static void Main( string[] args ) // you can call interface functions through a Call method using ( WebAPI.Interface steamNews = WebAPI.GetInterface( "ISteamNews" ) ) { - Dictionary newsArgs = new Dictionary(); + Dictionary newsArgs = new Dictionary(); newsArgs[ "appid" ] = "440"; KeyValue results = steamNews.Call( "GetNewsForApp", /* version */ 1, newsArgs ); + + foreach ( KeyValue news in results[ "newsitems" ][ "newsitem" ].Children ) + { + Console.WriteLine( "News: {0}", news[ "title" ].AsString() ); + } } } } diff --git a/SteamKit2/SteamKit2/Steam/WebAPI/SteamDirectory.cs b/SteamKit2/SteamKit2/Steam/WebAPI/SteamDirectory.cs index 338463b92..bff980991 100644 --- a/SteamKit2/SteamKit2/Steam/WebAPI/SteamDirectory.cs +++ b/SteamKit2/SteamKit2/Steam/WebAPI/SteamDirectory.cs @@ -48,7 +48,7 @@ static async Task> LoadCoreAsync( SteamConfigu } var directory = configuration.GetAsyncWebAPIInterface( "ISteamDirectory" ); - var args = new Dictionary + var args = new Dictionary { ["cellid"] = configuration.CellID.ToString( CultureInfo.InvariantCulture ) }; diff --git a/SteamKit2/SteamKit2/Steam/WebAPI/WebAPI.cs b/SteamKit2/SteamKit2/Steam/WebAPI/WebAPI.cs index cdce8043c..78369142f 100644 --- a/SteamKit2/SteamKit2/Steam/WebAPI/WebAPI.cs +++ b/SteamKit2/SteamKit2/Steam/WebAPI/WebAPI.cs @@ -11,6 +11,7 @@ using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; +using System.Web; namespace SteamKit2 { @@ -67,7 +68,7 @@ internal Interface( HttpClient httpClient, string iface, string apiKey ) /// An network error occurred when performing the request. /// A network error occurred when performing the request. /// An error occured when parsing the response from the WebAPI. - public KeyValue Call( string func, int version = 1, Dictionary args = null ) + public KeyValue Call( string func, int version = 1, Dictionary args = null ) => Call( HttpMethod.Get, func, version, args ); @@ -83,7 +84,7 @@ public KeyValue Call( string func, int version = 1, Dictionary a /// An network error occurred when performing the request. /// A network error occurred when performing the request. /// An error occured when parsing the response from the WebAPI. - public KeyValue Call( HttpMethod method, string func, int version = 1, Dictionary args = null ) + public KeyValue Call( HttpMethod method, string func, int version = 1, Dictionary args = null ) { var callTask = asyncInterface.CallAsync( method, func, version, args ); @@ -209,7 +210,7 @@ internal AsyncInterface( HttpClient httpClient, string iface, string apiKey ) /// An network error occurred when performing the request. /// A network error occurred when performing the request. /// An error occured when parsing the response from the WebAPI. - public Task CallAsync( HttpMethod method, string func, int version = 1, Dictionary args = null ) + public Task CallAsync( HttpMethod method, string func, int version = 1, Dictionary args = null ) { var task = CallAsyncCore( method, func, version, args ); @@ -226,7 +227,7 @@ public Task CallAsync( HttpMethod method, string func, int version = 1 return task; } - async Task CallAsyncCore( HttpMethod method, string func, int version = 1, Dictionary args = null ) + async Task CallAsyncCore( HttpMethod method, string func, int version = 1, Dictionary args = null ) { if ( method == null ) { @@ -240,7 +241,7 @@ async Task CallAsyncCore( HttpMethod method, string func, int version if ( args == null ) { - args = new Dictionary(); + args = new Dictionary(); } @@ -268,11 +269,21 @@ async Task CallAsyncCore( HttpMethod method, string func, int version // append any args paramBuilder.Append( string.Join( "&", args.Select( kvp => { - // TODO: the WebAPI is a special snowflake that needs to appropriately handle url encoding - // this is in contrast to the steam3 content server APIs which use an entirely different scheme of encoding + string key = HttpUtility.UrlEncode( kvp.Key ); + string value; - string key = WebHelpers.UrlEncode( kvp.Key ); - string value = kvp.Value; // WebHelpers.UrlEncode( kvp.Value ); + if ( kvp.Value == null ) + { + value = string.Empty; + } + else if ( kvp.Value is byte[] buffer ) + { + value = HttpUtility.UrlEncode( buffer ); + } + else + { + value = HttpUtility.UrlEncode( kvp.Value.ToString() ); + } return string.Format( "{0}={1}", key, value ); } ) ) ); @@ -360,7 +371,7 @@ public override bool TryInvokeMember( InvokeMemberBinder binder, object[] args, throw new InvalidOperationException( "Argument mismatch in API call. All parameters must be passed as named arguments." ); } - var apiArgs = new Dictionary(); + var apiArgs = new Dictionary(); var requestMethod = HttpMethod.Get; @@ -384,14 +395,14 @@ public override bool TryInvokeMember( InvokeMemberBinder binder, object[] args, foreach ( object value in enumerable ) { - apiArgs.Add( String.Format( "{0}[{1}]", argName, index++ ), value.ToString() ); + apiArgs.Add( String.Format( "{0}[{1}]", argName, index++ ), value ); } continue; } - apiArgs.Add( argName, argValue.ToString() ); + apiArgs.Add( argName, argValue ); } Match match = funcNameRegex.Match( binder.Name );