I am working on a final project in my school and there are a lot of new things to discover. We will make an API that will use Google Cloud APIs and deployment to Azure.
I have not gotten anywhere just googling this, it looks like everyone just uses one service or another but not together.
I have a basic .net Core API program with the initial controller, ValuesController. After getting the ServiceKey from Google Cloud, I used one of their basic tutorial code for calling the Vision API with an image. My problem is that everything works on localhost but after deploying the site to Azure and calling that controller in the browser, Azure site always gives me 500 internal server error:
Failed to load resource:
the server responded with a status of 500
(Internal Server Error).
I tried to setup a debug for Azure but with no success.
`[Route("api/sleepy")]
[ApiController]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
List<String> da = new List<String>();
var client = ImageAnnotatorClient.Create();
var image = Image.FromFile("shit.png");
var response = client.DetectLabels(image);
foreach (var annotation in response)
{
if (annotation.Description != null)
{
Console.WriteLine(annotation.Description);
da.Add(annotation.Description);
}
}
foreach (var stuff in da)
{
Console.WriteLine(stuff);
}
System.Threading.Thread.Sleep(5000);
return Ok(da);
} `
When I just return a string or something else from my GET in ValueController, that works on the Azure site, I do not understand this problem of mine, localhost gets the right information but something is missing since it does not work on the Azure deployed site.
The site i have been trying this with is:
https://webapplication220190211113216.azurewebsites.net/api/sleepy. It is just temporary to test this. THe image shit.png is a picture of a dog and located in the root of the project.
What am i missing here? I would be very greatful if someone could at least guide me in the right directions, I have found no answers on google. :)
EDIT:
I managed to find a workaround by using regular Http requests, it would still be interesting to hear the reasons for why using the client libraries result in 500 error on Azure. :)
Related
I'm the middleman on an integration project between a Woocommerce site and a retail POS system. The POS is trying to synchronize products with the Woocommerce store. The site has an SLL certificate so all communication is over SSL. The POS vendor tells me they are using TLS1.2. We have a URL that contains a customer key and secret so I can't paste the full URL here, but the problem is as follows...
The same URL pasted directly into the browser works perfectly well, returning the expected JSON payload. The same URL used with a .NET WebClient or HttpClient returns a 401 Not Authorized error. Here is an example of an integration test using WebClient;
[Test]
public void DownloadString_UsingWebClient_ReturnsNonEmptyResponse()
{
using (var client = new WebClient())
{
var response = client.DownloadString("https://demostore.mycompany.com.au/wp-json/wc/v2/settings/tax/woocommerce_prices_include_tax?consumer_key=ck_xxxskeyxxx&consumer_secret=cs_xxxsecretxxx");
Assert.IsNotEmpty(response);
}
}
And here is a similar test using HttpClient;
[Test]
public async Task DownloadString_UsingHttpClient_ReturnsNonEmptyResponse()
{
using (var client = new HttpClient())
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
var response = await client.GetStringAsync("https://demostore.mycompany.com.au/wp-json/wc/v2/settings/tax/woocommerce_prices_include_tax?consumer_key=ck_xxxskeyxxx&consumer_secret=cs_xxxsecretxxx"");
Assert.IsNotEmpty(response);
}
}
Both tests never make it to the Assert. Just to reiterate, if I take the same URL and paste it into my browser, everything works as expected. I've tried a couple of different things, including enforcing the security protocol type (as in the latter example), but it is all just a poke in the dark, really.
The website is using the latest version of Wordpress, and it is in a shared linux hosting environment.
Is there something I'm missing with WebClient and HttpClient? Do I go back to the web hosting company and find out if there is something in the configuration that would prevent a .NET client from performing the same as a browser (I have logged a support ticket to this effect, but I'm not getting any headway)?
If you're in a corporate network and the browser works and your code doesn't, it's likely you're missing the Proxy settings for the WebClient or HttpClient instance.
I typically pass a HttpClientHandler instance with Preauthenticate = true and UseDefaultCredentials = true to the HttpClient.
I found that usually when something works in the browser, but not outside of it, that suggests that the API relies on User-Agent header being present in the request.
One of the reasons for this may be a reverse-proxy/firewall in front of that API.
I have a Web Api, I don't know why when I add new methods to it and I put my Web Api online the new methods are not recognized, if I run the application locally the methods are recognized, I'm using somee.com to upload and run my application online, for example if I just add this simple method:
[HttpGet]
[System.Web.Mvc.ValidateInput(false)]
public IHttpActionResult TestJustGet()
{
var x = "new method tested";
return Ok(x);
}
and I run the application locally it is recognized(http://localhost:62852/api/people/testjustget)
But when I try to call that method with the online application is not recognized(http://testwebhook.somee.com/api/people/testjustget) and I get this error:
<Error>
<Message>
No HTTP resource was found that matches the request URI 'http://testwebhook.somee.com/api/people/testjustget'.
</Message>
</Error>
I think that the problem is that the online application it's not recognizing the new changes, maybe I'm not updating it the best way. What I am doing to update my application is delete the old one that I have online, and instead upload the new application with the new methods added, but those methods are not being recognized, what can I do?
It seems that I need to run locally my application first and then upload it to somee.com, after I began to do that, it has recognized all the new methods, I run it locally and try all the new methods locally first and then I upload it and works
I have made an Azure Mobile Service which works fine locally.
I then publish the Azure mobile Service to the cloud and the website shows that it is currently running.
I then make a GET Request to my published website and it returns the following:
Status 500 Internal Server Error 500 Internal Server Error A generic
error message, given when no more specific message is suitable
{ "message": "An error has occurred." }
I have tried adding:
<system.web>
<customErrors mode="Off"/>
</system.web>
To my Web.Config in the Site\wwwroot directory but this didn't do anything.
So how do I return a more meaningful error from my azure mobile service?
So turns out returning errors from a Web API is different to returning errors from Asp.net or iis
From this link I found the following:
Today Kurt and I were attempting to debug an Web API service we had
deployed to a remote machine. The service was returning 500 errors,
and for various reasons, we couldn’t just try to do the requests from
that deployed box. We wanted to get the full exception details in the
response, but we were just seeing blank 500 errors, with no responses.
We first tried the Web.Config setting for custom errors:
<customErrors mode="Off" />
But this didn’t affect anything. Digging a little further, we found
that ASP.NET Web API uses a different configuration for error details
being passed along. This is for a couple of reasons; first, the custom
errors element in the Web.Config is an ASP.NET thing. It’s something
that ASP.NET uses to determine if that yellow screen of death with
additional detail should be shown to users. However, ASP.NET Web API
is designed to be self-hosted, outside of ASP.NET and IIS. While the
customErrors element affects requests for ASPX and MVC, it does
nothing for Web API.
Instead of relying on a lot of XML configuration, Web API uses a lot
of programmatic configuration. This helps self hosting, but for
changing policies like error detail, we have to change the code,
re-compile and re-deploy. To set the error policy in our application,
we need to modify our global Web API configuration:
GlobalConfiguration.Configuration.IncludeErrorDetailPolicy
= IncludeErrorDetailPolicy.Always;
With this mode, requests from any source will get us full exception
detail. It’s likely not something we want in production, but nice that
it is available.
So in conclusion to view errors from a Web API you want to go to your Startup class where you will see a ConfigureMobileApp method.
This will include the line:
HttpConfiguration config = new HttpConfiguration();
and you want to add the following:
config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
The Azure Mobile Service handles all exceptions and raises an HttpResponseException with generic error message, if you want to get the detailed error message yo can do something like this:
// POST tables/TodoItem
public async Task<IHttpActionResult> PostTodoItem(TodoItem item)
{
try
{
TodoItem current = await InsertAsync(item);
return CreatedAtRoute("Tables", new { id = current.Id }, current);
}
catch (HttpResponseException ex)
{
string message = ((HttpError)((ObjectContent)ex.Response.Content).Value).First().Value.ToString();
string[] temp = message.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
var resp = new HttpResponseMessage(HttpStatusCode.BadRequest)
{
Content = new StringContent(message),
ReasonPhrase = temp[0]
};
throw new HttpResponseException(resp);
}
}
This article point me in the right direction
The simple goal here is to access the Xbox Music RESTful API on Azure and I stumble on the first part of it which is getting the Access Token. By following this procedure: http://msdn.microsoft.com/en-us/library/dn546686.aspx it's simply not allowing me to get a token.
Thus far I have:
I have a datamarket registration
I registered an application, got a client_id and client_secret
Subscribed to the Xbox Music RESTful API
Then I simply try to get a token either through a POST using XMLHttpRequest or Advanced Rest Client for Chrome and thus far all I receive is this Json response:
{
"error":"invalid_client",
"error_description":"ACS50012: Authentication failed.\r\nTrace ID: d2469189-d620-4725-98c6-544e3899d711\r\nCorrelation ID: 3726a6c7-de19-4873-a90c-b51c7ca447a7\r\nTimestamp: 2014-05-08 14:18:31Z"
}
I did some research for this error here: http://msdn.microsoft.com/en-us/library/gg429787.aspx but can't seem to pull an explanation for this.
The data explorer is also broken as I receive this:
The request resulted in a backend time out or backend error. The team is investigating the issue. We are sorry for the inconvenience. (502)
In the end I assume something is bogus with my account but can't figure it out. Any help with this would be greatly appreciated.
See comment, recreate a new application and copy client secret properly.
Please help, I'm trying to self-host a web api.
When the same controller is hosted on a web project, and run on dev, via F5, everything works well.
However now I'm trying to self-host the same, I'm getting 411 and 404. 411, when I use Fiddler to connect, 404 when I'm attempting to connect via another library.
This is the console app that's supposed to host the service:
class Program
{
static int portNumber;
static void Main(string[] args)
{
portNumber = 8089;
var config = new HttpSelfHostConfiguration(
string.Format("http://localhost:{0}", portNumber));
config.Routes.MapHttpRoute(
"API Default", "api/{controller}/{id}",
new { id = RouteParameter.Optional });
using (var server = new HttpSelfHostServer(config))
{
var test = new RetrieveGuidService().Execute(Unit.Instance);
server.OpenAsync().Wait();
Console.ReadLine();
}
}
}
This is what my controller looks like, it doesn't do anything it's just a test.
public class RetrieveGuidServiceController : ApiController
{
public virtual Guid PostExecute(Unit request)
{
IQueryService<Unit,Guid> queryService = new RetrieveGuidService();
return queryService.Execute(request);
}
}
And here's how I'm attempting to access it via fiddler:
The same works when the service is hosted on a web project. I have followed this tutorial almost to the letter: asp.net WebApi self host tutorial which includes running nugget scripts, adding dependencies, etc.
What am I still missing?
The 411 is because you didn't put the Content-Length header. Even if you are not sending content you need to include Content-Length: 0.
Regarding having the Controller in the correct assembly I have had inconsistent behaviour. In some projects it seems to work in other it doesn't. Not sure what I am doing wrong. I have a project here that does both Web Host and Self-Host with all the controllers in a different assembly and it works just fine.
It seems that by default, the services will not look for controllers in assemblies beyond the one hosting the services.
I think it's an omission, unless I'm reading the specs wropng.