I'm new to C# programming, and am learning as I go.
I'm working on a program to test whether a computer can connect to specific servers and ports.
I got the program itself working fine, when the list of servers and ports were hard coded into it.
I worked on a separate project to connect to an AWS S3 bucket and get the list of server addresses from a file there and load them into a dictionary. That worked fine.
But when I try to move the function in that project to my main project, if I call it, the program wont load, but there is also no error in the console log.
Here is the source code, with the working functions removed temporarily.
What it should do is when ran, run the ReadObjectDataAsync, with the specified s3 object name, and dictionary name, so that it preloads the info into the 3 specified dictionaries.
If I comment out the 3 ReadObjectDataAsync lines, the program runs as expected. If I leave them in, the program builds, is shown in task manager, but the window never actually opens.
I know the ReadObjectDataAsync function works, as it works in its own project
using System;
using System.Windows;
using System.Net.Sockets;
using System.Xml;
using System.IO;
using System.Linq;
using Amazon.S3.Model;
using Amazon.S3;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace ConnectionChecker
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public static string PublicKey = "PUBKEYHERE";
public static string SecretKey = "SECKEYHERE";
public static Dictionary<string, string> stream_servers = new Dictionary<string, string>();
public static Dictionary<string, string> other_servers = new Dictionary<string, string>();
public static Dictionary<string, string> ports = new Dictionary<string, string>();
public static AmazonS3Client s3Client = new AmazonS3Client(PublicKey, SecretKey, Amazon.RegionEndpoint.USEast1);
public MainWindow()
{
InitializeComponent();
ReadObjectDataAsync("streamservers.conf", stream_servers).Wait();
ReadObjectDataAsync("ports.conf", ports).Wait();
ReadObjectDataAsync("servers.conf", other_servers).Wait();
if (stream_servers.Count > 0)
{
ProgramStatus.Text = "Loaded";
}
}
public void Button_Click(object sender, RoutedEventArgs e)
{
//run through connection test and display results on form.
}
static async Task ReadObjectDataAsync(string itemname, Dictionary<string, string> listname)
{
string responseBody = "";
try
{
GetObjectRequest request = new GetObjectRequest
{
BucketName = "bucketname",
Key = itemname
};
using (GetObjectResponse response = await s3Client.GetObjectAsync(request))
using (Stream responseStream = response.ResponseStream)
using (StreamReader reader = new StreamReader(responseStream))
{
responseBody = reader.ReadToEnd(); // Now you process the response body.
string[] result = responseBody.Split("\n\r".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
//Console.WriteLine("Lines: " + result.Count());
foreach (string line in result)
{
string[] words = line.Split("::");
listname.Add(words[0], words[1]);
}
//Console.WriteLine(responseBody);
}
}
catch (AmazonS3Exception e)
{
// If bucket or object does not exist
Console.WriteLine("Error encountered ***. Message:'{0}' when reading object", e.Message);
}
catch (Exception e)
{
Console.WriteLine("Unknown encountered on server. Message:'{0}' when reading object", e.Message);
}
}
}
}
Related
I have a weird error in Redis on .Net 6. When I run the test code here:
https://github.com/redis-developer/redis-graph-dotnet-basic-app/blob/main/Program.cs
It works perfectly fine. In this case the code is running in the program.cs file.
When I port that code to a class, in order to better manage encapsulation and complexity. It does not work. What it does is run the code and when it gets to the: await graph.QueryAsync part, it just stops the debugger. Very strange indeed.
Here is the code I am using. Any thoughts or suggestions:
//Program.cs (Relevant Bits)
using RedisTest //PROGRAM //WRITE TO REDIS ENTERPRISE CLOUD Process_LoadGraph process_LoadGraph = new Process_LoadGraph(); process_LoadGraph.Controller(results);
//SHARED CONNECTION CLASS
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StackExchange.Redis;
namespace RedisTest
{
public class RedisSharedConnection
{
public static ConnectionMultiplexer Connection
{
get
{
return lazyConnection.Value;
}
}
private static Lazy<ConnectionMultiplexer> lazyConnection = new Lazy<ConnectionMultiplexer>(() =>
{
ConnectionMultiplexer connectionMultiplexer = ConnectionMultiplexer.Connect(ConfigData.dbConnectionString);
return connectionMultiplexer;
});
}
}
//USAGE CLASS
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using NRedisGraph;
namespace RedisTest
{
public class Process_LoadGraph
{
public async void Controller(List<Result> results)
{
//Setup
var redisConnection = RedisSharedConnection.Connection;
//var redisConnection = ConnectionMultiplexer.Connect(ConfigData.dbConnectionString);
var db = redisConnection.GetDatabase(ConfigData.dbId);
var graph = new RedisGraph(db);
string graphName = ConfigData.graphName;
//Test Transaction
// Create Bob
// CRASHES HERE
var createBobResult = await graph.QueryAsync("pets", "MERGE(:human{name:'Bob',age:32})");
}
}
}
Turns out the solution is to use Redis in a static class. Along the following lines:
internal static class WriteToDB
{
public static async Task WriteAsync(List<string> querieS)
{
//Load Graph
//Setup
var redisConnection = RedisSharedConnection.Connection;
//var redisConnection = ConnectionMultiplexer.Connect(ConfigData.dbConnectionString);
var db = redisConnection.GetDatabase(ConfigData.dbId);
var graph = new RedisGraph(db);
string graphName = ConfigData.graphName;
// ** DEBUG
//Test Transaction
// Create Bob
var createBobResult = await graph.QueryAsync("pets", "MERGE(:human{name:'Bob',age:32})");
{ }
//Clear Graph
await graph.QueryAsync(graphName, "MATCH(n) DETACH DELETE n");
{ }
}
}
I need to use another company's API to query data using POST requests.
The API works (= I receive all the data with no errors) when I query it from the swagger website using the UI, but when I do it from my C# program I get a 500 Internal Server Error.
Where should I be looking for the problem ? Is there a way to get a more detailed error message ?
Edit (added code) :
using System;
using System.Data.Entity;
using System.Data.Entity.Core.Mapping;
using System.Data.Entity.Core.Metadata.Edm;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Infrastructure.Interception;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Runtime.Serialization;
using System.Text;
namespace credex_distribution_offers_to_interfaces
{
class Program
{
private const string jsonMediaType = "application/json";
static void Main()
{
FetchJSONAndInsertToDB();
}
private static bool FetchJSONAndInsertToDB()
{
var baseServiceUrl = new Uri("a valid url");
Root rootObject;
using (var httpClient = new HttpClient())
{
httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(jsonMediaType));
try
{
string token = FetchToken(httpClient, baseServiceUrl);
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(token);
}
catch (Exception e)
{
return false;
}
try
{
rootObject = FetchDistributionLookupOffers(httpClient, baseServiceUrl, 29612, 29613, 29614, 29617, 29621);
}
catch (Exception e)
{
return false;
}
}
// database related stuff...
// ...
return true;
}
[DataContract]
public class MortgageForDistributionLookupInputDto
{
public int[] OfferNumbers { get; set; }
}
private static Root FetchDistributionLookupOffers(HttpClient aHttpClient, Uri aBaseServiceUrl, params int[] aOfferNumbers)
{
var input = new MortgageForDistributionLookupInputDto()
{
OfferNumbers = aOfferNumbers
};
var lookup = aHttpClient.PostAsync(new Uri(aBaseServiceUrl, "v1/MortgageDetails/InvestorLookupOffers"), PayloadFor(input)).Result;
if (lookup.StatusCode != HttpStatusCode.OK)
{
throw new Exception("Fetching investor lookup offers failed with HTTP status code '" + lookup.StatusCode + "' : " + lookup.ReasonPhrase + "}");
}
var obj = ValueFor<Root>(lookup.Content);
return obj;
}
private static HttpContent PayloadFor<T>(T aObject)
{
return new StringContent(aObject.SerializeJson(), Encoding.UTF8, jsonMediaType);
}
private static T ValueFor<T>(HttpContent aHttpContent)
{
//var content = aHttpContent.ReadAsStringAsync();
return aHttpContent.ReadAsStreamAsync().Result.DeSerializeJson<T>();
}
private static string FetchToken(HttpClient aHttpClient, Uri aBaseServiceUrl)
{
var login = new LoginRequest()
{
UserName = "some user name",
Password = "some password"
};
var authResult = aHttpClient.PostAsync(new Uri(aBaseServiceUrl, "api/Login"), PayloadFor(login)).Result;
if (authResult.StatusCode != HttpStatusCode.OK)
{
throw new Exception("Fetching authentication token failed. Reason : " + authResult.StatusCode + " -> " + authResult.ReasonPhrase);
}
return authResult.Content.ReadAsStringAsync().Result.Trim('"');
}
}
}
I take data from Bittrex without WebSocket by this way
request = WebRequest.Create("https://bittrex.com/api/v1.1/public/getticker?market=USDT-BTC");
request.Credentials = CredentialCache.DefaultCredentials;
response = (HttpWebResponse)request.GetResponse();
dataStream = response.GetResponseStream();
reader = new StreamReader(dataStream);
responseFromServer = reader.ReadToEnd();
reader.Close();
dataStream.Close();
response.Close();
date = JsonConvert.DeserializeObject(responseFromServer);
It is very easy way and it is working on Bittrex. But I did a lot off request. I need do it on Bitfinex but I have the exeption "Too many request". As I understood I need WebSocket for this. By this adress https://api.bitfinex.com/v1/pubticker/BTCUSD. Somebody can show easy code to understand how I need to conect and write in Console info from WebSocket. Thanks!
BIttrex release in March beta version of new site and WebSocket. GitHub repository have samples for usage WebSocket channel to subscribe for events.
Here is C# example:
using System;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.IO.Compression;
using System.Security.Cryptography;
using Microsoft.AspNet.SignalR.Client;
namespace WebsocketSample
{
public sealed class BittrexWebsocket
{
public delegate void BittrexCallback(string info);
private HubConnection _hubConnection { get; }
private IHubProxy _hubProxy { get; }
private BittrexCallback _updateExchangeState { get; }
private BittrexCallback _updateOrderState { get; }
private BittrexCallback _updateBalanceState { get; }
public BittrexWebsocket(
string connectionUrl,
BittrexCallback updateExchangeState,
BittrexCallback updateOrderState,
BittrexCallback updateBalanceState
)
{
// Set delegates
_updateExchangeState = updateExchangeState;
_updateOrderState = updateOrderState;
_updateBalanceState = updateBalanceState;
// Create connection to c2 SignalR hub
_hubConnection = new HubConnection(connectionUrl);
_hubProxy = _hubConnection.CreateHubProxy("c2");
// Register callback for uE (exchange state delta) events
_hubProxy.On(
"uE",
exchangeStateDelta => _updateExchangeState?.Invoke(exchangeStateDelta)
);
// Register callback for uO (order status change) events
_hubProxy.On(
"uO",
orderStateDelta => _updateOrderState?.Invoke(orderStateDelta)
);
// Register callback for uB (balance status change) events
_hubProxy.On(
"uB",
balanceStateDelta => _updateBalanceState?.Invoke(balanceStateDelta)
);
_hubConnection.Start().Wait();
}
public void Shutdown() => _hubConnection.Stop();
// marketName example: "BTC-LTC"
public async Task<bool> SubscribeToExchangeDeltas(string marketName) => await _hubProxy.Invoke<bool>("SubscribeToExchangeDeltas", marketName);
// The return of GetAuthContext is a challenge string. Call CreateSignature(apiSecret, challenge)
// for the response to the challenge, and pass it to Authenticate().
public async Task<string> GetAuthContext(string apiKey) => await _hubProxy.Invoke<string>("GetAuthContext", apiKey);
public async Task<bool> Authenticate(string apiKey, string signedChallenge) => await _hubProxy.Invoke<bool>("Authenticate", apiKey, signedChallenge);
// Decode converts Bittrex CoreHub2 socket wire protocol data into JSON.
// Data goes from base64 encoded to gzip (byte[]) to minifed JSON.
public static string Decode(string wireData)
{
// Step 1: Base64 decode the wire data into a gzip blob
byte[] gzipData = Convert.FromBase64String(wireData);
// Step 2: Decompress gzip blob into minified JSON
using (var decompressedStream = new MemoryStream())
using (var compressedStream = new MemoryStream(gzipData))
using (var deflateStream = new DeflateStream(compressedStream, CompressionMode.Decompress))
{
deflateStream.CopyTo(decompressedStream);
decompressedStream.Position = 0;
using (var streamReader = new StreamReader(decompressedStream))
{
return streamReader.ReadToEnd();
}
}
}
public static string CreateSignature(string apiSecret, string challenge)
{
// Get hash by using apiSecret as key, and challenge as data
var hmacSha512 = new HMACSHA512(Encoding.ASCII.GetBytes(apiSecret));
var hash = hmacSha512.ComputeHash(Encoding.ASCII.GetBytes(challenge));
return BitConverter.ToString(hash).Replace("-", string.Empty);
}
}
class Program
{
static public BittrexWebsocket.BittrexCallback CreateCallback(string name)
{
//
// In a real app, your code would do something useful based on the
// information accompanying each event.
//
return (info) =>
{
Console.WriteLine($"Callback Invoked: {name}");
Console.WriteLine(
BittrexWebsocket.Decode(info)
);
};
}
static void Main(string[] args)
{
Task task = Task.Run(
async () =>
{
string apiKey = "YOUR_API_KEY";
string apiSecret = "YOUR_API_SECRET";
string baseUrl = "https://beta.bittrex.com/signalr";
var btx = new BittrexWebsocket(
baseUrl,
CreateCallback("exchange"),
CreateCallback("order"),
CreateCallback("balance")
);
// If we successfully authenticate, we'll be subscribed to the uO and uB events.
var isAuthenticated = await btx.Authenticate(
apiKey,
BittrexWebsocket.CreateSignature(apiSecret, await btx.GetAuthContext(apiKey))
);
// Register for orderbook updates on the BTC-ETH market
await btx.SubscribeToExchangeDeltas("BTC-ETH");
});
task.Wait();
Console.WriteLine("Press enter to exit sample...");
Console.ReadLine();
}
}
}
Run in PackageManager Console to add SignalR dependency:
Install-Package Microsoft.AspNet.SignalR.Client -Version 2.3.0
Also to connect you need get Key and Secret from your account on Bittrex.
string apiKey = "YOUR_API_KEY";
string apiSecret = "YOUR_API_SECRET";
For Bitfinex you can try next code:
using System;
using WebSocketSharp;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
using (var ws = new WebSocket("wss://api.bitfinex.com/ws/2"))
{
ws.OnMessage += (sender, e) => Console.WriteLine(e.Data);
ws.Connect();
ws.Send("{\"event\":\"subscribe\", \"channel\":\"ticker\", \"pair\":\"BTCUSD\"}");
Console.ReadKey(true);
}
}
}
}
Requires dependency from Nuget:
Install-Package WebSocketSharp-NonPreRelease -Version 1.0.0
I'm trying to do a webrequest from my C# Windows application to my website,
but the desired result is empty or null when called only from C# but not from website where it works as expected.
Before I do my request, I need to begin with a login request which works as expected and does indeed return the correct value.
IMPORTANT EDIT:
I tried to copypaste my PHP code in to my login.php file and it does work in C# and returns the correct count-value.
Is my HttpClient not properly configured maybe?
My PHP test code looks as following:
<?php
session_start();
if(!isset($_SESSION['user'])){ header("Location: index.php"); }
include_once 'dbconnect.php'; //contains $db
$sql = "SELECT * FROM myTable"; //contains two rows
$sql_res = mysqli_query($db, $sql);
$proxyCount = mysqli_num_rows($sql_res);
$echo "Count: ".$proxyCount;
?>
And my C# looks like this:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Net.Http;
using ModernHttpClient;
using Newtonsoft.Json;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void log(string str)
{
logbox.AppendText(str + Environment.NewLine);
}
private string host = "http://www.mywebsite.com/";
private HttpClient httpClient = new HttpClient(new NativeMessageHandler());
private async Task<string> request(string target, Dictionary<string, string> _parameters)
{
string uri = host + target;
using (HttpResponseMessage response = await httpClient.PostAsync(uri, new FormUrlEncodedContent(_parameters)))
return new StreamReader(await response.Content.ReadAsStreamAsync()).ReadToEnd();
}
private async void button1_Click(object sender, EventArgs e)
{
string loginResp = await request("login.php", new Dictionary<string, string> { { "username", "user" }, { "password", "password" } });
log(loginResp);
}
private async void button2_Click(object sender, EventArgs e)
{
string proxiesResp = await request("proxy/proxy.php", new Dictionary<string, string> { { "getAllProxyRequests", "" } });
//above returns "count: " in C#, but returns "count: 2" in webbrowser
log(proxiesResp);
}
}
}
Found the problem, it was human error.
I had the file dbconnect.php located one directory below where myProblem.php was located.
I had to change the line saying
include_once 'dbconnect.php';
to
include_once '../dbconnect.php';
I am working on a project to create videos from a series of images, videos and audios. The best API we could find online that suits our purpose was Stupeflix. Unfortunately Stupeflix doesn't come with a C# implementation examples. Since I couldn't find one online, I decided to put this question here.
Here is an example
Go https://developer.stupeflix.com/ and register for Api Key and Secret
Create an ASP.NET project in C#
Go to NuGet Packages Manager and add Microsoft.AspNet.WebApi.Client and Json.NET
Add Default page to your project and add Async="true" to the page declaration
Copy the code below and replace YourSecret with your Stupeflix secret.
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
namespace StupeflixTest
{
public class TaskObj
{
public Dictionary<string,string> tasks { get; set; }
public TaskObj(Dictionary<string, string> t)
{
tasks = t;
}
}
public partial class Default : System.Web.UI.Page
{
private const string URL = "https://dragon.stupeflix.com/";
protected async void Page_Load(object sender, EventArgs e)
{
string error = string.Empty;
try
{
Dictionary<string, string> taskParam = new Dictionary<string, string>();
taskParam.Add("task_name", "video.create");
taskParam.Add("definition", "<movie service='craftsman-1.0'> <body> <stack> <sequence> <effect type='sliding' duration='5.0'> <image filename='http://s3.amazonaws.com/stupeflix-assets/apiusecase/Canyon_Chelly_Navajo.jpg'/> <image filename='http://s3.amazonaws.com/stupeflix-assets/apiusecase/Ha_long_bay.jpg'/> <image filename='http://s3.amazonaws.com/stupeflix-assets/apiusecase/Monument_Valley.jpg'/> </effect> </sequence> </stack> </body></movie>");
TaskObj obj = new TaskObj(taskParam);
//uncomment the line below to see the resultant json object
//string str = JsonConvert.SerializeObject(obj);
HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Add("Authorization", "Secret YourSecret");
client.BaseAddress = new Uri(URL);
// await response.
var response = await client.PostAsJsonAsync("v2/create", obj); // Blocking call!
if (response.IsSuccessStatusCode)
{
var jsonResp = response.Content.ReadAsStringAsync().Result;
var jsonArray = JsonConvert.DeserializeObject<dynamic>(jsonResp);
string resultKey = jsonArray[0].key.Value;
string taskProgressUrl = URL + "v2/status?tasks=" + resultKey;
}
else
{
error = string.Format(#"{0} ({1})", (int)response.StatusCode, response.ReasonPhrase);
}
}
catch (Exception ex)
{
error = ex.Message;
}
}
}
}