UWP App deployment with C# and REST - c#

I want to deploy and install an .appxbundle with c# on a UWP(IoT) - Device.
The REST-API documentation is on this site.
My code is
public async static Task<bool> UploadApp(string ip, Stream upload, string fileName)
{
try
{
if (http == null)
GetHttp();
HttpContent content = new StreamContent(upload);
var param = new Dictionary<string, string> {
{ "package", fileName}
};
var urlparam = new FormUrlEncodedContent(param);
var urlVar = await urlparam.ReadAsStringAsync();
var response = await http.PostAsync(String.Format("http://{0}:8080/api/app/packagemanager/package?{1}", ip, urlVar), content);
return response.IsSuccessStatusCode;
}
catch
{
return false;
}
}
The code is not working. I get an "Bad request" Error after I send it and I don't know what to change. Could someone help me?
EDIT: The message I get is "Missing .appx (or .eappx) or .appinstaller file in uploaded files". I can deploy and install the package with ARC as "multipart/form-data".

Related

Why im getting "ComputerVisionOcrErrorException: Operation returned an invalid status code 'BadRequest'"

I'm trying to test the Computer Vision SDK for .NET.
For that i've created a Computer vision resource in azure.
I create a project in .NET6 and follow the Microsoft guide to implement the api call.
But when i reach the code line:
var textHeaders = await client.ReadAsync(urlFile);
i'm getting the exception:
ComputerVisionOcrErrorException: Operation returned an invalid status code 'BadRequest'
This is the complete code:
public static void ComputerVisionPOC()
{
// Add your Computer Vision subscription key and endpoint
const string subscriptionKey = "xxxxxxx";
const string endpoint = #"https://xxxx.cognitiveservices.azure.com/";
const string readTextUrlImage = "https://drive.google.com/file/d/xxxxxxxx/view?usp=sharing";
var client = Authenticate(endpoint, subscriptionKey);
// Extract text (OCR) from a URL image using the Read
ReadFileUrl(client, readTextUrlImage).Wait();
}
public static ComputerVisionClient Authenticate(string endpoint, string key)
{
var client =
new ComputerVisionClient(new ApiKeyServiceClientCredentials(key))
{ Endpoint = endpoint };
return client;
}
public static async Task ReadFileUrl(ComputerVisionClient client, string urlFile)
{
try
{
var textHeaders = await client.ReadAsync(urlFile);
// After the request, get the operation location (operation ID)
var operationLocation = textHeaders.OperationLocation;
Thread.Sleep(2000);
// Retrieve the URI where the extracted text will be stored from the Operation-Location header.
// We only need the ID and not the full URL
const int numberOfCharsInOperationId = 36;
var operationId = operationLocation[^numberOfCharsInOperationId..];
// Extract the text
ReadOperationResult results;
Console.WriteLine($"Extracting text from URL file {Path.GetFileName(urlFile)}...");
Console.WriteLine();
do
{
results = await client.GetReadResultAsync(Guid.Parse(operationId));
} while ((results.Status == OperationStatusCodes.Running ||
results.Status == OperationStatusCodes.NotStarted));
// Display the found text.
Console.WriteLine();
var textUrlFileResults = results.AnalyzeResult.ReadResults;
foreach (var page in textUrlFileResults)
{
foreach (var line in page.Lines)
{
Console.WriteLine(line.Text);
}
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
I will really apreciate any help on this!
A Bad request error(400) occurs when a request which has been sent to the website server is incorrect/mistyped or corrupt and if the server receiving the request fails to understand it.
There is a possibility that the URL which has been used in the code could be wrong/mistyped.
Re-check the URL in readTextUrlImage and provide the valid one.
const string readTextUrlImage = "https://drive.google.com/file/d/xxxxxxxx/view?usp=sharing";
I have reproduced the same code with valid URL and got the expected result.
Output:

Angular app stops receive an exception after publish

Here is a basic Asp net core application with angular 8, created from a visual studio's 2019 template.
Could someone explain
why when I receive an error from API and throw an exception at client's backend during debug session via Visual studio, method in component.ts receive that exception successfully.
But, after publish the app (publish to folder via VS2019, then copy files to IIS and convert to app)
, there is just a 500 error, but according log file my exception was throw.
component.ts has a method
createRelatedTask() {
if (this.validation()) {
this.taskService.createRelatedTask(this.relatedTask).subscribe(
result => {
this.router.navigate(['/home']);
},
error => {
this.showMessage(error.error, error.message);
});
}
}
taskService.ts has a method
createRelatedTask(relatedTask: RelatedTaskData) {
return this.http.post<RelatedTaskData>(this._baseUrl + 'TaskService/', relatedTask);
}
TaskServiceController
[HttpPost]
public async Task<RelatedTaskInfo> CreateRelatedTask(RelatedTaskInfo relatedTask)
{
var result = await _taskService.CreateRelatedTaskAsync(relatedTask);
return result;
}
TaskService
public async Task<RelatedTaskInfo> CreateRelatedTaskAsync(RelatedTaskInfo relatedTask)
{
using (var httpClient = new HttpClient())
{
var apiClient = new RelatedTaskClient(httpClient) { BaseUrl = _relatedTaskApiSettings.ApiAddress };
var dto = Map(relatedTask);
try
{
var response = await apiClient.CreateRelatedTaskAsync(dto);
var result = Map(response);
return result;
}
catch (ApiException e)
{
var text = System.Text.RegularExpressions.Regex.Unescape(e.Response);
throw new Exception(text);
}
catch
{
throw;
}
}
}
while running via VisualStudio
when published to IIS

View not found due to await GetAsync

The view 'Search' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Views/Home/Search.aspx
~/Views/Home/Search.ascx
~/Views/Shared/Search.aspx
~/Views/Shared/Search.ascx
~/Views/Home/Search.cshtml
~/Views/Home/Search.vbhtml
~/Views/Shared/Search.cshtml
~/Views/Shared/Search.vbhtml
I am working on a basic web application that reads data from an api. When I run the solution and try to access the view referenced by this controller from the code below, I get this error. I have narrowed it down to being the GetAsync line of code. This works on windows however does not work on my Mac.
From what I can find, the cross platform .net framework Mono, used by visual studio on OSX, does not support GetAsync. What are my options if I want to develop/test this on my Mac but also deploy on a azure server?
public async Task<ActionResult> Search(string ticker)
{
using (var client = new HttpClient())
{
client.BaseAddress = new Uri(demoapiurl);
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
try
{
HttpResponseMessage res = await client.GetAsync(string.Format("{0}&symbol={1}&apikey={2}", apiurl, ticker, apikey));
if (res.IsSuccessStatusCode)
{
var accResponse = res.Content.ReadAsStringAsync().Result;
var quotes = GettingStarted.FromJson(accResponse);
GettingStarted allquotes = JsonConvert.DeserializeObject<GettingStarted>(accResponse);
return View(allquotes);
}
}
catch (Exception ex)
{
Console.WriteLine("Exception Message: " + ex.Message);
}
}
return View();
}

The remote server returned an error: (410) Gone in C#

I have a web API2 application which is consumed by a third party application. When the application hits my end-point, my application send oAuth credentials for authentication and gets the results from the third party application.
Recently some of the transactions are failing and when i added some logs, i saw that the error: The remote server returned an error: (410) Gone is occurring for all failed transactions. Unfortunately I am unable to reproduce this issue when I am calling my application. The following is the code that I am using. What could be the issue that is causing this error?
public async Task<customerModel> SendSigned(string url)
{
customerModel customermodel = null;
try
{
OAuthBase oauthBase = new OAuthBase();
string oAuthKey = ConfigurationManager.AppSettings["oAuthKey"];
string oAuthSecret = ConfigurationManager.AppSettings["oAuthSecret"];
string timestamp = oauthBase.GenerateTimeStamp();
string nonce = oauthBase.GenerateNonce();
string normalizedUrl;
string normalizedRequestParameters;
string sig = HttpUtility.UrlEncode(oauthBase.GenerateSignature(
new Uri(url), oAuthKey, oAuthSecret, string.Empty, string.Empty,
"GET", timestamp, nonce, out normalizedUrl, out normalizedRequestParameters));
string requestUrl = String.Format("{0}?{1}&oauth_signature={2}", normalizedUrl, normalizedRequestParameters, sig);
HttpWebRequest request = null;
request = (HttpWebRequest)HttpWebRequest.Create(requestUrl);
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
myXMLDocument = new XmlDocument();
customermodel = GetCustomerInformation(response);
}
return await Task.Run(() => customermodel);
}
catch (Exception ex)
{
_logger.Error("Error in SendSigned method", ex.InnerException);
return customermodel;
}
}
The explanation of 410 is The target resource is no longer available at the origin server and that this condition is likely to be permanent based on
this link (similar to a 404)
I would suggest you to think about recent changes you made to your
API signatures
Folder restructure/reorganization of assets/resources
Routing changes
Rename of resources

GetAsync azure call no result

Using VS 2017 Community. Azure.
I have Azure setup, I have a blank webapp created just for test purpose.
My actual site is an Angular2 MVC5 site, currently run locally.
The following is the code that should... Contact azure providing secret key(the site is registered in azure Active directory).
From this i get a token i then can use to contact azure api and get list of sites.
WARNING: code is all Sausage code/prototype.
Controller
public ActionResult Index()
{
try
{
MainAsync().ConfigureAwait(false);
}
catch (Exception e)
{
Console.WriteLine(e.GetBaseException().Message);
}
return View();
}
static async System.Threading.Tasks.Task MainAsync()
{
string tenantId = ConfigurationManager.AppSettings["AzureTenantId"];
string clientId = ConfigurationManager.AppSettings["AzureClientId"];
string clientSecret = ConfigurationManager.AppSettings["AzureClientSecret"];
string token = await AuthenticationHelpers.AcquireTokenBySPN(tenantId, clientId, clientSecret).ConfigureAwait(false);
using (var client = new HttpClient())
{
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);
client.BaseAddress = new Uri("https://management.azure.com/");
await MakeARMRequests(client);
}
}
static async System.Threading.Tasks.Task MakeARMRequests(HttpClient client)
{
const string ResourceGroup = "ProtoTSresGrp1";
// Create the resource group
// List the Web Apps and their host names
using (var response = await client.GetAsync(
$"/subscriptions/{Subscription}/resourceGroups/{ResourceGroup}/providers/Microsoft.Web/sites?api-version=2015-08-01"))
{
response.EnsureSuccessStatusCode();
var json = await response.Content.ReadAsAsync<dynamic>().ConfigureAwait(false);
foreach (var app in json.value)
{
Console.WriteLine(app.name);
foreach (var hostname in app.properties.enabledHostNames)
{
Console.WriteLine(" " + hostname);
}
}
}
}
Controller class uses a static helper class that gets the token from Azure...
public static class AuthenticationHelpers
{
const string ARMResource = "https://management.core.windows.net/";
const string TokenEndpoint = "https://login.windows.net/{0}/oauth2/token";
const string SPNPayload = "resource={0}&client_id={1}&grant_type=client_credentials&client_secret={2}";
public static async Task<string> AcquireTokenBySPN(string tenantId, string clientId, string clientSecret)
{
var payload = String.Format(SPNPayload,
WebUtility.UrlEncode(ARMResource),
WebUtility.UrlEncode(clientId),
WebUtility.UrlEncode(clientSecret));
var body = await HttpPost(tenantId, payload).ConfigureAwait(false);
return body.access_token;
}
static async Task<dynamic> HttpPost(string tenantId, string payload)
{
using (var client = new HttpClient())
{
var address = String.Format(TokenEndpoint, tenantId);
var content = new StringContent(payload, Encoding.UTF8, "application/x-www-form-urlencoded");
using (var response = await client.PostAsync(address, content).ConfigureAwait(false))
{
if (!response.IsSuccessStatusCode)
{
Console.WriteLine("Status: {0}", response.StatusCode);
Console.WriteLine("Content: {0}", await response.Content.ReadAsStringAsync());
}
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsAsync<dynamic>().ConfigureAwait(false);
}
}
}
}
ISSUE:
Ok so the issue I was faced with was Async Deadlocks in my code. So i looked at this stack post stack post here
I fixed the issues by putting in .ConfigureAwait(false) on most of the await declarations.
Code runs and gets all the way back to the controller with a token etc and runs through the MakeARMRequests(HttpClient client) method, however the json only returns 1 result "{[]}" when i debug and as such ignores the loops.
My question is, is my code the culprit here? or would this point to a configuration setting in azure?
Not sure if this is the issue you are facing now BUT you never wait for a result from your async action in the first method Index in your code. MainAsync().ConfigureAwait(false); will immediately return and continue to the next block while the task MainAsync() will start in the background. The catch handler also does nothing because you dont wait f or a result.
Option 1 (recommended)
public async Task<ActionResult> Index()
{
try
{
await MainAsync().ConfigureAwait(false);
}
catch (Exception e)
{
Console.WriteLine(e.GetBaseException().Message);
}
return View();
}
Option 2 if you can't use async/await for some reason
public ActionResult Index()
{
try
{
MainAsync().GetAwaiter().GetResult();
}
catch (Exception e)
{
Console.WriteLine(e.GetBaseException().Message);
}
return View();
}
The Code looks OK and runs fine, Anyone who could help verify would be good, but one can assume this is OK.
The issue for this was configuration in azure, When you register an app you must set a certain number of Access controls via the subscription.
In this case I set some more specific things for the web api , for now set the app as owner and made reference to service management api.
Probably don't need half the "IAM" added in the subscription to the registered app, I simply went through adding the relevant ones and debugging each time until finally i got the results expected.

Categories