How to call a public static async void in Main console app? - c#

I have the below class GetProjectClass, with public static async void GetProjects()
I want to call this method/class so it does "something" pretty new to Asynchronous programming – goal is to connect to TFS, pragmatically
I have the below code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
public class GetProjectClass
{
public static async void GetProjects()
{
try
{
var personalaccesstoken = "PAT_FROM_WEBSITE";
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Accept.Add(
new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic",
Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", "", personalaccesstoken))));
using (HttpResponseMessage response = client.GetAsync( "https://{account}.visualstudio.com/DefaultCollection/_apis/projects").Result)
{response.EnsureSuccessStatusCode();
string responseBody = await response.Content.ReadAsStringAsync();
Console.WriteLine(responseBody);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}
The below is my program.cs file, wanting to call the above, was wondering if this was possible
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
GetProjectClass t = new GetProjectClass();
t.GetProjects().Wait();
Console.WriteLine("finished");
Console.ReadKey();
}
}
}

Starting with C# 7.1 you can use async main methods:
class Program
{
static async Task Main(string[] args)
{
GetProjectClass t = new GetProjectClass();
await t.GetProjects();
Console.WriteLine("finished");
Console.ReadKey();
}
}
Pre C# 7.1 this was not possible.
NOTE: Yo need to change GetProjects to return a Task to get this working.

Related

Overriding dispose method in multiple child classes

I am currently using Xunit to write some integration testing in my .NET Core project. As part of this, I am setting up the data and other information before running a test in my custom class.
using Microsoft.AspNetCore.TestHost;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Xunit;
namespace XUnitTestProject1
{
public class BaseClassFixture<TStartup> : IAsyncLifetime where TStartup : class
{
private readonly TestServer _server;
public HttpClient Client { get; }
public BaseClassFixture()
{
Client = new HttpClient();
Client.BaseAddress = new Uri("https://apple.com");
Client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_server?.Dispose();
this.Client?.Dispose();
}
}
public Task DisposeAsync()
{
return Task.CompletedTask;
}
public Task InitializeAsync()
{
throw new NotImplementedException();
}
}
}
My first Child Class:
using Microsoft.AspNetCore.TestHost;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Xunit;
namespace XUnitTestProject1
{
public class GoogleTestClassFixture<TStartUp> : BaseClassFixture<TStartUp>, IAsyncLifetime where TStartUp : class
{
private readonly TestServer _server;
public HttpClient GoogleClient { get; }
public GoogleTestClassFixture()
{
GoogleClient = new HttpClient();
GoogleClient.BaseAddress = new Uri("https://google.com");
GoogleClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
public void Dispose()
{
_server?.Dispose();
GoogleClient?.Dispose();
base.Dispose(true);
}
public Task DisposeAsync()
{
throw new NotImplementedException();
}
public Task InitializeAsync()
{
throw new NotImplementedException();
}
}
}
My Second Child Class:
using Microsoft.AspNetCore.TestHost;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Xunit;
namespace XUnitTestProject1
{
public class FaceBookTestClassFixture<TStartUp> : BaseClassFixture<TStartUp>, IAsyncLifetime where TStartUp : class
{
private readonly TestServer _server;
public HttpClient FaceBookClient { get; }
public FaceBookTestClassFixture()
{
FaceBookClient = new HttpClient();
FaceBookClient.BaseAddress = new Uri("https://facebook.com");
FaceBookClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
public void Dispose()
{
_server?.Dispose();
FaceBookClient?.Dispose();
base.Dispose(true);
}
public Task DisposeAsync()
{
throw new NotImplementedException();
}
public Task InitializeAsync()
{
throw new NotImplementedException();
}
}
}
When I run all the tests in my test explorer at once, some times I'm getting the error "Cannot access a dispose object". I am assuming, this is happening because some times the tests related to one test fixture are running and the object is disposed, and the other test fixture is unable to access already disposed of items from the base Class fixture.
My First Tests looks something like this:
public class GoogleTests
{
private readonly HttpClient _googleClient;
private readonly HttpClient _baseClient;
public GoogleTests(GoogleTestClassFixture<StartUp> fixture)
{
_googleClient = fixture.GoogleClient;
_baseClient = fixture.Client;
}
[Fact]
public async Task ValidateFirstClient()
{
var getDetails = await _googleClient.GetAsync("//someRoute");
var uri = new Uri("https://someRandom.com");
var postDetails = await _baseClient.PutAsync(uri, getDetails.Content);
var response = await postDetails.Content.ReadAsStringAsync();
dynamic dynamicResponse = JObject.Parse(response);
((int)dynamicResponse.myProperty).Should().Be(0);
}
}
My Second Test Class:
using FluentAssertions;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Xunit;
namespace XUnitTestProject1
{
public class FaceBookTests
{
private readonly HttpClient _fbClient;
private readonly HttpClient _baseClient;
public FaceBookTests(FaceBookTestClassFixture<StartUp> fixture)
{
_fbClient = fixture.FaceBookClient;
_baseClient = fixture.Client;
}
[Fact]
public async Task ValidateFirstClient()
{
var getDetails = await _fbClient.GetAsync("//someRoute");
var uri = new Uri("https://someRandom.com");
var postDetails = await _baseClient.PutAsync(uri, getDetails.Content);
var response = await postDetails.Content.ReadAsStringAsync();
dynamic dynamicResponse = JObject.Parse(response);
((int)dynamicResponse.myProperty).Should().Be(0);
}
}
}
enter code here
How can I solve this issue, and make sure the object is not disposed until it finishes running all the tests?
Note: I have created a simple web application project just to get the startup.cs class as a reference in my test project

getting CS1503 when im trying to create a rest api from a tutorial

I'm trying to communicate with my node js backend from my Xamarin forms app from a tutorial and getting the following error
Severity Code Description Project File Line Suppression State
Error CS1503 Argument 1: cannot convert from 'Kula.MainPage' to 'Android.Content.Context' Kula C:\Users\1243g\Desktop\Kula\Kula\Kula\Kula\MainPage.xaml.cs 28 Active
The error is under this in Mainactivity
I was wondering what I am doing wrong because this is the first time I'm trying to create a rest API code below. I think I'm close. So any implementation on how to use the right variables and fix it would be extremely helpful
Main
using Kula.API;
using Refit;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace Kula
{
// Learn more about making custom code visible in the Xamarin.Forms previewer
// by visiting https://aka.ms/xamarinforms-previewer
[DesignTimeVisible(false)]
public partial class MainPage : ContentPage
{
// set variables
Entry RinputEmail;
Entry RinputPassword;
IMyAPI myAPI;
APIRequestHelper apiRequestHelper;
public MainPage()
{
InitializeComponent();
myAPI = RestService.For<IMyAPI>("");
apiRequestHelper = new APIRequestHelper(this , myAPI);
RinputEmail = this.FindByName<Entry>("Remail");
RinputPassword = this.FindByName<Entry>("Rpassword");
}
async private void GTLogin_Clicked(object sender, EventArgs e)
{
//navigate to Login page
await Navigation.PushAsync (new Login());
}
async private void registerUser_Clicked(object sender, EventArgs e)
{
await apiRequestHelper.RequestRegisterUserAsync((RinputEmail.Text).ToString(), (RinputPassword.Text).ToString());
}
}
}
API request helper (one for login one for register)
using Android.Content;
using Android.Widget;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace Kula.API
{
public class APIRequestHelper
{
Context context;
IMyAPI myAPI;
public APIRequestHelper(Context context, IMyAPI myAPI)
{
this.context = context;
this.myAPI = myAPI;
}
public async Task RequestRegisterUserAsync(string email, string password)
{
if (string.IsNullOrEmpty(email))
{
Toast.MakeText(context, "no email detected", ToastLength.Short).Show();
}
if (string.IsNullOrEmpty(password))
{
Toast.MakeText(context, "no password detected", ToastLength.Short).Show();
}
//create params for request
Dictionary<string, object> data = new Dictionary<string, object>();
data.Add("email", email);
data.Add("password", password);
string result = await myAPI.RegisterUser(data);
}
public async Task RequestLoginUserAsync(string email, string password)
{
if (string.IsNullOrEmpty(email))
{
Toast.MakeText(context, "no email detected", ToastLength.Short).Show();
}
if (string.IsNullOrEmpty(password))
{
Toast.MakeText(context, "no password detected", ToastLength.Short).Show();
}
//create params for request
Dictionary<string, object> data = new Dictionary<string, object>();
data.Add("email", email);
data.Add("password", password);
string result = await myAPI.LoginUser(data);
}
}
}
MyAPI
using Refit;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace Kula.API
{
public interface IMyAPI
{
[Post("/register")]
Task<string> RegisterUser([Body(BodySerializationMethod.UrlEncoded)] Dictionary<string, object> data);
[Post("/login")]
Task<string> LoginUser([Body(BodySerializationMethod.UrlEncoded)] Dictionary<string, object> data);
}
}

How run Multiple c# class files

I have these three class files which I am working on in the bot framework.But when I run my project in the bot emulator only the dialogs of the WelcomeDialog file runs and the other files don't
like if I say hi which is from the WelcomeDialog file I get a corresponding in the emulator but if say Search me something which is from the Bing Search the emulator response with I am unable to understand sorry
I don't know whether the problem is with the message controller file or what
only single cs file works at a time
WelcomeDialog .cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Connector;
using Microsoft.Azure.CognitiveServices.Search;
namespace MyFYP.Dialogs
{
[Serializable] //As bot framework serilaizes and deserializes dialogs
public class WelcomeDialog : IDialog<object>
{
public Task StartAsync(IDialogContext context)
{
context.Wait(PerformActionAsync); // calling PerformActionAsync
return Task.CompletedTask;
}
public async Task PerformActionAsync(IDialogContext context, IAwaitable<object> result)
{ //method
var activity = await result as Activity;
if (activity.Text.Equals("Hello") || activity.Text.Equals("Hi") || activity.Text.Equals("hi") || activity.Text.Equals("hii"))
{
await context.PostAsync("Welcome to the Chatbot Portal of LMS");
}
else if (activity.Text.Equals("How are you"))
await context.PostAsync("I am doing well AlhamdULLILAH what I can do for you");
else if (activity.Text.Equals("what can you do") || activity.Text.Equals("What services you provide"))
await context.PostAsync("i CAN OFFER A COUPLE OF SERVICES ");
else await context.PostAsync("I am unable to understand you");
}
}
}
BingSearch.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Connector;
using Microsoft.Azure.CognitiveServices.Search;
namespace MyFYP.Dialogs
{
[Serializable] //As bot framework serilaizes and deserializes dialogs
public class BingSearch : IDialog<object>
{
private string searchtype = string.Empty;
private string query = string.Empty;
private const string BING_KEY = "3b681ec3e2ed47f3930493d261a28e6d";
private const string searchWeb = "Search Web";
public Task StartAsync(IDialogContext context)
{
context.Wait(MessageActionAsync); // calling PerformActionAsync
return Task.CompletedTask;
}
private async Task MessageActionAsync(IDialogContext context, IAwaitable<object> result)
{ //method
var activity = await result as Activity;
if (activity.Text.Equals("Search me something") || activity.Text.Equals("i want some material"))
{
PromptDialog.Choice(
context: context,
resume: ResumeAfterSearchTypeSelecting,
prompt: "Select searcht type you want to perform",
options: new List<string>
{
searchWeb
}
);
}
}
private async Task ResumeAfterSearchTypeSelecting(IDialogContext context, IAwaitable<string> result)
{
searchtype = (await result) as string;
PromptDialog.Text(
context: context,
resume: ResumeAfterEnteringQuery,
prompt: "Enter your query"
);
}
private async Task ResumeAfterEnteringQuery(IDialogContext context, IAwaitable<string> result)
{
query = (await result) as string;
switch (searchtype)
{
case searchWeb:
{
await BingSearchHelper.SearchWebAsync(context, BING_KEY, query);
break;
}
}
context.Wait(MessageActionAsync);
}
}
}
BingSearchHelper.cs
using System.Web;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Connector;
using Microsoft.Azure.CognitiveServices.Search.WebSearch;
using Microsoft.Azure.CognitiveServices.Search.WebSearch.Models;
namespace MyFYP.Dialogs
{
public class BingSearchHelper
{
public async static Task SearchWebAsync(IDialogContext context,string key,string query)
{
IWebSearchClient client = new WebSearchClient(new ApiKeyServiceClientCredentials(key));
var result = await client.Web.SearchAsync(query:query, count:3, safeSearch: SafeSearch.Strict);
if(result?.WebPages?.Value?.Count>0)
{
await context.PostAsync($"Here is top 3 results for {query} ");
foreach(var item in result.WebPages.Value)
{
HeroCard card = new HeroCard
{
Title = item.Name,
Text = item.Snippet,
Buttons = new List<CardAction>
{
new CardAction(ActionTypes.OpenUrl,"Open Page",value:item.Url)
}
};
var message = context.MakeMessage();
message.Attachments.Add(card.ToAttachment());
await context.PostAsync(message);
}
}
}
}
}
In WelcomeDialog.cs you are calling context.Wait(PerformActionAsync ) which is executing the WelcomeDialog.PerformActionAsync function. Replace PerformActionAsync with BingSearchHelper.SearchWebAsync if you would like to run that function instead.
context.Wait(BingSearchHelper.SearchWebAsync);
To answer the bigger question of "How to run Multiple C# class files", you will typically do it one of two ways.
By creating an instance of that class and calling functions from that instance
Animal dog = new Animal();
dog.Sit();
Or if that function you want to call is static (meaning a class object doesn't need to be created like in the first example), you can simply call the class name followed by the function
Animal.Sit();

How to get magento admin token with restsharp

I'm pretty new to rest API and restsharp so I need some help. I need to get a magento version 2.2.3 admin token but I keep getting a bad request. I've followed this tutorial: https://www.youtube.com/watch?v=2sdGuC7IUAI&t=343s. But I'm ending up with a bad request. When I check the statuscode using a the breakpoints from the tutorial I get: NotFound.
My main goal is to get the categories I have in Magento. But to get that I need an admin token. I already have a bearer acces code etc.
I would really appreciate your help.
my code so far:
magento.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RestSharp;
using Newtonsoft.Json;
namespace MagentoTest
{
public class magento
{
private RestClient Client { get; set; }
private string Token { get; set; }
public magento(string magentoUrl)
{
Client = new RestClient(magentoUrl);
}
public magento(string magentoUrl,string token)
{
Client = new RestClient(magentoUrl);
Token = token;
}
public string GetAdminToken(string userName, string passWord)
{
var request = CreateRequest("/rest/V1/integration/admin/token", Method.POST);
var user = new Credentials();
user.username = userName;
user.password = passWord;
string Json = JsonConvert.SerializeObject(user, Formatting.Indented);
request.AddParameter("aplication/json", Json, ParameterType.RequestBody);
var response = Client.Execute(request);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
return response.Content;
}
else
{
return "";
}
}
private RestRequest CreateRequest(string endPoint, Method method)
{
var request = new RestRequest(endPoint, method);
request.RequestFormat = DataFormat.Json;
return request;
}
}
}
Credentials:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MagentoTest
{
public class Credentials
{
public string username { get; set; }
public string password { get; set; }
}
}
(Client)
Program.cs
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MagentoTest;
namespace Client
{
class Program
{
static void Main(string[] args)
{
GetToken("blabla", "blabla");
}
static void GetToken(string userName, string passWord)
{
var m2 = new magento("http://beta.topprice24.com");
string token = m2.GetAdminToken(userName, passWord);
}
}
}
It looks, relative URL needs to be changed as "/rest/default/V1/integration/admin/token"
(https://devdocs.magento.com/guides/v2.1/get-started/order-tutorial/order-admin-token.html).
I have simplified the above code and you can easily get the token.
Keep your Credentials class as it is and change your main program as below
Modified Code:(Program.cs)
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Client
{
class Program
{
static void Main(string[] args)
{
//Base URL needs to be Specified
String host = "http://beta.topprice24.com";
//Relative URL needs to be Specified
String endpoint = "/rest/default/V1/integration/admin/token";
RestClient _restClient = new RestClient(host);
var request = new RestRequest(endpoint, Method.POST);
//Initialize Credentials Property
var userRequest = new Credentials{username="blabla",password="blabla"};
var inputJson = JsonConvert.SerializeObject(userRequest);
//Request Header
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Accept", "application/json");
//Request Body
request.AddParameter("application/json", inputJson, ParameterType.RequestBody);
var response = _restClient.Execute(request);
var token=response.Content;
}
}
}

(Discord bot 1.0 c#) How to make a new class and add cmds?

Hello there Stackoverflow! (first time posting here so plz be nice :P)
So, I've decided to make a discord bot 1.0 in c# (i'm learning c# atm) and I have gotten in to a problem and i'm not sure how to fix it..
So, to describe what i'm trying to do is following.
I'm trying to make it so i can have different classes for x commands such as .say etc instead of having em all in the "commands" one below so its a bit easier to work with.
I got these working three scripts but cant get the fourth to work
//Startup
using System;
using System.Threading.Tasks;
using Discord;
using Discord.WebSocket;
using Discord.Commands;
namespace MyBot
{
public class Program
{
// Convert our sync main to an async main.
public static void Main(string[] args) =>
new Program().Start().GetAwaiter().GetResult();
private DiscordSocketClient client;
private CommandHandler handler;
public async Task Start()
{
// Define the DiscordSocketClient
client = new DiscordSocketClient();
var token = "Censored";
// Login and connect to Discord.
await client.LoginAsync(TokenType.Bot, token);
await client.StartAsync();
var map = new DependencyMap();
map.Add(client);
handler = new CommandHandler();
await handler.Install(map);
// Block this program until it is closed.
await Task.Delay(-1);
}
private Task Log(LogMessage msg)
{
Console.WriteLine(msg.ToString());
return Task.CompletedTask;
}
}
}
//My command handler
using System.Threading.Tasks;
using System.Reflection;
using Discord.Commands;
using Discord.WebSocket;
namespace MyBot
{
public class CommandHandler
{
private CommandService commands;
private DiscordSocketClient client;
private IDependencyMap map;
public async Task Install(IDependencyMap _map)
{
// Create Command Service, inject it into Dependency Map
client = _map.Get<DiscordSocketClient>();
commands = new CommandService();
_map.Add(commands);
map = _map;
await commands.AddModulesAsync(Assembly.GetEntryAssembly());
client.MessageReceived += HandleCommand;
}
public async Task HandleCommand(SocketMessage parameterMessage)
{
// Don't handle the command if it is a system message
var message = parameterMessage as SocketUserMessage;
if (message == null) return;
// Mark where the prefix ends and the command begins
int argPos = 0;
// Determine if the message has a valid prefix, adjust argPos
if (!(message.HasMentionPrefix(client.CurrentUser, ref argPos) || message.HasCharPrefix('!', ref argPos))) return;
// Create a Command Context
var context = new CommandContext(client, message);
// Execute the Command, store the result
var result = await commands.ExecuteAsync(context, argPos, map);
// If the command failed, notify the user
if (!result.IsSuccess)
await message.Channel.SendMessageAsync($"**Error:** {result.ErrorReason}");
}
}
}
//Commands
using System;
using System.Linq;
using System.Threading.Tasks;
using Discord;
using Discord.Commands;
using Discord.WebSocket;
using System.Runtime.InteropServices;
using System.Diagnostics;
namespace MyBot.Modules.Public
{
public class PublicModule : ModuleBase
{
[Command("invite")]
[Summary("Returns the OAuth2 Invite URL of the bot")]
public async Task Invite()
{
var application = await Context.Client.GetApplicationInfoAsync();
await ReplyAsync(
$"A user with `MANAGE_SERVER` can invite me to your server here: <https://discordapp.com/oauth2/authorize?client_id={application.Id}&scope=bot>");
}
[Command("leave")]
[Summary("Instructs the bot to leave this Guild.")]
[RequireUserPermission(GuildPermission.ManageGuild)]
public async Task Leave()
{
if (Context.Guild == null) { await ReplyAsync("This command can only be ran in a server."); return; }
await ReplyAsync("Leaving~");
await Context.Guild.LeaveAsync();
}
}
}
//This is the one i want to work but i only get "Unknown command" as error?
using Discord.Commands;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
namespace MyBot.Modules.Public
{
class test : ModuleBase
{
[Command("say")]
[Alias("echo")]
[Summary("Echos the provided input")]
public async Task Say([Remainder] string input)
{
await ReplyAsync(input);
}
}
}
If you know what i do wrong please tell me or reefer me to some info about the problem and i can try fix it :)
Thanks in advance!
PS, im sorry if there is a dupe of this question but i don't know what to search for to find it
EDIT
I've been told to "Pit the metohds (cmds) in the class" but how would i go around todo that?
The answer is following
Add Public before the class {name}so it would be
namespace MyBot.Modules.Public
{
**Public** class test : ModuleBase
{
[Command("say")]
[Alias("echo")]
[Summary("Echos the provided input")]
public async Task Say([Remainder] string input)
{
await ReplyAsync(input);
}
}
}

Categories

Resources