Unable to run the web API - asp.net-web-api2

I have two web-apis
public string GetRData(string data)
{
var serialPort = new SerialPort("COM1", 9600, Parity.Even, 8, StopBits.One);
try
{
if(serialPort.IsOpen)
{
var stream = new SerialStream(serialPort);
stream.ReadTimeout = 2000;
//byte[] bytestoread = new byte[9999];
byte[] bytestosend = StringToByteArray(data);
serialPort.Write(bytestosend, 0, bytestosend.Length);
//receiveData = serialPort.ReadExisting();
serialPort.Close();
}
else
{
//serial port settings and opening it
serialPort.Open();
var stream = new SerialStream(serialPort);
stream.ReadTimeout = 2000;
//byte[] bytestoread = new byte[9999];
byte[] bytestosend = StringToByteArray(data);
serialPort.Write(bytestosend, 0, bytestosend.Length);
//receiveData = serialPort.ReadExisting();
serialPort.Close();
}
}
catch(Exception ex)
{
}
return data;
}
public string GetPData(string id)
{
var serialPort = new SerialPort("COM2", 9600, Parity.Even, 8, StopBits.One);
string receiveData = "";
try
{
//serial port settings and opening it
serialPort.Open();
var stream = new SerialStream(serialPort);
stream.ReadTimeout = 2000;
//byte[] bytestoread = new byte[9999];
//byte[] bytestosend = StringToByteArray(data);
//serialPort.Write(bytestosend, 0, bytestosend.Length);
receiveData = serialPort.ReadExisting();
serialPort.Close();
}
catch (Exception ex)
{
}
return receiveData;
}
WebApiConfig.cs
config.Routes.MapHttpRoute(
name: "GetRData",
routeTemplate: "api/{controller}/{action}/{data}",
defaults: null
);
config.Routes.MapHttpRoute(
name: "GetPData",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Whenever I am trying to hit the GetPData I am getting below response in Postman
{
"Message": "No HTTP resource was found that matches the request URI 'https://localhost:44337/api/rtu/GetPData/1'.",
"MessageDetail": "No action was found on the controller 'RTU' that matches the request."
}
I have searched for this issue but unable to get a solution.
Note: The GetRData is working perfectly

You are including the action in the URI rather than relying on convention for route matching so you should add attributes to explicitly specify the allowed HTTP verbs:
[HttpGet]
public string GetPData(string id)
Having said that your action does start with "Get" so that should be the verb to which it matches. You should ensure that the request is a "GET". Otherwise the routing looks OK. Have you tried hitting it with the URL:
https://localhost:44337/api/rtu/GetPData?id=1

Related

Azure Logic Apps internal server error 500

Am trying to create a an azure function that is triggered in a Logic Apps,
The functions purpose is to web crawl certain web sites, take the desired information, compare that with a a SQL Server database in Azure, compare if we already have that information if not add it.
My issue is that when ever i run it I get the Server 500 error, I assume its accessing the database that cause. Help?
public static async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req, ILogger log
)
{
log.LogInformation("C# HTTP trigger function processed a request.");
string RequestBody = await new StreamReader(req.Body).ReadToEndAsync();
{
return await CrawlBlog(0, RequestBody);
}
}
private static async Task<IActionResult> CrawlBlog(int Picker, string req)
{
int BlogPicker = Picker;
string TheResult = req;
//Get the url we want to test
var Url = "";
if (BlogPicker == 0)
{
Url = "*********";
}
else if (BlogPicker == 1)
{
Url = "*********";
}
/*
else if (BlogPicker == 2)
{
Url = "https://azure.microsoft.com/en-in/blog/?utm_source=devglan";
}
*/
else
{
TheResult = "False we got a wrong pick";
return (ActionResult)new OkObjectResult
( new {TheResult });
}
var httpClient = new HttpClient();
var html = await httpClient.GetStringAsync(Url);
var htmlDocument = new HtmlDocument();
htmlDocument.LoadHtml(html);
//a list to add all availabel blogs we found
var Blog = new List<BlogStats>();
switch (BlogPicker)
{
case 0:
{
var divs =
htmlDocument.DocumentNode.Descendants("div")
.Where(node => node.GetAttributeValue("class", "").Equals("home_blog_sec_text")).ToList();
foreach (var divo in divs)
{
var Blogo = new BlogStats
{
Summary = divo.Descendants("p").FirstOrDefault().InnerText,
Link = divo.Descendants("a").FirstOrDefault().ChildAttributes("href").FirstOrDefault().Value,
Title = divo.Descendants("a").FirstOrDefault().InnerText
};
Blog.Add(Blogo);
}
break;
}
case 1:
{
var divs =
htmlDocument.DocumentNode.Descendants("div")
.Where(node => node.GetAttributeValue("class", "").Equals("post_header_title two_third last")).ToList();
foreach (var divo in divs)
{
//string TheSummary = "we goofed";
var ThePs = divo.Descendants("p").ToList();
var Blogo = new BlogStats
{
Summary = ThePs[1].GetDirectInnerText(),
Link = divo.Descendants("a").LastOrDefault().ChildAttributes("href").FirstOrDefault().Value,
Title = divo.Descendants("a").FirstOrDefault().InnerText
};
Blog.Add(Blogo);
}
break;
}
}
TheResult = await SqlCheck(Blog[0].Title, Blog[0].Summary, Blog[0].Link); //error 500
return (ActionResult)new OkObjectResult
(
new
{
TheResult
}
);
}
public static async Task<string> SqlCheck(string Tit, string Sumy, string Lin)
{
SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
builder.DataSource = "flygon.database.windows.net";
builder.UserID = "*****";
builder.Password = "********";
builder.InitialCatalog = "torkoal";
System.Data.DataSet ds = new System.Data.DataSet();
SqlConnection connection = new SqlConnection(builder.ConnectionString);
connection.Open();
SqlCommand CheckCommand = new SqlCommand("SELECT * FROM TableBoto WHERE Link = #id3 ", connection);
CheckCommand.Parameters.AddWithValue("#id3", Lin);
SqlDataAdapter dataAdapter = new SqlDataAdapter(CheckCommand);
dataAdapter.Fill(ds);
int i = ds.Tables[0].Rows.Count;
if (i > 0)
{
return $" We got a Duplicates in title : {Tit}";
}
try
{
{
string query = $"insert into TableBoto(Title,Summary,Link) values('{Tit}','{Sumy}','{Lin}');";
SqlCommand command = new SqlCommand(query, connection);
SqlDataReader reader = await command.ExecuteReaderAsync();
reader.Close();
}
}
catch (SqlException)
{
// Console.WriteLine(e.ToString());
}
connection.Close();
return $" Success Ign +{Tit} + Ign {Sumy}+ Ign {Lin} Ign Success SQL ";
}
}
500 HTTP status code is a generic code which means that the server was not able to process the request due to some issues, First step would be to add some exception handling to your function and see if the failure occurs and where it occurs.
On Side note, you should not use HTTP client in the way used in the code, you should not new it up every time your function executes, this client should be static in nature. Refer Manage connections in Azure Functions

completion port thread is leaking when client terminates the connection

I have a ASP.NET WebApi self-hosted application. HttpSelfHostConfiguration is configured as below
HttpSelfHostConfiguration config = new HttpSelfHostConfiguration("http://0.0.0.0:54781")
{
TransferMode = TransferMode.StreamedResponse,
MaxConcurrentRequests = 1000,
SendTimeout = TimeSpan.FromMinutes(60),
};
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "{controller}",
defaults: new { #controller = "Default" }
);
HttpSelfHostServer server = new HttpSelfHostServer(config);
server.OpenAsync().Wait();
for (;;)
{
int workerThreads, completionPortThreads;
ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);
Console.WriteLine("Available Completion Port Threads = {0};", completionPortThreads);
Console.Out.Flush();
Thread.Sleep(2000);
}
There is an action accepts HTTP GET request as below
public class DefaultController : ApiController
{
public HttpResponseMessage GET()
{
Console.WriteLine("Receive HTTP GET request");
Func<Stream, HttpContent, TransportContext, Task> func = (stream, httpContent, transportContext) =>
{
return Monitor(httpContent, stream);
};
HttpResponseMessage response = Request.CreateResponse();
response.StatusCode = HttpStatusCode.OK;
response.Content = new PushStreamContent(func, new MediaTypeHeaderValue("text/plain"));
return response;
}
async Task Monitor(HttpContent httpContent, Stream stream)
{
try
{
using (StreamWriter sw = new StreamWriter(stream, new UTF8Encoding(false)))
{
for (;;)
{
sw.WriteLine(Guid.NewGuid().ToString());
sw.Flush();
await Task.Delay(1000);
}
}
}
catch (CommunicationException ce)
{
HttpListenerException ex = ce.InnerException as HttpListenerException;
if (ex != null)
{
Console.WriteLine("HttpListenerException occurs, error code = {0}", ex.ErrorCode);
}
else
{
Console.WriteLine("{0} occurs : {1}", ce.GetType().Name, ce.Message);
}
}
catch (Exception ex)
{
Console.WriteLine("{0} occurs : {1}", ex.GetType().Name, ex.Message);
}
finally
{
stream.Close();
stream.Dispose();
httpContent.Dispose();
Console.WriteLine("Dispose");
}
}
}
Open the url http://127.0.0.1:54781/ and I see progressive response comming.
But If the client terminates the connection when the server is sending the response, the completion port thread is taken up and never released.
It able to bring down the application by exhausting the completion port threads pool.
After changing to OWIN self-hosting, this problem disappears. It seems a bug in System.Web.Http.SelfHost
Here is updated code:
class Program
{
static void Main(string[] args)
{
var server = WebApp.Start<Startup>(url: "http://*:54781");
for (;;)
{
int workerThreads, completionPortThreads;
ThreadPool.GetAvailableThreads(out workerThreads, out completionPortThreads);
Console.WriteLine("Worker Threads = {0}; Available Completion Port Threads = {1};", workerThreads, completionPortThreads);
Console.Out.Flush();
Thread.Sleep(2000);
}
}
}
public class Startup
{
// This code configures Web API. The Startup class is specified as a type
// parameter in the WebApp.Start method.
public void Configuration(IAppBuilder appBuilder)
{
// Configure Web API for self-host.
HttpConfiguration config = new HttpConfiguration();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "{controller}",
defaults: new { #controller = "Default" }
);
appBuilder.UseWebApi(config);
}
}
For others coming to this post there is a similar issue in System.Web.Http.SelfHost which by default uses CPU Cores * 100 threads which is the same as the default ThreadPool limit ending in a deadlock as Mono pre-creates all the threads.
The easiest way to get around this is to set the MONO_THREADS_PER_CPU environment variable to a value greater than 1 or use the --server flag when running the Mono application.

Win Phone 8.1 : OutOfMemory Exception while downloading large files (30 MB)

I am creating a universal Windows Phone 8.1 App. I am trying to download the file and view it into launcher. I works for small file less than 15 MB files. But when file size is more than 15 MB, I got the out of memory exception.
async private Task<object> GetMailAttachments(string attachNotify)
{
try
{
cmdBarMailItem.IsEnabled = false;
if (await Device.IsNetworkAvailable())
{
cts = new CancellationTokenSource();
// Ignore SSL Certificate which is untrusted,expired and has invalid hostname.
var filter = new HttpBaseProtocolFilter() { AllowUI = false };
filter.IgnorableServerCertificateErrors.Add(Windows.Security.Cryptography.Certificates.ChainValidationResult.Untrusted);
filter.IgnorableServerCertificateErrors.Add(Windows.Security.Cryptography.Certificates.ChainValidationResult.Expired);
filter.IgnorableServerCertificateErrors.Add(Windows.Security.Cryptography.Certificates.ChainValidationResult.InvalidName);
// Start calling the soap service #userGetAttachmentByIndex
using (var client = new System.Net.Http.HttpClient(new WinRtHttpClientHandler(filter)))
{
//Prepare parameters which is to be post via soap envelope.
List<KeyValuePair<string, string>> parameter = new List<KeyValuePair<string, string>>();
parameter.Add(new KeyValuePair<string, string>("sessionId", GlobalInfo.SessionID));
parameter.Add(new KeyValuePair<string, string>("attachmentIndex", attachNotify.Split('|')[1].ToString()));
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("text/xml"));
client.DefaultRequestHeaders.Add("SOAPAction", "userGetAttachmentByIndex");
var postContent = new StringContent(StringHelper.ConstructSoapRequest(parameter, "userGetAttachmentByIndex"), Encoding.UTF8, "text/xml");
// Getting response from soap service
var response = await client.PostAsync(new Uri(AppEnv.ServiceEndPoint), postContent, cts.Token);
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
string soapResponse = await response.Content.ReadAsStringAsync();
var soap = XDocument.Parse(soapResponse);
XNamespace ns = "http://service.webservice.cryoserver.ci";
var base64BinaryStr = soap.Descendants(ns + "userGetAttachmentByIndexResponse").First().Descendants(ns + "return").First().Descendants(ns + "attachmentType").First().Descendants(ns + "binaryData").First().Descendants(ns + "base64Binary").First().Value;
await saveStringToLocalFile(base64BinaryStr);
var file = await Windows.Storage.ApplicationData.Current.LocalFolder.GetFileAsync("myTest.pdf");
bool x = await Windows.System.Launcher.LaunchFileAsync(file);
return x;
}
}
}
cmdBarMailItem.IsEnabled = true;
}
catch (TaskCanceledException)
{
PopupRetrieve.IsOpen = false;
ProgressBar.IsVisible = false;
cmdBarMailItem.IsEnabled = true;
}
catch(Exception ex)
{
cmdBarMailItem.IsEnabled = true;
ProgressBar.IsVisible = false;
MessageBox.Show(AlertType.Connectivity);
}
return null;
}
async Task saveStringToLocalFile(string content)
{
try
{
// saves the string 'content' to a file 'filename' in the app's local storage folder
// byte[] fileBytes = System.Text.Encoding.UTF8.GetBytes(content.ToCharArray());
byte[] byteArray = Convert.FromBase64String(content);
// create a file with the given filename in the local folder; replace any existing file with the same name
StorageFile file = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync("myTest.pdf", CreationCollisionOption.ReplaceExisting);
// write the char array created from the content string into the file
using (var stream = await file.OpenStreamForWriteAsync())
{
stream.Write(byteArray, 0, byteArray.Length);
stream.Flush();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
I got the exception on executing the line
string soapResponse = await response.Content.ReadAsStringAsync();
Anybody have an idea why the exception occurs ? What could be possible solution to fix it.
Any help would be appriciable. :)

HTTP Requests in Glass GDK

I am implementing a GDK application and need to do in my application some HTTP Post requests. Do I send the HTTP requests the same way as on android phone or there is some other way of doing it? (I have tried the code that I am using on my phone and it's not working for glass.)
thanks for your help in advance.
You can make any post request like in smartphones, but ensure you make the requests using an AsyncTask.
For example:
private class SendPostTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
// Make your request POST here. Example:
myRequestPost();
return null;
}
protected void onPostExecute(Void result) {
// Do something when finished.
}
}
And you can call that asynctask anywhere with:
new SendPostTask().execute();
And example of myRequestPost() may be:
private int myRequestPost() {
int resultCode = 0;
String url = "http://your-url-here";
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(url);
// add headers you want, example:
// post.setHeader("Authorization", "YOUR-TOKEN");
List<NameValuePair> urlParameters = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("id", "111111"));
nameValuePairs.add(new BasicNameValuePair("otherField", "your-other-data"));
try {
post.setEntity(new UrlEncodedFormEntity(urlParameters));
HttpResponse response = client.execute(post);
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + post.getEntity());
System.out.println("Response Code : " +
response.getStatusLine().getStatusCode());
resultCode = response.getStatusLine().getStatusCode();
BufferedReader rd = new BufferedReader(
new InputStreamReader(response.getEntity().getContent()));
StringBuffer result = new StringBuffer();
String line = "";
while ((line = rd.readLine()) != null) {
result.append(line);
}
System.out.println(result.toString());
} catch (Exception e) {
Log.e("POST", e.getMessage());
}
return resultCode;
}

Create Registrant using GoToWebinar

I want to create a registrant for a webinar using GoToWebinar API's. I came across the code at gotowebinar api php
I provided my username and password to get the oAuth object. This worked perfectly fine as described.
Now I want to do something like this:
I have a Registration page. When user fills in the required details, selects the 'register to webinar' option and clicks on 'Submit', I want to enrol him for that webinar using CreateRegistrant API. The problem is, I am not able to get the oAuth object without providing username and password. Is there a way to pass this programatically and create oAuth object?
I store my API key, UserID and password in my WebConfig then read them into a Login Object for use when I do authorization. Here's how I do it in C#:
public class Login
{
public string UserId
{ get { return System.Configuration.ConfigurationManager.AppSettings["GTWUserId"]; } }
public string Password
{ get { return System.Configuration.ConfigurationManager.AppSettings["GTWPassword"]; } }
public string APIKey
{ get { return System.Configuration.ConfigurationManager.AppSettings["GTWAPIKey"]; } }
}
public string DoAuthorize()
{
Login lg = new Login();
string sError = "";
// first we need to create the uri for the web request
string uri = String.Format("https://api.citrixonline.com/oauth/access_token?grant_type=password&user_id={0}&password={1}&client_id={2}",
lg.UserId, lg.Password, lg.APIKey);
// then the request to login is created and sent. From the response
// we need to store at least the access token and the organizer key
// to use for further calls
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
request.Accept = "application/json";
request.ContentType = "application/json";
try
{
var response = request.GetResponse();
//the following lines duplicate the response stream so we can read it for
//deserialization and also re-read it and write it out.
using (MemoryStream ms = new MemoryStream())
{
var stream = response.GetResponseStream();
stream.CopyTo(ms);
ms.Position = 0;
stream.Close();
DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(ResponseDirectLogin));
var deserialized = (ResponseDirectLogin)ser.ReadObject(ms);
auth.OauthToken = deserialized.AccessToken;
auth.OrganizerKey = deserialized.OrganizerKey;
}
}
catch (WebException e)
{
using (var sr = new StreamReader(e.Response.GetResponseStream()))
sError = sr.ReadToEnd();
sError = String.Concat(sError, "/n", uri);
}
return sError;
}
public class Auth {
public string OauthToken { get; set; }
public string OrganizerKey { get; set; }
}
public static Auth auth = new Auth(); // This is actually in a BaseControlelr inherited by our MVC Home Controller.
public string DoRegister(string WebinarKey)
{
// Here we authorize if we haven't alerady
if (auth.OauthToken == null)
{
sMessage = DoAuthorize();
}
// first we need to create the uri for the web request
// OrganizerKey is your authorization key for the webinar organizer
string uri = String.Format(#"https://api.citrixonline.com/G2W/rest/organizers/{0}/webinars/{1}/registrants",
OrganizerKey, WebinarKey);
//then create and serialize the registrant object
// This is for when you have questions on your webinar, you can omit them if you don't have any
List<questions> q = GetQuestionKeys(Key, OrganizerKey);
List<response> responses_ = new List<response>();
foreach (var question in q)
{
response res1 = new response();
res1.questionKey = question.questionKey;
// determine which question and set the response
if (question.question == "question")
{
res1.responseText = "response";
responses_.Add(res1);
}
}
var registrant = new Registrant
{
firstName = FirstName,
lastName = LastName,
email = EmailAddress,
responses = responses_.ToArray()
};
JavaScriptSerializer ser = new JavaScriptSerializer();
string json = ser.Serialize(registrant);
// then the request to create a registrant is created and sent
// N.B. we need to include the access token to the headers to access
// the user's account and data
try {
WebClient client = new WebClient();
client.Headers = new WebHeaderCollection();
client.Headers.Add("Accept", "application/vnd.citrix.g2wapi-v1.1+json");
client.Headers.Add("Content-type", "application/json");
client.Headers.Add("Authorization", string.Format("OAuth oauth_token={0}", OAuthToken));
try
{
string resp = client.UploadString(uri, "POST", json);
var ok = ser.Deserialize<ResponseCreateRegistrantOk>(resp);
}
catch (WebException e)
{
//if there is an error, e.g. the registrant exists already
// we need an alternative deserialization
Stream s = new MemoryStream();
using (Stream response = e.Response.GetResponseStream())
{
byte[] buffer = new byte[1024];
int byteCount;
do
{
byteCount = response.Read(buffer, 0, buffer.Length);
s.Write(buffer, 0, byteCount);
} while (byteCount > 0);
}
s.Seek(0, SeekOrigin.Begin);
string content = new StreamReader(s, Encoding.UTF8).ReadToEnd();
s.Seek(0, SeekOrigin.Begin);
using (var err = new StreamReader(s))
{
var sb = new StringBuilder("Registration Error\n");
if (content.IndexOf("int_err_code") > -1)
{
var dupe = ser.Deserialize<ResponseCreateRegistrantDuplicate>(err.ReadToEnd());
sb.AppendFormat(String.Format("Error Code: {0}<br />", dupe.ErrorCode));
sb.AppendFormat(String.Format("Message: {0}<br />", dupe.Message));
}
else
{
var dupe = ser.Deserialize<ResponseCreateRegistrantDuplicate>(err.ReadToEnd());
sb.AppendFormat(String.Format("Description: {0}<br />", dupe.Description));
//sb.AppendFormat(String.Format("Incident: {0}<br />", dupe.Incident));
//sb.AppendFormat(String.Format("Registrant key: {0}<br />", dupe.RegistrantKey));
sb.AppendFormat(String.Format("Join Url: {0}<br />", dupe.JoinUrl));
}
sMessage = sb.ToString();
}
}
} catch (Exception exc) {
exc.Data.Add("stringInfo", "inside");
return "";
}
return sMessage;
}