I'm trying to test sending a request to Document AI using .NET framework. I didn't see any info specific to .NET on the formal Google explanations for using client libraries.
So far this is what I came up with:
public void Test()
{
var documentProcessorServiceClient = new DocumentProcessorServiceClientBuilder
{
Endpoint = "us-documentai.googleapis.com"
}.Build();
ProcessRequest request = new ProcessRequest
{
SkipHumanReview = false,
RawDocument = new RawDocument
{
MimeType = "application/pdf",
Content = ByteString.CopyFrom(bytesArray); // bytesArray of some file
}
};
try
{
ProcessResponse response = documentProcessorServiceClient.ProcessDocument(request);
Document docResponse = response.Document;
Console.WriteLine(docResponse.Text);
}
catch (Exception ex)
{
throw;
}
}
My questions are:
Why I always get the following exception:
"Error starting gRPC call. HttpRequestException: Unable to get subchannel from HttpRequestMessage."
How do I authenticate using a key instead of using OAuth2?
Thanks.
Successfully send the request with authentication.
Related
I have a app that uses boiler plate code from aws ses docs https://docs.aws.amazon.com/ses/latest/dg/send-an-email-using-sdk-programmatically.html. This is my EmailSender.cs file:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Amazon;
using Amazon.Runtime;
using Amazon.SimpleEmail;
using Amazon.SimpleEmail.Model;
using Microsoft.AspNetCore.Identity.UI.Services;
using Microsoft.Extensions.Options;
namespace amaranth.Helpers
{
public class EmailSender : IEmailSender
{
private ApiEndpoints _endpoints;
public EmailSender(IOptions<ApiEndpoints> _options)
{
_endpoints = _options.Value;
}
public async Task SendEmailAsync(string email, string subject, string htmlMessage)
{
using (var client = new AmazonSimpleEmailServiceClient(RegionEndpoint.USEast1))
{
var sendRequest = new SendEmailRequest
{
Source = "<A DOMAIN THAT I DO OWN>",
Destination = new Destination
{
ToAddresses =
new List<string> { email }
},
Message = new Message
{
Subject = new Content(subject),
Body = new Body
{
Html = new Content
{
Charset = "UTF-8",
Data = htmlMessage
}
}
},
// If you are not using a configuration set, comment
// or remove the following line
//ConfigurationSetName = configSet
};
try
{
Console.WriteLine("Sending email using Amazon SES...");
var response = await client.SendEmailAsync(sendRequest);
Console.WriteLine("The email was sent successfully.");
}
catch (Exception ex)
{
Console.WriteLine("The email was not sent.");
Console.WriteLine("Error message: " + ex.Message);
}
}
}
}
}
My variables email, subject and htmlMessage are all properly formatted. Also I verified the domain (represented with <A DOMAIN THAT I DO OWN> in the code). See here:
I am also out of the sandbox and I even created an IAM user to handle email:
But when I run my app, the email isn't sent and I get this error: Error message: Unable to get IAM security credentials from EC2 Instance Metadata Service.
I am not sure what the problem is but I noticed that I'm not really declaring my credentials anywhere. But... I don't even know where I would put the credentials. The amazon ses docs don't really appear to specify where the credentials go. Can somebody show me where I'm going wrong and where my credentials go?
UPDATE:
I added a BasicAWSCredentials where _endpoints.EmailUsername is my "Access key ID" and _endpoints.EmailPassword" is my Secret Access Key for the user I created specifically for this app.
var awsCreds = new BasicAWSCredentials(_endpoints.EmailUsername, _endpoints.EmailPassword);
using (var client = new AmazonSimpleEmailServiceClient(awsCreds, RegionEndpoint.USEast1))
But I got this error:
Error message: The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.
I was able to get this working. It was a strange fix. First I added my credentials to the code:
AWSCredentials awsCreds = new BasicAWSCredentials(_endpoints.EmailUsername, _endpoints.EmailPassword);
using (var client = new AmazonSimpleEmailServiceClient(awsCreds, RegionEndpoint.USEast2))
But then I got this error: The request signature we calculated does not match the signature you provided. This was the difficult error to get around. I tried a lot of stuff but then I came across this post https://adithya.dev/aws-signaturedoesnotmatch-error/. I generated another credential for my aws user that had a + closer to the end of the name and then it worked perfectly. I think this is a weird bug in the C# (and possibly other languages) AWS code.
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:
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
I have created a WCF Web Service using this walk through:
http://mikesknowledgebase.com/pages/Services/WebServices-Page2.htm
It returns data from a local SQL Server. The WCF Web Service takes a string parameter, and returns it back, as a string in JSON format.
I have now created a client website where i want to use the WCF Services as my data source to output the information in the database through a grid view or something similar. How do i do this? I assume i have to use some c#.
Service.cs:
public class Service : IService
{
private object cds;
public List<cdInfo> GetCDinfo()
{
try
{
CdDataClassesDataContext dc = new CdDataClassesDataContext();
List<cdInfo> results = new List<cdInfo>();
foreach (cd cD in dc.cds)
{
results.Add(new cdInfo()
{
Id = cD.Id.ToString(),
artist = cD.artist,
genre = cD.genre,
title = cD.title,
date = cD.date
});}
return results;
}
catch (Exception ex)
{
// Return any exception messages back to the Response header
OutgoingWebResponseContext response = WebOperationContext.Current.OutgoingResponse;
response.StatusCode = System.Net.HttpStatusCode.InternalServerError;
response.StatusDescription = ex.Message.Replace("\r\n", "");
return null;}}}
Hopefully this link will help you in consuming WCF service.
https://msdn.microsoft.com/en-us/library/bb412178(v=vs.110).aspx
I've made a .NET service in C# that can be accessed via
http://localhost:2586/Service1.asmx/AddPackage?username=acesda&description=no%20Description&state=New&location=Home
If I use the browser, The service works fine and I can see the XML result in browser.
But, if I use the following code in a Java application, I get an HTTP 400 error:
Server returned HTTP response code: 400 for URL: http://localhost:2586/Service1.asmx/AddPackage?adminName=admin&sessionID=1388849172471&packageOwner=user&description=iPhone 4s&state=new&location=iPhone 4s
Code:
try {
String parameters = String.format(PARAMETERS_TEMPLATE, adminName, sessionID, packageOwner, description, packageState, description, location);
String url = String.format(PACKAGE_URL_TEMPLATE, "AddPackage", parameters);
Document responseDocument = Utils.getRemoteXML(url, 1000);
properties.put("success", Utils.isSuccesfull(responseDocument));
properties.put("failReason", Utils.getMessage(responseDocument));
} catch (Exception e) {
properties.put("success", "false");
properties.put("failReason", e.getMessage());
}
public static Document getRemoteXML(String url, int timeout) throws Exception {
URLConnection connection = new URL(url).openConnection();
connection.setConnectTimeout(timeout);
SAXBuilder builder = new SAXBuilder();
Document document = (Document) builder.build(connection.getInputStream());
return document;
}
I must notice that I copied the address from exception, and it works in browser.
Thank you.