I want to be able to print the body of a google docs in the console using c#.
I am able to print the title using this code
DocumentsResource.GetRequest request = service.Documents.Get(documentId);
Document doc = request.Execute();
Console.WriteLine(doc.Title);
but I am unable to do the same thing with the body of the text using this code
DocumentsResource.GetRequest request = service.Documents.Get(documentId);
Document doc = request.Execute();
Console.WriteLine(doc.Body);
The output is Google.Apis.Docs.v1.Data.Body.
What is the problem with the code and what should I change ?
Answer:
You need to extract the data out of the body object.
More Information:
As per the documentation on the Document Resource, the body is an object containing more than just a string of data:
{
"documentId": string,
"title": string,
"body": {
"content": [
{
"startIndex": integer,
"endIndex": integer,
"paragraph": {
object (Paragraph)
},
"sectionBreak": {
object (SectionBreak)
},
"table": {
object (Table)
},
"tableOfContents": {
object (TableOfContents)
}
}
]
},
// ...
}
The Document resource goes quite a few layers deep, so depending on what information you are trying to extract from the Body, you will have to reference this directly - something like doc.Body.Content[0].Paragraph.Elements[0].TextRun.Content - but this will highly depend on what your document contains.
You can also try viewing the whole object with by serialising the object with the JavaScriptSerializer Class as recommended by Microsoft.
References:
REST Resource: documents | Google Docs API | Google Developers
JavaScriptSerializer Class (System.Web.Script.Serialization) | Microsoft Docs
Related
I'm using Graph SDK to search files in SharePoint. Is it possible to search them only by the name?
var request = _graphServiceClient
.Drives[id]
.Root
.Search($"{searched}")
.Request();
The request above returns files that have the given phrase in content or metadata and I need to filter them by name in code. I would like to avoid this approach if possible.
You can use search api like following
POST /search/query
Content-Type: application/json
{
"requests": [
{
"entityTypes": [
"driveItem"
],
"query": {
"queryString": "contoso"
}
}
]
}
Here is the document for details
https://learn.microsoft.com/en-us/graph/search-concept-files
I'm trying to scrape pages, find their schema.org script, then deserialize it.
I am able to find the script, however, valid JSON schema (according to Google/schema.org) is supposedly invalid in most Json Validator tools.
For example, this is my code
string Url = "https://www.independent.co.uk/news/health/nhs-pay-health-coronavirus-unions-b1812659.html";
HtmlWeb web = new HtmlWeb();
HtmlDocument doc = web.Load(Url);
var scripts = doc.DocumentNode.SelectNodes("//script");
foreach (HtmlNode node in scripts)
{
string value = node.InnerText;
if (value.Contains("schema.org"))
{
dynamic results = JsonConvert.DeserializeObject<dynamic>(value);
var name = results.name;
}
}
Which finds the following Schema (JSON)
{{
"#type": "Organization",
"#context": "https://schema.org",
"name": "The Independent",
"url": "https://www.independent.co.uk",
"logo": {
"#type": "ImageObject",
"url": "https://www.independent.co.uk/img/logo.png",
"width": 504,
"height": 60
},
"sameAs": [
"https://twitter.com/Independent",
"https://www.facebook.com/TheIndependentOnline"
]
}}
#1 The JSON is supposedly invalid, even though every website using structured data uses it like this
#2 When I try to get the name value, it returns null.
I assume my problems are because the JSON is invalid. How do I make this work? I'm out of ideas.
You need to get rid of the extra curly brackets at the start and end of the JSON to make it valid JSON.
I currently have this WEB API running locally:
// POST api/CsvParse
[HttpPut]
public void Put([FromBody]string value)
{
if (string.IsNullOrEmpty(value))
throw new Exception("Input is null or empty.");
}
I currently have it running locally, and am sending a string to the put using POSTMAN. I have selected the body tab, and have the string pasted into the raw body tab:
It states that my text is unsupported, or when I add a break point the value is null or I get the error describing the format is incorrect.
What am I doing wrong?
That's because there is no media type formatter that can serialize a raw string into your model (your route parameter with [FromBody] attribute).
A quick and dirty workaround is to directly read the body of your request as a string:
[HttpPut]
public async Task<HttpResponseMessage> Put(HttpRequestMessage request)
{
var myCsv = await request.Content.ReadAsStringAsync();
// do stuff with your string
return new HttpResponseMessage(HttpStatusCode.OK);
}
As an alternative you could implement a custom media type formatter yourself, as per this answer.
Change the media type to x-www-form-urlencoded rather than multipart/form-data.
Also, WebAPI is particular about FromBody parameters.
http://encosia.com/using-jquery-to-post-frombody-parameters-to-web-api/
For you, I think this is the relevant part:
[FromBody] parameters must be encoded as =value
The final hurdle remaining is that Web API requires you to pass
[FromBody] parameters in a particular format. That’s the reason why
our value parameter was null in the previous example even after we
decorated the method’s parameter with [FromBody].
Instead of the fairly standard key=value encoding that most client-
and server-side frameworks expect, Web API’s model binder expects to
find the [FromBody] values in the POST body without a key name at all.
In other words, instead of key=value, it’s looking for =value.
This part is, by far, the most confusing part of sending primitive
types into a Web API POST method. Not too bad once you understand it,
but terribly unintuitive and not discoverable.
Try adding a content type of text/plain
There is a similar Q&A here
I found that solution #1 worked for me as I was trying to PUT JSON containing the Key/Value pair. So originally my JSON looked like this
{
"subscriber": {
"Id": "2",
"subscriptions":[
{
"Name": "Subscription 1",
"Id": "18",
"IsSubscribed": false
},
{
"Name": "Subscription 2",
"Id": "19",
"IsSubscribed": false
},
{
"Name": "Subscription 3",
"Id": "20",
"IsSubscribed": false
}
]
}
}
But I modified it to become
{
"Id": "2",
"subscriptions":[
{
"Name": "Subscription 1",
"Id": "18",
"IsSubscribed": false
},
{
"Name": "Subscription 2",
"Id": "19",
"IsSubscribed": false
},
{
"Name": "Subscription 3",
"Id": "20",
"IsSubscribed": false
}
]
}
And that worked. My PUT request from Postman was recognised in my C# web api using [FromBody]
Just to add my bit, there is one more solution to pass primitives into a POST or a PUT method. Just specify the model as JObject. ASP.Net core web api then binds incoming JSON object(containing primitives like string) into JObject model object.
Your code would look like this:
// POST api/CsvParse
[HttpPut]
public void Put([FromBody]JObject value)
{
//access your string data
string data = value[SPECIFY_KEY_HERE];
if (string.IsNullOrEmpty(data))
throw new Exception("Input is null or empty.");
}
I'm trying to integrate BlueImp jQuery file upload component into my ASP.NET 4 website. I have the file upload working and writing to disk, but the component requires that I return a JSON object from the server as confirmation of success, in a particular format:
{"files": [
{
"name": "picture1.jpg",
"size": 902604,
"url": "http:\/\/example.org\/files\/picture1.jpg",
"thumbnailUrl": "http:\/\/example.org\/files\/thumbnail\/picture1.jpg",
"deleteUrl": "http:\/\/example.org\/files\/picture1.jpg",
"deleteType": "DELETE"
},
{
"name": "picture2.jpg",
"size": 841946,
"url": "http:\/\/example.org\/files\/picture2.jpg",
"thumbnailUrl": "http:\/\/example.org\/files\/thumbnail\/picture2.jpg",
"deleteUrl": "http:\/\/example.org\/files\/picture2.jpg",
"deleteType": "DELETE"
}
]}
I'd like to use the JsonResultClass to return this object in my C#, but I'm not sure how to format the response correctly. I can probably do something like this:
var uploadedFiles = new List<object>();
uploadedFiles.Add(new { name = "picture1.jpg", size = 902604, url = "http://example.org/files/picture1.jpg", thumbnailUrl = "http://example.org/files/thumbnail/picture1.jpg", deleteUrl ="http://example.org/files/picture1.jpg", deleteType = "DELETE" });
uploadedFiles.Add(new { name = "picture2.jpg", size = 902604, url = "http://example.org/files/picture1.jpg", thumbnailUrl = "http://example.org/files/thumbnail/picture1.jpg", deleteUrl ="http://example.org/files/picture1.jpg", deleteType = "DELETE" });
return Json(uploadedFiles);
...but then I'm not sure how to wrap this in the outer 'files' object.
Can anyone point me (a .NET novice trying to learn!) in the right direction here. I've looked at the MSDN documentation but it doesn't go into detail about formatting or constructing more complex JSON objects.
Many thanks.
Replace:
return Json(uploadedFiles);
with:
return Json(new {files = uploadedFiles});
to create a new anonymous type with property "files", which has your original list as a value.
I am new to C#, and did not find an easy piece of code to read a response from a URL. Example:
http://www.somesitehere.com/mysearch
The response is something like this ( I do not know what kind of response is this):
{ "response": {
"status": {
"code": "0",
"message": "Success",
"version": "4.2"
},
"start": 0,
"total": 121,
"images": [
{
"url": "www.someimagelinkhere.com/pic.jpg",
"license": {
"url": "",
"attribution": "",
"type": "unknown"
}
}
]
}}
After that I will to save that url "www.someimagelinkhere.com/pic.jpg" to a file. But this I know how to do. I just want to separate the url from the rest.
I saw this topic: Easiest way to read from a URL into a string in .NET
bye
Your response is of JSON Format. Use a library (NewtonSoft but there are others too) to extract the node you want.
You can use something like JSON.NET by Newton soft, which can be found and installed using NuGet Package Manager in Visual Studio.
Also you could just do this.
var jSerializer = new JavaScriptSerializer();
var result = jSerializer.DeserializeObject("YOUR JSON RESPONSE STRING");
The JSON string will not be a C# object with properties that match your names such as start, total, images, etc. If you need to you can create a strong type object and cast your converted object to that one for ease of use.
Strong typed version:
var jSerializer = new JavaScriptSerializer();
var result = (YourStrongType)jSerializer.DeserializeObject("YOUR JSON RESPONSE STRING");
var imgUrl = result.images[0].url;