Form Field is null using Form recognizer - c#

We are trying to extract data from a checkbox using the Form recognizer. We have a custom model where we extract 4 fields. All fields get extracted except one ("has_observations").
We used the analyze tab on fott-2-1.azurewebsites.net and it shows correctly for all the files we are trying to do OCR on.
private static FormField GetField(this RecognizedFormCollection forms, string fieldName)
{
FormField field = null;
foreach (RecognizedForm form in forms)
{
if (form.Fields.ContainsKey(fieldName) && form.Fields[fieldName] != null)
{
field = form.Fields[fieldName];
logger.LogWarning("values is=" + field.ValueData.ToString());
break;
}
}
return field;
}
The field is "Azure.AI.FormRecognizer.Models.FormField" for "has_observations" label everytime and we have no idea how to fix it.

Which version of FormRecognizer SDK are you using? 3.1.1? You maybe calling different version from website vs from SDK.
If you are using 4.0.0-beta.X, by default it calls 2022-01-30-preview version of FormRecognizer APIs (see https://azuresdkdocs.blob.core.windows.net/$web/dotnet/Azure.AI.FormRecognizer/4.0.0-beta.3/index.html), but based on the screenshot you are using 2.1. So, API results maybe different between versions.
A few other troubleshooting options to see exact URLs and responses for http traffic from FormRecognizer SDK:
Logging with the Azure SDK for .NET, I.e. line below starts printing to the console each request/response.
var listener = AzureEventSourceListener.CreateConsoleLogger(EventLevel.Informational);
Some information will be redacted in logs. Changes to ClientOptions below will show more data (see details in Azure SDK diagnostics):
var frOptions = new FormRecognizerClientOptions() { Diagnostics = { IsLoggingContentEnabled = true, LoggedHeaderNames = { "*" }, LoggedQueryParameters = { "*" }}};
var client = new FormRecognizerClient(new Uri(endpoint), credential, frOptions);

Related

Cannot update read/write attributes of UserPoolClient via C# SDK

When programmatically creating a Cognito user pool and app client, if the app client is to have read/write access to attributes of the user pool, that access must be explicitly given. I have been able to do so successfully for custom attributes but built-in attributes always return an error of "Invalid write attributes specified while creating a client" or "Invalid read attributes specified while creating a client".
Documentation is ... both voluminous and difficult to find. I have yet to see an example of this or an actual bit of useful documentation on the CreateUserPoolClientRequest type that says anything about this other than things like "ReadAttributes is a list of strings that are the attributes that can be read".
Here is the code I'm using that always ends up with that error message and failure to create the app client. _client is an AmazonCognitoIdentityProviderClient properly instantiated and credentialed and running in a lambda function.
var request = new CreateUserPoolClientRequest { UserPoolId = userPoolId, ClientName = $"{name}AppClient" };
var builtInAttributes = new List<string>()
{
"address","birthdate","email","family name","gender","given name","locale","middle name","name","nickname","phone number", "picture","preferred username","profile","zoneinfo","updated at","website"
};
var readAttributes = new List<string>();
var writeAttributes = new List<string>();
readAttributes.InsertRange(0,builtInAttributes);
writeAttributes.InsertRange(0, builtInAttributes);
var attributeConfig = ConfigurationHelper.GetListFromSection("UserPoolCustomAttributes");
foreach (var attribute in attributeConfig)
{
readAttributes.Add($"custom:{attribute.Key}");
writeAttributes.Add($"custom:{attribute.Key}");
}
request.ReadAttributes = readAttributes;
request.WriteAttributes = writeAttributes;
var result = await _client.CreateUserPoolClientAsync(request, CancellationToken.None);
Any help is greatly appreciated.
Figured it out. Though I have yet to find it documented anywhere, default attributes with a space in the name in the ui need to have that space replaced with an underscore when using their name in the api.

How to get all installations when using Azure Notification Hubs installation model?

Using NotificationHubClient I can get all registered devices using GetAllRegistrationsAsync(). But if I do not use the registration model but the installation model instead, how can I get all installations? There are methods to retrieve a specific installation but none to get everything.
You're correct, as of July 2016 there's no way to get all installations for a hub. In the future, the product team is planning to add this feature to the installations model, but it will work in a different way. Instead of making it a runtime operation, you'll provide your storage connection string and you'll get a blob with everything associated with the hub.
Sorry for visiting an old thread... but in theory you could use the GetAllRegistrationsAsyc to get all the installations. I guess this will return everything without an installation id as well, but you could just ignore those if you choose.
Could look something like this
var allRegistrations = await _hub.GetAllRegistrationsAsync(0);
var continuationToken = allRegistrations.ContinuationToken;
var registrationDescriptionsList = new List<RegistrationDescription>(allRegistrations);
while (!string.IsNullOrWhiteSpace(continuationToken))
{
var otherRegistrations = await _hub.GetAllRegistrationsAsync(continuationToken, 0);
registrationDescriptionsList.AddRange(otherRegistrations);
continuationToken = otherRegistrations.ContinuationToken;
}
// Put into DeviceInstallation object
var deviceInstallationList = new List<DeviceInstallation>();
foreach (var registration in registrationDescriptionsList)
{
var deviceInstallation = new DeviceInstallation();
var tags = registration.Tags;
foreach(var tag in tags)
{
if (tag.Contains("InstallationId:"))
{
deviceInstallation.InstallationId = new Guid(tag.Substring(tag.IndexOf(":")+1));
}
}
deviceInstallation.PushHandle = registration.PnsHandle;
deviceInstallation.Tags = new List<string>(registration.Tags);
deviceInstallationList.Add(deviceInstallation);
}
I am not suggesting this to be the cleanest chunk of code written, but it does the trick for us. We only use this for debugging type purposes anyways

DisconnectedContext detected when using STA thread to modify SharePoint page

Background Info: I'm using an ItemCheckedIn receiver in SharePoint 2010, targeting .NET 3.5 Framework. The goal of the receiver is to:
Make sure the properties (columns) of the page match the data in a Content Editor WebPart on the page so that the page can be found in a search using Filter web parts. The pages are automatically generated, so barring any errors they are guaranteed to fit the expected format.
If there is a mismatch, check out the page, fix the properties, then check it back in.
I've kept the receiver from falling into an infinite check-in/check-out loop, although right now it's a very clumsy fix that I'm trying to work on. However, right now I can't work on it because I'm getting a DisconnectedContext error whenever I hit the UpdatePage function:
public override void ItemCheckedIn(SPItemEventProperties properties)
{
// If the main page or machine information is being checked in, do nothing
if (properties.AfterUrl.Contains("home") || properties.AfterUrl.Contains("machines")) return;
// Otherwise make sure that the page properties reflect any changes that may have been made
using (SPSite site = new SPSite("http://san1web.net.jbtc.com/sites/depts/VPC/"))
using (SPWeb web = site.OpenWeb())
{
SPFile page = web.GetFile(properties.AfterUrl);
// Make sure the event receiver doesn't get called infinitely by checking version history
...
UpdatePage(page);
}
}
private static void UpdatePage(SPFile page)
{
bool checkOut = false;
var th = new Thread(() =>
{
using (WebBrowser wb = new WebBrowser())
using (SPLimitedWebPartManager manager = page.GetLimitedWebPartManager(PersonalizationScope.Shared))
{
// Get web part's contents into HtmlDocument
ContentEditorWebPart cewp = (ContentEditorWebPart)manager.WebParts[0];
HtmlDocument htmlDoc;
wb.Navigate("about:blank");
htmlDoc = wb.Document;
htmlDoc.OpenNew(true);
htmlDoc.Write(cewp.Content.InnerText);
foreach (var prop in props)
{
// Check that each property matches the information on the page
string element;
try
{
element = htmlDoc.GetElementById(prop).InnerText;
}
catch (NullReferenceException)
{
break;
}
if (!element.Equals(page.GetProperty(prop).ToString()))
{
if (!prop.Contains("Request"))
{
checkOut = true;
break;
}
else if (!element.Equals(page.GetProperty(prop).ToString().Split(' ')[0]))
{
checkOut = true;
break;
}
}
}
if (!checkOut) return;
// If there was a mismatch, check the page out and fix the properties
page.CheckOut();
foreach (var prop in props)
{
page.SetProperty(prop, htmlDoc.GetElementById(prop).InnerText);
page.Item[prop] = htmlDoc.GetElementById(prop).InnerText;
try
{
page.Update();
}
catch
{
page.SetProperty(prop, Convert.ToDateTime(htmlDoc.GetElementById(prop).InnerText).AddDays(1));
page.Item[prop] = Convert.ToDateTime(htmlDoc.GetElementById(prop).InnerText).AddDays(1);
page.Update();
}
}
page.CheckIn("");
}
});
th.SetApartmentState(ApartmentState.STA);
th.Start();
}
From what I understand, using a WebBrowser is the only way to fill an HtmlDocument in this version of .NET, so that's why I have to use this thread.
In addition, I've done some reading and it looks like the DisconnectedContext error has to do with threading and COM, which are subjects I know next to nothing about. What can I do to prevent/fix this error?
EDIT
As #Yevgeniy.Chernobrivets pointed out in the comments, I could insert an editable field bound to the page column and not worry about parsing any html, but because the current page layout uses an HTML table within a Content Editor WebPart, where this kind of field wouldn't work properly, I'd need to make a new page layout and rebuild my solution from the bottom up, which I would really rather avoid.
I'd also like to avoid downloading anything, as the company I work for normally doesn't allow the use of unapproved software.
You shouldn't do html parsing with WebBrowser class which is part of Windows Forms and is not suited for web as well as for pure html parsing. Try using some html parser like HtmlAgilityPack instead.

C# Project Google map

For my studying and university I have a project where I need to make an application using C# WPF. This application must allow me to select a path between two adresses and show the path on the map like google map.
How can I implement the google webservice API ? I am a bit lost with it and I don't understand how I can make my application and fit in the google map itself.
With this i must be able to calculate the distance as well.
This is what i have done with the webBrowser but it displays the whole website of google maps:
I know that the WebBrowser control can display the google maps but it doesnt actually work
This is my code actually
private void btnCharger_Click(object sender, RoutedEventArgs e)
{
//Use static or WebControl we don't know yet.
//This is the case we use webControl
string street = "";
string city = "";
string zipcode = "";
StringBuilder adresseQuery = new StringBuilder();
adresseQuery.Append("http://maps.google.com/maps?q=");
street = tbStreet.Text.Replace(" ", "+");
adresseQuery.Append(street + ",+");
city = tbCity.Text;
adresseQuery.Append(city + ",+");
zipcode = tbZipCode.Text;
webBrowser1.Navigate(adresseQuery.ToString());*/
}
So in this code i have created the adresse and sent it to the webbrowser through google maps. But is shows the whole google map page with the left bar and everything. I would like to only display the map ! How can i only display the map and not the bars present on the https://maps.google.com/
I have already checked this Link and am currently working on it but this is static.
For the part of routing/getting the directions (and for some of others functions you need as well), you can use a .NET wrapper around Google Maps API:
GoogleApi
google-maps
gmaps-api-net is outdated (at this time of answering) - the last update for the Directions API was made in 2016.
Usage example for GoogleApi:
using GoogleApi.Entities.Common;
using GoogleApi.Entities.Maps.Directions.Request;
using GoogleApi.Entities.Maps.Directions.Response;
public void GetRoute()
{
DirectionsRequest request = new DirectionsRequest();
request.Key = "AIzaSyAJgBs8LYok3rt15rZUg4aUxYIAYyFzNcw";
request.Origin = new Location("Brasov");
request.Destination = new Location("Merghindeal");
var response = GoogleApi.GoogleMaps.Directions.Query(request);
Console.WriteLine(response.Routes.First().Legs.First().DurationInTraffic);
Console.WriteLine(response.Routes.First().Legs.First().Distance);
Console.WriteLine(response.Routes.First().Legs.First().Steps);
}

Processing PHP scripts from within C#

I'm not sure if this has even been done before, but what I am trying to accomplish can't be explained in any great detail, but basically, what I am trying to do is Process PHP scripts from within my C# Windows Forms Application.
I have already created a HTTP server, which works just fine. But now I need to be able to process PHP scripts aswell. We're working on a new privatised language over here, purely for learning and fun.
(Just a little background, not completely related):
We are now able to create a webpage like so:
Using System.Core,
System.Http,
System.Graphics and System.IO;
protected void -> Webpage(object homepage)
{
// Set Webpage properties.
homepage.Name = "Home";
homepage.Size = new Size(960[px], 100[%]);
homepage.Alignment = new AlignmentType.Vertical;
homepage.Alignment = new AlignmentType.Horizontal;
// This is a comment.
// Create objects to be rendered on the page.
Text text = new Text();
FormElements formElements = new FormElements();
private void -> Webpage.Load(object homepage)
{
text.Text = "Please enter your name below:";
text.Style = new Style(
Alignment = new AlignmentType.Horizontal,
Alignment = new AlignmentType.ManualAlignment(15[Y, px]),
Font = new Font(
Font.Family("Arial"),
Font.Size = new Size(9[pt], LineHeight(4[px])),
Font.Color = new Color.FromArgb(15, 15, 15))
);
formElements.CreateElements(TextField["textField"], SubmitButton["submitButton"], Form["form"]);
textField.Name = "name";
submitButton.Name = "submit";
form.Encapsulate(name, submit);
form.Alignment = new AlignmentType.RelativeTo(text.Bottom);
Elements[] elements = new Elements[]
{
text, form;
};
homepage.Display.Element.ElementCollection(elements);
}
private void -> Webpage.FormSubmission(object form)
{
form.Element(name).OmitSpecialCharacters();
if(form.Value is not Empty)
{
text.Text = "Hello, " + form.Element(name).Value;
}
}
}
The above sample demonstrates the ability to create a whole webpage, style it, and process form input in a nice, clean way. However, we've come to a complete dead end (trying to support PHP) and we do not wish to delve too far into server-side languages (lack of experience in that area is the main reason), so we would like to be able to "support" PHP scripts from within our WinForms app.
Anyone know of any way to process PHP scripts from within a C# winforms app?
Here is a simple http server that supports PHP:
MiniHttpd: an HTTP web server library
And here is Phalanger - The PHP Language Compiler for the .NET Framework
Use an HttpWebRequest, and request the url to the PHP page like you would to run the PHP page in your browser.
See here for more info: http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.aspx

Categories

Resources