Get MongoCluster Primary with C# Drver - c#

I connect with the following code to a mongo database.
Then i iterated through the server descriptions of the cluster but the state is always "disconnected" but when i look with tools like monogchef i can see that all server are connected and there is one primary and all others are secondaries
var client = new MongoClient(conString);
var db = client.GetDatabase("admin");
foreach (var server in client.Cluster.Description.Servers)
{
Console.WriteLine(server.State); // Always returns disconnected.
}
How can I read who is the primary and when has been the last election?

Just found it.
Have to make a dummy request then i find the data under
server.ReplicaSetConfig.Primary

Related

DirectConnection cannot be used when ConnectionModeSwitch is set to UseConnectionMode while connect with Azure Cosmos DB API for MongoDB

I want to connect with Azure Cosmos DB API for MongoDB via ASP.NET app. To start I use connection string provided by Microsoft (when creating an instance by Azure)
var client = new MongoClient("mongodb://[myInstanceName]:
[primaryAccountKey]#[myInstanceName].documents.azure.com:10255/?ssl=true&retrywrites=false&replicaSet=globaldb
&maxIdleTimeMS=120000&appName=#mongocosmocoffedb#");
var database = client.GetDatabase("productdb");
var collection = database.GetCollection<Product>("productcollection");
return Ok(collection);
But when I use this connection string I got error
DirectConnection cannot be used when ConnectionModeSwitch is set to UseConnectionMode.
I found this stackoverflow topic and try use
var client = new MongoClient("mongodb://[myInstanceName]:
[primaryAccountKey]#[myInstanceName].documents.azure.com:10255/?ssl=true");
but in this case i got error
MaxWireVersion is not known.
This is the connection mode port issue. The port number you mentioned 10255 is used for geo-replication and that is causing the issue. Post numbers 10255, 10256 map to the instance that has geo-replication.
Change the port number to 10255. 10250 maps to the default Azure cosmos DB API for Mongo DB. In case of using geo-replication, public end point you can use 10255
Refer the following link: https://learn.microsoft.com/en-us/azure/cosmos-db/sql/sql-sdk-connection-modes

MongoDB - view failed commands

Are failed commands (inserts, updated, deletes etc.) logged anywhere by Mongo DB?
I'm using the C# driver and some commands fail (e.g. inserts) due to duplicate unique key (enforced by an index), so I want to see in retrospect which documents were being inserted.
I would like to see the raw documents that failed, after the driver serialized them.
By the way, as I understand the Mongo oplog only contains successful commands.
Are failed commands (inserts, updated, deletes etc.) logged anywhere by Mongo DB?
I don't think they are, but maybe I haven't tried hard enough to find them yet.
However, you can log them in the application by setting the ClusterConfigurator on the MongoClientSettings like this
//Build the initial settings from the MongoConnectionString
MongoClientSettings settings = MongoClientSettings.FromConnectionString("MongoConnectionString");
//Subscribe on the following events
settings.ClusterConfigurator += cb =>
{
cb.Subscribe(delegate (CommandStartedEvent startedEvent) { Console.WriteLine($"Started: {startedEvent.Command} with OpId: {startedEvent.OperationId}"); });
cb.Subscribe(delegate (CommandSucceededEvent succeededEvent) { Console.WriteLine($"Succeeded OpId: {succeededEvent.OperationId}"); });
cb.Subscribe(delegate (CommandFailedEvent failedEvent) { Console.WriteLine($"Failed OpId: {failedEvent.OperationId}"); });
};
//Builld a MongoClient with the new Settings
var client = new MongoClient(settings);
This example will only write the commands that are being exected and if which OperationId failed or succeeded.
But from here on you can extend it by keeping track of which command got started and what OperationId it runs on.
For a completed example you can see this Gist (as it seems like too much code to post here).
Which can be called as this:
var settings = MongoClientSettings.FromConnectionString("MongoConnectionString");
new MongoTracking().ConfigureTracking(settings);
var client = new MongoClient(settings);
For the record, this does the logging in the application and not the database.

C# MongoDB.Driver : How to see if server is connected. GetServer Replacement

GetServer is gone for good. How do i check if the server is connected or even exists?
Example code:
// This server exists
var exists = new MongoClient("mongodb://192.168.2.109:27017");
// This server does not exist
var doesNotExist = new MongoClient("mongodb://194.168.200.129:27017");
// Both states return "Discennected"
var connStateExisting = exists.Cluster.Description.State;
var connStateNotExisting = doesNotExist.Cluster.Description.State;
// GetDatabase("name") works for both without errors.
How can i check if a server can be connected?
The Cluster.Description.State does not update immediately. When i checked, it was updated after roughly 100+ milliseconds. The driver contains a connection pool and it seems to do quite a lot asynchronous.
However, the Cluster-property has a "DescriptionChanged"-event that is fired once the connection is done.
If someone else has any knowledge about connections and timeouts, please share it.

Serialize linq query so that it can be executed somewhere else

I am creating a client application that connects to a website in order to execute queries. I am not enabling the client to connect directly to the database but he can perform queries through the website.
The way I execute queries through the website is through linq. For example I may do:
MyEntities db = new MyEntities();
var customers = db.Customers.ToList();
Since the client does not have the connection string and sql server does not allow remote connections when he executes the above code it will obviously not work. My question is how can the client send that query to the web service?
The reason why I need this is because there are so many different types of queries and for each different one I have to create a different page. For example I have GetInvoices.aspx, GetCustomers.aspx, and I am always creating new ones just because I dont want the client to connect directly to the database. It will be nice if I could serialize the linq query and send that to the server. the server then should validate that I am not doing a delete statement for example and if thats the case then execute the query.
Eidt
This is what I am going to do for only select statements:
// Note connection string only have basics. It does not have password nor database.
public static string GenerateSelectQuery<T>(Func<Common.Data.TcEntities, IQueryable> method)
{
Common.Data.TcEntities db = new Common.Data.TcEntities(#"metadata=res://*/Data.Model1.csdl|res://*/Data.Model1.ssdl|res://*/Data.Model1.msl;provider=System.Data.SqlClient;provider connection string=""""");
var query = method(db);
return query.ToString();
}
then if I wish to create a custom query I will do:
var query = GenerateSelectQuery<Customer>(db => db.Customers.Where(x=>x.FirstName.Contains("a")));
I will send then that string to the server and expect an array of Customers. On the server side I will make sure string starts with select and it does not contain --.
Implementing a WCF Data Services, http client can query your data using the OData protocol.
For example, applying a select Name on your customers collections will be queryable using the http url:
http://youdomain/yourWCFDataServices.svc/Customers()?$select=Name

mongodb C# query doesn't respond

I'm trying to get Item from mongodb Server, sometimes its work and after 4-5 attemps its stop resonding in the last row (I can't take out the object out side the query)
any one had it before? what is the right way to take out the object?
var client = new MongoClient(connectionString);
var server = client.GetServer();
var database = server.GetDatabase("myPlaces");
var collection = database.GetCollection<MongoPlace>("Places");
int startDay = int.Parse(Request.QueryString["day"]);
MongoPlace mp = collection.AsQueryable<MongoPlace>().Where(x => x.guid ==
Request.QueryString["id"]).FirstOrDefault();
It's likely you're hitting the default connection pool limit.
As it looks like this is a web application, you shouldn't be opening the client more than once per instance of your web application.
The MongoClient, MongoServer, MongoDatabase and MongoCollection are all thread-safe and generally there should only be one instance of each. (See here for more information).
You'd probably want to do this as the application starts and then maintain the connections statically until the application exits.
In my ASP.NET MVC applications, I usually add a "DatabaseConfig" class that's called in the same way as other app configurations. As an example here's some code I've got in the project I'm currently building using MongoDB (there isn't any error handling yet):
var client = new MongoClient(ConfigurationManager.ConnectionStrings["DefaultConnection"].ConnectionString);
var server = client.GetServer();
DataLayer.Client = client;
DataLayer.Server = server;
var settings = new MongoDatabaseSettings(server, "default");
settings.WriteConcern = WriteConcern.Acknowledged;
DataLayer.Database = DataLayer.GetDatabase(settings);
Then, in Application_Start, I call an Initialize method that contains the code above.
DatabaseConfig.Initialize();

Categories

Resources