Not Getting Line Items from "prebuilt-invoice" - .net-6.0

If I submit an invoice in the Form Recognizer Studio, it finds and presents the line items from the invoice.
If I then take that same invoice and submit it using the code from the Form Recognizer Studio, I do not get the line items in the JSON. I do get all the other data.
Any idea why?
<TargetFramework>net6.0</TargetFramework>
<PackageReference Include="Azure.AI.FormRecognizer" Version="4.0.0" />
public async Task<IActionResult> ProcessInvoice(IFormFile pdfInvoice) {
try {
string endpoint = "https://xxx.cognitiveservices.azure.com/";
string key = "xxx";
AzureKeyCredential credential = new AzureKeyCredential(key);
DocumentAnalysisClient client = new DocumentAnalysisClient(new Uri(endpoint), credential);
using var stream = pdfInvoice.OpenReadStream();
AnalyzeDocumentOperation operation = await client.AnalyzeDocumentAsync(WaitUntil.Completed, "prebuilt-invoice", stream);
AnalyzeResult result = operation.Value;
return Ok(JsonConvert.SerializeObject(result));
} catch (Exception ex) {
return BadRequest(ex.Message);
}
}

#VasaviLankipalle you are correct. What I was looking for was that the AnalyzeResult JSON would just include the line items without the extra step of iterating through them.
I did end up iterating through the line items and building my own JSON to send back from the controller.

Related

MVC6 Web Api - Return Plain Text

I have looked at other similar questions (such as this one Is there a way to force ASP.NET Web API to return plain text?) on SO but they all seem to address WebAPI 1 or 2, not the latest version you use with MVC6.
I need to return plain text on one of my Web API controllers. Only one - the others should keep returning JSON. This controller is used for dev purposes to output a list of records in a database, which will be imported into a traffic load generator. This tool takes CSV as input so I'm trying to output that (users will only have to save the content of the page).
[HttpGet]
public HttpResponseMessage AllProductsCsv()
{
IList<Product> products = productService.GetAllProducts();
var sb = new StringBuilder();
sb.Append("Id,PartNumber");
foreach(var product in products)
{
sb.AppendFormat("{0},{1}", product.Id, product.PartNumber);
}
HttpResponseMessage result = new HttpResponseMessage(HttpStatusCode.OK);
result.Content = new StringContent(sb.ToString(), System.Text.Encoding.UTF8, "text/plain");
return result;
}
Based on various searches this seems like the simplest way to proceed since I'll need this only for this one action. However when I request this, I get the following output:
{
   "Version": {
      "Major": 1,
      "Minor": 1,
      "Build": -1,
      "Revision": -1,
      "MajorRevision": -1,
      "MinorRevision": -1
   },
   "Content": {
      "Headers": [
         {
            "Key": "Content-Type",
            "Value": [
               "text/plain; charset=utf-8"
            ]
         }
      ]
   },
   "StatusCode": 200,
   "ReasonPhrase": "OK",
   "Headers": [],
   "RequestMessage": null,
   "IsSuccessStatusCode": true
}
So it seems that MVC still tries to output JSON, and I have no idea why they'd output these values. When I debug the code step by step I can see that the content of the StringBuilder is okay and what I want to output.
Is there any easy way to just output a string with MVC6?
Have a go with this:
var httpResponseMessage = new HttpResponseMessage();
httpResponseMessage.Content = new StringContent(stringBuilder.ToString());
httpResponseMessage.Content.Headers.ContentType = new MediaTypeHeaderValue("text/plain");
return httpResponseMessage;
The solution was to return a FileContentResult. This seems to bypass the built-in formatters:
[HttpGet]
public FileContentResult AllProductsCsv()
{
IList<Product> products = productService.GetAllProducts();
var sb = new StringBuilder();
sb.Append("Id,PartNumber\n");
foreach(var product in products)
{
sb.AppendFormat("{0},{1}\n", product.Id, product.PartNumber);
}
return File(Encoding.UTF8.GetBytes(sb.ToString()), "text/csv");
}

(Windows Phone 10) Is possible to edit, add new contact programmatically in windows phone 10?

I want to implement function edit and add contact programatically in windows phone 10.
Is it possible? Has any sample about it ?
Here is a code snippet for creating the contact:
public async Task AddContact(String FirstName, String LastName)
{
var contact = new Windows.ApplicationModel.Contacts.Contact();
contact.FirstName = FirstName;
contact.LastName = LastName;
//Here you can set other properties...
//Get he contact store for the app (so no lists from outlook and other stuff will be in the returned lists..)
var contactstore = await Windows.ApplicationModel.Contacts.ContactManager.RequestStoreAsync(Windows.ApplicationModel.Contacts.ContactStoreAccessType.AppContactsReadWrite);
try
{
var contactLists = await contactstore.FindContactListsAsync();
Windows.ApplicationModel.Contacts.ContactList contactList;
//if there is no contact list we create one
if (contactLists.Count == 0)
{
contactList = await contactstore.CreateContactListAsync("MyList");
}
//otherwise if there is one then we reuse it
else
{
contactList = contactLists.FirstOrDefault();
}
await contactList.SaveContactAsync(contact);
}
catch
{
//Handle it properly...
}
}
And here is a short sample for changing an existing contact:
//you can obviusly couple the changes better then this... this is just to show the basics
public async Task ChangeContact(Windows.ApplicationModel.Contacts.Contact ContactToChange, String NewFirstName, String NewLastName)
{
var contactStore = await Windows.ApplicationModel.Contacts.ContactManager.RequestStoreAsync(Windows.ApplicationModel.Contacts.ContactStoreAccessType.AppContactsReadWrite);
var contactList = await contactStore.GetContactListAsync(ContactToChange.ContactListId);
var contact = await contactList.GetContactAsync(ContactToChange.Id);
contact.FirstName = NewFirstName;
contact.LastName = NewLastName;
await contactList.SaveContactAsync(contact);
}
And very important:
In the appxmanifest you have to add the contacts capability. Right click to it in the solution explorer and "View Code" and then under Capabilities put
<uap:Capability Name="contacts" />
There is no UI for this. See this.
Both samples are meant to be for starting point... obviously it's not production ready and you have to adapt it to your scenario.
Update
Since this came up in the comments I extend my answer a little bit.
Based on this (plus my own experimentation) the ContactListId for aggregated contacts is null (which makes sense if you think about it). Here is how to get the raw contact with ContactlLstId (code is based on the comment from the link)
public async Task IterateThroughContactsForContactListId()
{
ContactStore allAccessStore = await ContactManager.RequestStoreAsync(ContactStoreAccessType.AllContactsReadOnly);
var contacts = await allAccessStore.FindContactsAsync();
foreach (var contact in contacts)
{
//process aggregated contacts
if (contact.IsAggregate)
{
//here contact.ContactListId is "" (null....)
//in this case if you need the the ContactListId then you need to iterate through the raw contacts
var rawContacts = await allAccessStore.AggregateContactManager.FindRawContactsAsync(contact);
foreach (var rawContact in rawContacts)
{
//Here you should have ContactListId
Debug.WriteLine($"aggregated, name: {rawContact.DisplayName }, ContactListId: {rawContact.ContactListId}");
}
}
else //not aggregated contacts should work
{
Debug.WriteLine($"not aggregated, name: {contact.DisplayName }, ContactListId: {contact.ContactListId}");
}
}
}
And another important thing:
According to the documentation you won’t be able to change all the contacts which are created by other apps.
AllContactsReadWrite:
Read and write access to all app and system contacts. This value is
not available to all apps. Your developer account must be specially
provisioned by Microsoft in order to request this level of access.
In some cases, I get a System.UnauthorizedAccessException when SaveContactAsync(contact) is called. One example for this was when the contact was in the Skype Contact List.

How do you update objects in a Parse.com database using Xamarin?

I have an online Parse.com database and I can create objects and query them but not update. In the Xamarin section of the Parse.com documentation it only tells you how to update an object directly after you've created it which I don't want to do. I tried adapting what the documentation says for other platforms but it hasn't worked, I have also tried querying the database and entering the new field values directly after that but it treats them as separate functions. Does anyone have any help?
Parse.com documentation:
// Create the object.
var gameScore = new ParseObject("GameScore")
{
{ "score", 1337 },
{ "playerName", "Sean Plott" },
{ "cheatMode", false },
{ "skills", new List<string> { "pwnage", "flying" } },
};
await gameScore.SaveAsync();
// Now let's update it with some new data. In this case, only cheatMode
// and score will get sent to the cloud. playerName hasn't changed.
gameScore["cheatMode"] = true;
gameScore["score"] = 1338;
await gameScore.SaveAsync();
What I tried most recently:
ParseQuery<ParseObject> query = ParseObject.GetQuery("cust_tbl");
IEnumerable<ParseObject> customers = await query.FindAsync();
customers["user"] = admin;
record["score"] = 1338;
await record;
In your example, you are getting an list (IEnumerable) of objects instead of single object. Instead, try something like this:
ParseQuery<ParseObject> query = ParseObject.GetQuery("cust_tbl");
// you need to keep track of the ObjectID assigned when you first saved,
// otherwise you will have to query by some unique field like email or username
ParseObject customer = await query.GetAsync(objectId);
customer["user"] = admin;
customer["score"] = 1338;
await customer.SaveAsync();

CRM 2011 accessing webcontext with outlook plugin

I have found some plugin code on the web that enables me to get the entity ID and the object type code for an entity in a plugin. The plugin is fired on RetrieveMultiple on activitypointer. The code lets me get the id and object code of the entity that is currently being viewed (which is displaying the activities grid which is firing the plugin).
This code works fine when using the web interface. However I need it to also work in the Outlook preview pane and currently it does not. The activities grid in the Outlook preview pane just says "an error has occurred". Below is the code that the plugin is using to get the details from the web header.
internal static Dictionary<string, string> GetHeaderFields(HttpContext webcontext, string objectTypeCode, string objectId)
{
Dictionary<string, string> fields = new Dictionary<string, string>();
string callerentitytype = null;
string callerentityidstring = null;
try
{
// Activities Navigation Pane
if (new List<string>(webcontext.Request.Params.AllKeys).Contains("oType"))
{
callerentitytype = webcontext.Request.Params["oType"];
callerentityidstring = webcontext.Request.Params["oId"];
}
// Activities Sub Grid
else
{
string requeststring = webcontext.Request.UrlReferrer.Query;
requeststring = requeststring.Substring(1);
string[] parts = requeststring.Split(new string[] { "=", "&" }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < parts.Length - 1; i++)
if (parts[i].ToLower() == "otype" || parts[i].ToLower() == "etc")
callerentitytype = parts[i + 1];
else if (parts[i].ToLower() == "oid" || parts[i].ToLower() == "id")
callerentityidstring = parts[i + 1];
}
fields.Add(objectTypeCode, callerentitytype);
fields.Add(objectId, callerentityidstring);
}
catch (Exception ex)
{
throw new Plugin.LoggableException(string.Format("Failed to obtain header information; {0}", ex.Message), ex.InnerException);
}
return fields;
}
The reason is that webcontext.Request.UrlReferrer is NULL. Is there anywhere else I can get this info of the 'calling' entity? (Not the activity sub grid that is triggering the plugin, but the actual parent entity that the sub grid is on).
Thanks for any help or direction with this.
This might work. Each of the activitypointers that are returned should all be "regarding" the same record (if in a sub grid). If you take say the 1st one and examine the regardingobjectid property, that should be an entity reference which will give you the logical name of the parent and it's guid. If that works, it will work across all clients (in theory anyway).

unable to parse the xml query using Linq

I am developing a sample Twitter app for Windows phone 7. In my code to display some details of user, used the following code.
void ShowProfile()
{
WebClient client = new WebClient();
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(Profile_DownloadCompleted);
client.DownloadStringAsync(new Uri("http://api.twitter.com/1/users/show.xml?user_id=" + this.id));
}
void Profile_DownloadCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error != null)
{ return; }
if (e.Result == null) MessageBox.Show("NUlllllllllll");
XElement Profile = XElement.Parse(e.Result);
var ProfileDetails = (from profile in Profile.Descendants("user")
select new UserProfile
{
UserName = profile.Element("screen_name").Value,
ImageSource = profile.Element("profile_image_url").Value,
Location = profile.Element("location").Value,
TweetsCount = profile.Element("statuses_count").Value,
}).FirstOrDefault();
LayoutRoot.DataContext = ProfileDetails;
}
Here, LayoutRoot is the Grid name. But the data binding doesn't work.
Infact, when kept a Break point it seems there is no data in the ProfileDetails object. But I could observe that e.Result contains the required data in the XML format.
Can any body figureout where I am going wrong??
Thanks in advance.
You have used XElement.Parse so Profile represents the single root <user> that API request would have returned. You are then trying to look for user elements inside it which of course makes no sense.
Try XDocument.Parse instead. Also does it really make any sense assigning a IEnumerable<UserProfile> to the data context when that list can only ever contain 1 entry?

Resources