using System;
using System.Text;
namespace ConsoleApp7
{
class Program
{
static void Main(string[] args)
{
YourClient client = new YourClient();
client.Put();
}
public class YourClient
{
private readonly HttpClient _client;
public YourClient()
{
_client = new HttpClient();
}
public async Task Put() // must be async
{
using (var request = new HttpRequestMessage(HttpMethod.Put, "https://api.minecraftservices.com/minecraft/profile/name/egg"))
{
request.Headers.Add("Authorization", "Bearer token");
request.Content = new StringContent("body", Encoding.UTF8, "content-type");
using (var response = await _client.SendAsync(request))
{
var data = await response.Content.ReadAsStringAsync();
var code = response.StatusCode;
Console.WriteLine(Convert.ToString(code));
// do something with data
}
}
}
}
}
}
I'm not getting any output and I don't know why. I'm trying to print the response code of the request but nothing is output, is it to do with my method?
I have tried printing hi after Client.Put() and it was printed, so I know that my code is actually running, I just don't know why it isn't printing the status code ...
The excellent comment by Prolog points out one of two issues. If your Console app is built on < C# 7.1 you will need a workaround to prevent the app from exiting (before the request has time to process) so in this case add Console.ReadKey() as the very last line. This will spin the message loop until you hit a key. But this is not the main issue and I would like to offer a couple of debugging tips.
The big issue is this:
If I run your code, your http request is failing and is throwing a System.FormatException
Usually this type of exception is not set to Break when Thrown. (You can verify this by looking in the Exception Settings window.) Unfortunately, this is giving you a silent failure in this case, so you must take matters into your own hands to observe it.
Suggestions for debugging your code
Use a try-catch block around any code that has any likelihood of failing.
Use System.Diagnostics.Debug.Assert which will cause your program to break on a line if any condition expression evaluates to false (but only when you're running in Debug mode not Release mode).
Add output statements to trace execution. Using Debug.WriteLine will send messages to the Output window (but again, only in Debug mode). Alternatively, since we have a Console app here, I'm using the main app window to output trace statements.
Example using 1-3:
public async Task Put() // must be async
{
Console.WriteLine("Begin Put()");
try
{
using (var request = new HttpRequestMessage(HttpMethod.Put, "https://api.minecraftservices.com/minecraft/profile/name/egg"))
{
request.Headers.Add("Authorization", "Bearer token");
request.Content = new StringContent("body", Encoding.UTF8, "content-type");
using (var response = await _client.SendAsync(request))
{
var data = await response.Content.ReadAsStringAsync();
var code = response.StatusCode;
Console.WriteLine(Convert.ToString(code));
// do something with data
}
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.Assert(condition: false, message: ex.Message);
}
Console.WriteLine("End Put()");
}
Now, if I run the code it will break and show what the problem is.
Use the Exception Settings window to turn on all exceptions (if in doubt). Now the code will break on the exact line that is the problem.
Verify that you are Setting Authorization Header of HttpClient correctly as this may be part of the root cause of the exception.
Finally, if you continue after the Debug.Assert you will see the following text in your console which will confirm whether your Put method has had a chance to complete or not.
Hope these suggestions help you solve this problem and future ones!
// This workaround for C# versions below 7.1 attempts to
// mimic an `async Main` method.
static void Main(string[] args)
{
RunAsync();
Console.ReadKey();
}
private static async void RunAsync()
{
YourClient client = new YourClient();
// Put() should be awaited inside an async method
await client.Put();
}
Related
I am trying to debug a request by GetFromJsonAsync which is supposed to fetch data from a Flask API and convert to JSON within a .NET Core cli app.
The issue I am having however is that after performing the request the cli app simply exits with no error. I have tried implementing try/catch block but nothing shows up there.
the Flask endpoint builds jsonifies a number of uuids and messages from Postgres and returns them to the client.
As GetFromJsonAsync is asynchronous I have tried making the Flask endpoint likewise but that has not seemed to help at all. The latter works fine and has been validated with curl.
I know the call executes as I can see it in my web server logs.
A similar call which simply returns plain javascript object {"foo": "bar"} works fine which is why I think this could by an async issue but I cannot see any errors etc to troubleshoot. I have placed a breakpoint on the foreach after the call but this is never hit.
What am I missing here?
public static async void GetMessages()
{
ConfigureHeaders();
try
{
var client = Client;
var res = await Client.GetFromJsonAsync<Received>(Url + "/api/chat/message"); // stops here
foreach (var c in res!.messages) // breakpoint here is never hit
Console.WriteLine(c);
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
public class Received
{
public Dictionary<string,string> messages { get; set; }
}
Flask
#message.get("/api/chat/message")
#csrf.exempt
async def get_messages():
new_msgs = {}
msgs = await get_unreplied() # DB gets called from another function here
try:
for m in msgs:
new_msgs[m.id] = m.message
if len(new_msgs) != 0:
return jsonify(new_msgs)
else:
return jsonify("no messages")
except Exception as e:
print(str(e))
This returns...
{
"id_foo1": "message_bar1",
"id_foo2": "message_bar2"
}
Best guess: your Main function is not awaiting the call to GetMessages
public async Task<int> Main(string []args)
{
await GetMessages();
}
I am writing a Visual Studio extension in C# and I get a strange behavior on managing exception and displaying error messages. Basically, I just want to add some details to the exception message to help me investigate in case of a problem.
It all starts from a command on a context menu item and I suspect it may be related to threads management behind the async/await mechanism. But I am not sure I guess correctly and I am not able to find any solution. HELP!
It starts from my menu item callback:
internal sealed class My_RunAnalysis
{
//...
public static async Task InitializeAsync(AsyncPackage package)
{
// Switch to the main thread - the call to AddCommand in PS_RunAnalysis's constructor requires
// the UI thread.
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(package.DisposalToken);
OleMenuCommandService commandService = await package.GetServiceAsync((typeof(IMenuCommandService))) as OleMenuCommandService;
Instance = new My_RunAnalysis(package, commandService);
}
//...
private async void ExecuteAsync(object sender, EventArgs e)
{
try
{
await My_ViewModel.RunAnalysisAsync();
}
catch (Exception exc)
{
await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(package.DisposalToken);
MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
}
//...
class My_ViewModel
{
async public static Task RunAnalysisAsync()
{
await My_Model.GetResultsListAsync();
}
}
//...
class My_Model
async public static Task GetResultsListAsync()
{
ResultsList = new My_ResultsList();
var rawResultsList = await QueryServerAsync<RawResultsListResponse>("GET", My_Request.GetResults());
//...
}
async public static Task<JsonResponse> QueryServerAsync<JsonResponse>(string method,
string request)
{
try
{
HttpResponseMessage response;
switch (method)
{
case "GET":
response = await _httpClient.GetAsync(request);
break;
case "POST":
default:
StringContent httpContent = new StringContent("", Encoding.UTF8, "application/json");
response = await _httpClient.PostAsync(request, httpContent);
break;
}
if (!response.IsSuccessStatusCode) //<<<<<<CASE #1
{
throw new My_Exception(
response.ReasonPhrase,
"Exception while querying server for " + request);
}
string serializedJson = await response.Content.ReadAsStringAsync();
// CASE #2>>>>>
var jsonResponse = serializer.Deserialize<JsonResponse>(serializedJson);
return jsonResponse;
}
catch (Exception e)
{
throw new My_Exception(
e.Message,
"Exception while querying server for " + request);
}
}
The strange thing is that:
When an error occurs in case #1 and I create a custom exception (my server responded but there was an internal error and I have a clean error code), the MessageBox in the catch of My_ViewModel::RunAnalysisAsync() will show correctly and immediately.
When a native exception occurs in case #2 (my server responded with malformed json and I get an exception from serializer.Deserialize), the MessageBox in the catch of My_ViewModel::RunAnalysisAsync() will not show, the IDE will hang for around 15s before restarting (and still not show the MessageBox).
Any idea what's wrong?
Thanks!
EDIT:
Seeing that the template for my custom command initializes also with SwitchToMainThreadAsync, I have tried to do the same with the Execute method. I updated the code above but it still does not work: an exception thrown by serializer.Deserialize will still freeze the UI for 10 to 15s and the MessageBox will not show!
Also note that the debugger can step immediately on "await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(package.DisposalToken);" and go on next step to MessageBox. I would tend to suppose it means that the switch to the main thread is immediate but there is still something wrong...
Any idea what's wrong? I really need to capture exceptions a reliable way...
I could not find any explanation to the MessageBox working on a case and not on the other one. I ended up going to some log solution using FileStream.WriteAsync. Hence everything keeps async and I don't have to use MessageBox anymore.
use await JoinableTaskFactory.SwitchToMainThreadAsync(); to switch to the main thread JoinableTaskFactory is a member of AsyncPackage.
If it still doesn't work try
public static void ShowMessageBox(string title, string text)
{
Microsoft.VisualStudio.Shell.ThreadHelper.ThrowIfNotOnUIThread();
IVsUIShell uiShell = Microsoft.VisualStudio.Shell.ServiceProvider.GlobalProvider.GetService(typeof(SVsUIShell)) as IVsUIShell;
Guid clsid = Guid.Empty;
int result;
Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(uiShell.ShowMessageBox(
0,
ref clsid,
title,
text,
string.Empty,
0,
OLEMSGBUTTON.OLEMSGBUTTON_OK,
OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST,
OLEMSGICON.OLEMSGICON_INFO,
0, // false
out result));
}
I found that my Xamarin Android app is running slowly so I added some async/await code to improve the performance. I wanted to excluded my API calls from the UI thread. I thought this would be a perfect opportunity to use async/await. So, I added async to the signature of the function and wrapped Task around my return value type. Then I updated the RestSharp GET call with "await client.ExecuteTaskAsync." Once I did this I found I needed to update my call to the GetCustInfo function. I simply needed to add .Result to the end of the call and it showed no errors. The problem is it hangs on the call to GetCustInfo and just doesn't work.
What am I doing wrong here?
public async Task<List<CustInfo>> GetCustInfo(string strBranchNumber, string dblCurrentXCoordinate, string dblCurrentYCoordinate)
{
if (this.strBearerToken == string.Empty)
{
throw new ArgumentException("No Bearer Token Found");
}
try
{
var restUrl = this.strCustomerInfoAPIURL;
var uri = new Uri(string.Format(restUrl, string.Empty));
var client = new RestClient(uri);
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "bearer " + this.strBearerToken);
request.AddParameter("intBranchNumber", strBranchNumber);
request.AddParameter("intZipCode", this.strZipCode);
request.AddParameter("intCustomerType", this.strCustomerType);
request.AddParameter("intMinTotalAmount", this.strMinRevenue);
request.AddParameter("dblCurrentXCoordinate", dblCurrentXCoordinate);
request.AddParameter("dblCurrentYCoordinate", dblCurrentYCoordinate);
request.AddParameter("bolGetLocation", true);
var response = await client.ExecuteTaskAsync(request);
return JsonConvert.DeserializeObject<List<CustInfo>>(response.Content).OrderBy(x => x.ApproxDistance).ToList();
}
catch (Exception ex)
{
return null;
}
}
So what is happening is when I call the async/await function from my OnCreate it just stops when I try to call customer.GetCustomerInfo().
protected override void OnCreate(Bundle bundle)
{
....
this.tableItems = customer.GetCustInfo(
"xxxxxxx",
this.currentLocation.Latitude.ToString(),
this.currentLocation.Longitude.ToString()).Result;
this.listView.Adapter = new ListOfLocationAdapter(this, this.tableItems);
}
Change the call to
this.tableItems = await customer.GetCustInfo(..
and let us know..
In the next line you are using the result from the not-awaited call, it obviously would hangs, crash whatever:
this.listView.Adapter = new ListOfLocationAdapter(this, **this.tableItems**); //this.tableItems is just empty
I am using the below code to read JSON from an endpoint in my Xamarin crossplatform project and I am getting error
Cannot read disposed object exception or it fires ObjectDisposedException
IS it something wrong with code Can I write it in a better way ?
public async Task<APISchoolDetailModel> GetSchooDetailsAsync()
{
APISchoolDetailModel api_data = new APISchoolDetailModel();
try
{
var client = new System.Net.Http.HttpClient();
client.DefaultRequestHeaders.Add("Accept", "application/json");
var web_client = await client.GetAsync("http://appapitest.net/APIs/Student/Schooldetails");
var response_string= web_client.Content.ReadAsStringAsync().Result;
DataContractJsonSerializer serializer = new DataContractJsonSerializer(api_data.GetType());
MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(response_string));
api_data = serializer.ReadObject(ms) as APISchoolDetailModel;
}
catch (Exception ex) { }
return api_data;
}
The controller comes till the line var web_client = await client.GetAsync(" and then its not going further and after few seconds I am getting exception
Is any better way to write this code for reading and parsing JSON
#Gserg pointed out something important you should not do this:
var response_string= web_client.Content.ReadAsStringAsync().Result;
in stead of that use:
var response_string= await web_client.Content.ReadAsStringAsync();
within an async Task method:
is you use .Result this may be causing deadlocks within threads or the same stuff that you are experiencing because a thread may be trying to update or use a variable that is already collected from the GC.
I'm trying to debug an asynchronous call from a test script inside my .NET webservice, but the breakpoints inside my async call are never getting hit. I even tried putting a Debugger.Break() inside of it. Below is the calling code...
HttpClient client = new HttpClient();
client.BaseAddress = new Uri(ConfigurationManager.AppSettings["BaseAddress"]);
string uri = "/api/Rd_Regions";
// Below is the line of code I want to step into, but it won't step into the 'client.GetAsync(uri)'...
HttpResponseMessage response = await client.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
// Convert the result into business object
// Do stuff...
}
else do other stuff...
and the part of the webservice that should be getting called where the breakpoints are is here, the first is the context of the web api, followed by the method being called. I'd be happy if it stopped in either...
public partial class PIMSContext : DbContext
{
public PIMSContext()
: base(new OracleConnection(Security.ConfigurationReader.GetAppSetting("PIMS")), true)
//: base(new OracleConnection(ConfigurationManager.ConnectionStrings["PIMS"].ConnectionString), true)
etc....
And here is the method that is ultimately called:
// GET: api/RD_REGIONS
public IQueryable<RD_REGIONS> GetRD_REGIONS()
{
// I want the debugger to stop here!
Debugger.Break();
return db.RD_REGIONS;
}
Am I missing something? Is it not possible to step into this asynchronous call?
Any insight is appreciated.
Forgot to update with the answer earlier - it turns out I was accidentally debugging in Release mode (VS2015). Switching to Debug mode fixed it - all breakpoints started behaving as expected.
If i have understood you correctly - all breakpoints listed above are not getting hit? Not in await client.GetAsync(uri); neither in web-service GetRD_REGIONS() ? Is the code following after client.GetAsync not reached?
If it's true - maybe this method is never completed?
await client.GetAsync(uri);
Than it's possible that you are getting an exception in this place. Try to surround your GetAsync method with try/catch and place the breakpoint inside the catch block. Something like this:
...
HttpResponseMessage response = null;
try {
response = await client.GetAsync(uri);
}
catch (Exception e) {
throw e; //breakpoint goes here
}
...
Sometimes, because of your method is asynchronous, unhandled exceptions can't be registered globally by debugger or event-log. You can get this exception only with try/catch.