I am trying to insert elements into a MongoLab database (Sandbox plan) using C# (by parsing a xml file, but that is not the relevant part).
var connectionString = "mongodb://user:pass#ds011111.mongolab.com:11111/db";
var server = client.GetServer();
var database = server.GetDatabase("mydb");
var elementCollection = database.GetCollection<Entity>("entities");
XmlDocument doc = new XmlDocument();
doc.LoadXml(elementxml);
XmlNodeList elementList = doc.GetElementsByTagName("element");
foreach (XmlNode element in elementList)
{
var t = new Entity();
t.Name = element.FirstChild.InnerText;
elementCollection.Insert(t); // this causes the error below
}
This is the message I get:
WriteConcern detected an error 'not authorized for insert on mydb.entities'. (Response
was { "err" : "not authorized for insert on mydb.entities", "code" : 16544, "n" : 0,
"lastOp" : { "$timestamp" : NumberLong(0) }, "connectionId" : 33932414, "ok" : 1.0 }).
If I run the same code on localhost, everything works as intended
If I insert an element using mongo/shell I get Cannot use commands write mode, degrading to compatability mode, but it works
Does this mean I cannot populate my mongolab database with data (from C#) because I do not have the right permissions as a Sandbox user? If that is the case, what are my options?
The problem seems to be that you're authenticating to the "db" database but trying to use the "mydb" database. Except for specially-privileged/admin users, most users only have access to one database, hence the not authorized error. We run all our databases with authentication on, while the MongoDB defaults, which you're likely using locally, require no authentication; that's why you're not seeing the issue locally.
You should be grabbing the DB to be used from the URI. Here's an example from our Language Center.
// Standard URI format: mongodb://[dbuser:dbpassword#]host:port/dbname
String uri = "mongodb://user:pass#host:port/db";
MongoUrl url = new MongoUrl(uri);
MongoClient client = new MongoClient(url);
MongoServer server = client.GetServer();
MongoDatabase db = server.GetDatabase(url.DatabaseName);
If that doesn't sort you out, try our connectivity troubleshooting guide. In particular, the next thing I'd look at is whether you're using the right credentials (see the section entitled "Check your database credentials").
Finally, please don't hesitate to contact us as support#mongolab.com if you continue to have issues or have any other questions.
Related
I'm trying to change Power BI connection string using their API (Microsoft.IdentityModel.Clients.ActiveDirectory). Using this API, I'm able to publish .pbix file to my PBI account. But Getting Bad Request error while trying to update dataset connection string. Here is my code.
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Accept", "application/json");
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
var restUrlImportPbix = POWER_BI_SERVICE_ROOT_URL + $"datasets/{dataset.id}/Default.SetAllConnections";
var postData = new { connectionString = _powerBISettings.DataConnectionString };
var response = client.PostAsync(restUrlImportPbix, new StringContent(JsonConvert.SerializeObject(postData), Encoding.UTF8, "application/json")).Result;
Also I found in a blog that SetAllConnections only works on direct query connections. Anybody help please.
In addition to trying to redirect the datasource by changing the connection string, you can achieve the same by allowing the report itself to switch it's data source. To do this, use connection specific parameters in the report. To do this, open Power Query Editor by clicking Edit Queries and in Manage Parameters define two new text parameters, lets name them ServerName and DatabaseName:
Set their current values to point to one of your data sources, e.g. SQLSERVER2016 and 'AdventureWorks2016. Then right click your query in the report and openAdvanced Editor`. Find the server name and database name in the M code:
and replace them with the parameters defined above, so the M code will look like this:
Now you can close and apply changes and your report should work as before. But now when you want to change the data source, do it using Edit Parameters:
and change the server and/or database name to point to the other data source, that you want to use for your report:
After changing parameter values, Power BI Desktop will ask you to apply the changes and reload the data from the new data source. To change the parameter values (i.e. the data source) of a report published in Power BI Service, go to dataset's settings and enter new server and/or database name:
If the server is on-premise, check the Gateway connection too, to make sure that it is configured properly to use the right gateway. You may also want to check the available gateways in Manage gateways:
After changing the data source, refresh your dataset to get the data from the new data source. With Power BI Pro account you can do this 8 times per 24 hours, while if the dataset is in a dedicated capacity, this limit is raised to 48 times per 24 hours.
To do this programatically, use Update Parameters / Update Parameters In Group and Refresh Dataset / Refresh Dataset In Group REST API calls, or if I modify your code, something like this:
var client = new HttpClient();
client.DefaultRequestHeaders.Add("Accept", "application/json");
client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
var restUrlUpdateParameters = POWER_BI_SERVICE_ROOT_URL + $"datasets/{dataset.id}/Default.UpdateParameters";
var postData = new { updateDetails = new[] { new { name = "ServerName", newValue = "NEWSERVER" }, new { name = "DatabaseName", newValue = "Another_AdventureWorks2016" } } };
var responseUpdate = client.PostAsync(restUrlUpdateParameters, new StringContent(JsonConvert.SerializeObject(postData), Encoding.UTF8, "application/json")).Result;
var restUrlRefreshDataset = POWER_BI_SERVICE_ROOT_URL + $"datasets/{dataset.id}/refreshes";
var responseRefresh = client.PostAsync(restUrlRefreshDataset, null).Result;
This is a easy way to make your reports "switchable", e.g. for switching one report from DEV or QA to PROD environment, or as part of your disaster recovery plan, to automate switching all reports in some workgroup to another DR server. In general I recommend to define such connection specific parameters in all reports.
The following code works as it should do, if the server is running and if the usename and password are correct. However, if i give a wrong username or password, it does not give me feedback, but only runs into a timeout when calling the Count method.
MongoClientSettings setts = new MongoClientSettings()
{
Server = new MongoServerAddress("127.0.0.1", 27017),
Credentials = new MongoCredential[] { MongoCredential.CreateCredential("TestDatabase", "username", "password") }
};
this.client = new MongoClient(setts);
this.client.Cluster.DescriptionChanged += this.ClusterDescriptionChanged;
var database = this.client.GetDatabase("TestDatabase");
var collection = database.GetCollection<BsonDocument>("SimpleCollection");
var count = collection.Count(MongoDB.Driver.FilterDefinition<BsonDocument>.Empty);
How do i get error messages from the driver and how can i check if it's the connection, the user or the password that does not fit?
PS: The driver API has changed a lot since 2.0 in Jan.2016, which means that most webtutorials and posts on this site no longer work for the current version.
Once you get the client, you can check if the connection is successful
var server = client.GetServer();
server.Ping();
Also it is always a good idea to enclose your code in a try catch with timeout exception because that is expected.
for more info on this you can refer MongoDB C# Driver check Authentication status & Role
I nee to connect to a mongo and run a commands.
I'm am connecting using the following piece of code. I want to test weather I am connecting by listing the databases.
MongoClient client = new MongoClient("mongodb://127.0.0.1:27017");
client.ListDatabases();
If I debug and click on the second line I cannot see the names of the databases. How can I print the names of the databases to screen to confirm I am connected to mongo.
You need to specify credentials in the Connection String. Couple ways you can do this:
var connectionString = "mongodb://user1:password1#127.0.0.1:27017";
Is the format expected, you will have to supply the username and password yourself, these are just placeholders.
Or you can create a MongoCredentials object and use that instead of a connection string (probably a bit cleaner this way, and allows more configuration if you look deeper into the object documentation)
var credential = MongoCredential.CreateMongoCRCredential("test", "user1", "password1");
var settings = new MongoClientSettings
{
Credentials = new[] { credential }
};
var mongoClient = new MongoClient(settings);
Both of these examples are found on MongoDB's documentation site
Try GetDatabaseNames() method and also assign the result to a variable. So that you can inspect it at breakpoint like
MongoClient client = new MongoClient("mongodb://127.0.0.1:27017/");
var databaseNames = client.GetDatabaseNames();
ListDatabases returns an IAsyncCursor so try the following:
var client = new MongoClient(<CONNECTION STRING>);
var cursor = client.ListDatabases();
cursor.ForEachAsync(db => Console.WriteLine(((BsonString)db["name"]).Value));
I try to connect to server and get database. It run properly but it VS2013 show me a warning :
Warning 1 'MongoDB.Driver.MongoClientExtensions.GetServer(MongoDB.Driver.MongoClient)' is obsolete: 'Use the new API instead.
string connectionString = "mongodb://localhost:27017";
MongoClientSettings settings = MongoClientSettings.FromUrl(new MongoUrl(connectionString));
MongoClient mongoClient = new MongoClient(settings);
var server = mongoClient.GetServer();
var db = server.GetDatabase("bookstore");
var bookCollection = db.GetCollection<Book>("Book");
Can someone help me solve this ? Tks for reading.
The MongoServer class was deprecated in version 2.0.0 (see here). You can call GetDatabase() directly on the MongoClient object:
MongoClient mongoClient = new MongoClient(settings);
var db = mongoClient.GetDatabase("bookstore");
More documentation about connecting to the MongoDB server, retrieving a database, etc. can be found in the reference documentation.
I changed my code to following:
var mongoUrl = new MongoUrl(connectionString);
var mongoClient = new MongoClient(mongoUrl);
MongoServer server = new MongoServer(MongoServerSettings.FromClientSettings(mongoClient.Settings));
The example code from #Robby works, but it doesn't return what your code is expecting; it returns Interface objects. The C# driver was updated to utilize Interface methods, as well as a number of asynchronous functions, so updating your code is probably a good idea.
The new way to get a database is -- well, you don't get a database anymore. You get an IMongoDatabase which is an interface to the database. Also, you should not work with MongoCollections anymore (from the MongoDatabase object), when you get an IMongoDatabase you will work with an IMongoCollection. Refactoring? You bet! But it's worth it.
I would also recommend putting your default database in the Mongo URL formatted connection strings. That way you can keep hard-coded constants, such as the database name, out of your code.
// Get your connection string -- use the URL format as in example below:
// name="MongoConnectionStr" connectionString="mongodb://localhost/bookstore"
var connectionString = ConfigurationManager.ConnectionStrings["MongoConnectionStr"].ConnectionString;
var mongoUrl = MongoUrl.Create(connectionString);
var client = new MongoClient(connectionString);
// Use the Mongo URL to avoid hard-coding the database name.
var db = new MongoClient(mongoUrl).GetDatabase(mongoUrl.DatabaseName);
// books below is an IMongoCollection
var books = db.GetCollection<Book>("Books");
I am using primavera webservices (version 6.2.1) to read data from a primavera database (sqlserver 2008R2) in a winform application (c#). I use http cookie container authentication mode. Before I moved my database to a new server I was able to login and read data from the primavera database successfully but when I moved DB (using backup and restore), I can still login to db but primavera webservices return null for any request.
This is my code to login:
AuthenticationService authService = new AuthenticationService( );
authService.CookieContainer = new System.Net.CookieContainer( );
authService.Url = _P6wsAuthenticationService;
Login loginObj = new Login( );
loginObj.UserName = pv_Username;
loginObj.Password = pv_Password;
loginObj.DatabaseInstanceId = 1;
loginObj.DatabaseInstanceIdSpecified = true;
loginObj.VerboseFaults = true;
loginObj.VerboseFaultsSpecified = true;
LoginResponse loginReturn = authService.Login( loginObj );
ReadDatabaseInstancesResponseDatabaseInstance[] readdbInstances = authService.ReadDatabaseInstances("");
cookieContainer = authService.CookieContainer;
When I run this code the loginresponse for new database is "true" and it shows the correct database instance information in "readdbInstances".
I run the following code to read some project info from DB:
ProjectPortBinding pbProject = new ProjectPortBinding( );
pbProject.CookieContainer = cookieContainer;
pbProject.Url = _P6wsProjectService;
ReadProjects readProject = new ReadProjects( );
Primavera.Ws.P6.Project.ProjectFieldType[] pfProject = new Primavera.Ws.P6.Project.ProjectFieldType[6];
pfProject[0] = Primavera.Ws.P6.Project.ProjectFieldType.ObjectId;
pfProject[1] = Primavera.Ws.P6.Project.ProjectFieldType.Id;
pfProject[2] = Primavera.Ws.P6.Project.ProjectFieldType.Name;
pfProject[3] = Primavera.Ws.P6.Project.ProjectFieldType.Status;
pfProject[4] = Primavera.Ws.P6.Project.ProjectFieldType.StartDate;
pfProject[5] = Primavera.Ws.P6.Project.ProjectFieldType.FinishDate;
readProject.Filter = pv_ProjectList.Equals( String.Empty ) ? String.Empty : "Id IN (" + pv_ProjectList + ")";
readProject.Field = pfProject;
Primavera.Ws.P6.Project.Project[] aProject = pbProject.ReadProjects( readProject );
it sends the request to the server but the message that I receive contains no project.
Before I moved the database I was able to read data with the same code. I changed database instance for primavera web services using its database configuration and I'm sure that it connects to the right DB, I'm just confusing why it cannot read the data from it. When I use the primavera client module to connect and read data from the new database it works fine and I can see all my projects.
Check the credentials that you are using in the user administrator front end, you will need to increase the permissions there on a module level or project level. Once you enable those you should see some data.
Kindly,
JK.