I'm working in a ASP MVC + Mongodb App, so I want to save files inside a specific document through a List. I'm using GridFs Upload Method which returns a MongoGridFSFileInfo (The type of the List in my Model) so I get the reference to the object returned and Add it to the List --so far everything seems fine-- but when I try to save the changes in the collection I get this exception "The specified method is not supported" and the File won't save into the document.
This is my Model
public class Document
{
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public List<MongoGridFSFileInfo> FsFileInfos = new List<MongoGridFSFileInfo>();
public Document()
{
}
}
And Here is the Method where 1) Add a File to a List of Document Collection 2) Try to save the changes in the collection.
[HttpPost]
public ActionResult PrepareToAttach(string id, string description, HttpPostedFileBase raw_file)
{
Document doc = Context.FindById(id);
var options = new MongoGridFSCreateOptions
{
ContentType = raw_file.ContentType
};
var mongoFileInfo = Context._db.GridFS.Upload(raw_file.InputStream, raw_file.FileName,options);
doc.FsFileInfos.Add(mongoFileInfo);
Context.Documents.Save(doc);
return RedirectToAction("Index", "Document");
}
The exception is displayed in Context.Documents.Save(doc); --> The specified method is not supported
MongoGridFSFileInfo is not a POCO class. What I mean by that is that it has many properties on it that either aren't persistable or shouldn't be.
The only thing you actually need to persist to get back a document is the unique identifier for the file. You may want to persist some other meta-data as well, but only the identifier is required.
Related
I am retrieving data from an odata service. The response contains a link for loading more data i.e. odata.nextLink which I need to retrieve to load more data(odata.nextLink). How do I do this using C# code? The server's response is something like this:
{
"odata.metadata":"http://localhost:60497/odata/$metadata#tables","value":[
{"id":001,"name":"abc" }
.
.
],
"odata.nextLink":"http://localhost:60497/odata/tables?$skip=10"
}
The presence of the odata.nextLink element is used to indicate that there are more results available.
If you simply want to fetch all results then you would keep fetching additional results from each successive nextLink URI until you receive a response that does not contain a nextLink element.
In the most simple case you could simply have a while loop, however in most situations if a query is returning a large set of results you would want to retrieve some and then offer the user the means to request more rows.
In C# you might be using the OData Client library from Microsoft which allows you to perform LINQ queries on OData services.
Microsoft's documentation has a comprehensive example at https://learn.microsoft.com/en-gb/odata/client/pagination
Create a class for the Json Object which is returned, Like this
public class Value
{
public int id { get; set; }
public string name { get; set; }
}
public class Root
{
[JsonProperty("odata.metadata")]
public string OdataMetadata { get; set; }
public List<Value> value { get; set; }
[JsonProperty("odata.nextLink")]
public string OdataNextLink { get; set; }
}
Try to deserialize the Json object returned, here data is going to be the Json Object in String Format.
var RootObj = JsonConvert.DeserializeObject<Root>(data);
From this RootObj, you will be able to get the OdataNextLink value and other values you need, which you can store in your local variable.
Let me know if you have more questions on this.
In Firestore how do you check to see if a collection and document already exists, and if not create a new collection and a document with a specific ID using .NET?
Per this answer for a node based question, the collection will be created automatically, but even still, it's not readily apparent how you do this, especially in .NET. This is even more true if it's multiple collections down the tree. As an example, here is a class for the document that we are going to try and add:
using Google.Cloud.Firestore;
namespace FirestoreTest.Models
{
[FirestoreData]
public class ClassicGame
{
public ClassicGame()
{
}
[FirestoreProperty]
public string title { get; set; }
[FirestoreProperty]
public string publisher { get; set; }
}
}
Here's an example function that performs a check if the collection and document exists at PC/Games/{publisher}/{title} and if not creates it using gameId as the ID for the document. It is using Google.Cloud.Firestore and Google.Cloud.Firestore.V1Beta1
public async Task<bool> AddPcGame(string gameTitle, string gamePublisher, string gameId)
{
string publisherCollectionPath = "PC/Games/" + gamePublisher;
//Try and get the document and check if it exists
var document = await db.Collection(publisherCollectionPath).Document(gameId).GetSnapshotAsync();
if (document.Exists)
{
//document exists, do what you want here...
return true;
}
//if it doesn't exist insert it:
//create the object to insert
ClassicGame newGame = new ClassicGame()
{
title = gameTitle,
publisher = gamePublisher
};
//Notice you have to traverse the tree, going from collection to document.
//If you try to jump too far ahead, it doesn't seem to work.
//.Document(gameId).SetAsync(newGame), is what set's the document's ID and inserts the data for the document.
CollectionReference collection = db.Collection("PC");
var document2 = await collection.Document("Games").Collection(gamePublisher).Document(gameId).SetAsync(newGame);
return true;
}
I am getting an XML return from an Ebay API call. This is actually an Ebay category list of collections. But the problem is, I can't access its collection from XML output. I have attached two pictures - the first one showing debug of XML value returning variable, and the second one showing "InnerList". My main goal is prepare this XML data to store on my database, so I need a clean list of values from XML data. Any ideas?
You could deserialize your xml into your own class/object - Then it might be easier to work with. All i do is put xml tags to a class and i can deserialize it. See the class and method below:
public static T Deserialize<T>(string xmlText)
{
try
{
var stringReader = new System.IO.StringReader(xmlText);
var serializer = new XmlSerializer(typeof(T));
return (T)serializer.Deserialize(stringReader);
}
catch
{
throw;
}
}
[XmlElement("adress")]
public class Adress
{
[XmlElementAttribute("street_address")]
public string street_address { get; set; }
[XmlElementAttribute("postal_code")]
public string postal_code { get; set; }
[XmlElementAttribute("city")]
public string city { get; set; }
[XmlElementAttribute("country")]
public string country { get; set; }
}
public main()
{
Adress myAdress = Deserialize<Adress>(XMLstring);
}
Hope it helps!
It seems you are using Ebay SDK. Please try code below to process return values.
foreach (CategoryTypeCollection item in categories)
{
item.ItemAt(0).CategoryID = "This is how you access the properties of he returned result";
// THE XML is already parsed for you via SDK, so you don't have to parse it...
// since i wrote foreach loop here, always access itemAt 0th index posiiton
}
How Can i OutPut the published Content of a Certain Document Type via Web Api?
Example:
I have a Document Type Called
Comment
its has three Properties "Name, Date, Text"
I Want To output the Values of those Properties to a UmbracoApiController So that I can Use it in other WebSites
any thoughts ? Thanks in Advance
public class publishedContentapiController : UmbracoApiController
{
//What Logic To Put Here In Order to get the Content OF published
// Document Types With the Alias "comment"
}
The below code outputs all documents of type "comment" through the webapi
public class publishedContentapiController : UmbracoApiController
{
public IHttpActionResult GetComments()
{
// Create an UmbracoHelper for retrieving published content
var umbracoHelper = new UmbracoHelper(UmbracoContext.Current);
// Get all comments from the Umbraco tree (this is not a optimized way of doing this, since it queries the complete Umbraco tree)
var comments = umbracoHelper.TypedContentAtRoot().DescendantsOrSelf("comment");
// Map the found nodes from IPublishedContent to a strongly typed object of type Comment (defined below)
var mappedComments = comments.Select(x => new Comment{
Name = x.Name, // Map name of the document
Date = x.CreatedTime, // Map createdtime
Text = x.GetPropertyValue<string>("text") // Map custom property "text"
});
return Ok(mappedComments);
}
private class Comment
{
public string Name { get; set; }
public DateTime Date { get; set; }
public string Text { get; set; }
}
}
Diclaimer: Code is untested and obviously needs refactoring
I have a Raven database which contains a document collection. I would like to retrieve a subset of the documents in that collection. Only documents fulfilling certain criteria would be retrieved. However, for each document retrieved, the entire document must be retrieved.
Consider the following document type:
public class MyDocument {
public string Id { get; set; }
public string Name { get; set; }
public int Foo { get; set; }
public string Bar { get; set; }
}
Let's say I would like to retrieve all documents where the Foo property is greater than a given value (unknown at compile/index creation time). Using dynamic indexes, this could be done like:
IList<MyDocument> FindMyDocuments(int minFooValue) {
using(IDocumentSession session = _store.OpenSession()) {
return session.Query<MyDocument>().Where(d => d.Foo > minFooValue).ToList();
}
}
However, as I understand it, there are benefits to using predefined indexes instead of dynamic indexes. So I would like to define an index for this operation up front. How would an implementation of AbstractIndexCreationTask< MyDocument, MyDocument > look like?
The following doesn't seem to work as Raven wants the Map to select a new anonymous type:
class MyDocumentIndex: AbstractIndexCreationTask<MyDocument, MyDocument> {
public MyDocumentIndex() {
Map = docs => from doc from docs
select doc;
}
}
And shouldn't there be a Reduce part as well?
As you probably noticed, I'm rather new to this Map/Reduce concept :-).
David,
You do it like this:
public class MyDocumentIndex: AbstractIndexCreationTask<MyDocument> {
public MyDocumentIndex() {
Map = docs => from doc from docs
select new { doc.Foo };
}
}
And then you query it with:
session.Query<MyDocument, MyDocumentIndex().Query(x=>x.Foo > minValue).ToArray();