Uploading files in Asp.NET Core using MongoDb - c#

I would like to upload an image using Asp.net core and MongoDb; however, I am not able to find the property GridFS in MongoDatabase class . I have checked the Google and did not have any luck.
The method in which I need to change GridFS to something else:
private async Task StoreImage(Computer computer, IFormFile file)
{
var imageId = ObjectId.GenerateNewId();
computer.ImageId = imageId.ToString();
var filter = Builders<Computer>.Filter.Eq("_id", new ObjectId(computer.Id));
var update = Builders<Computer>.Update.Set("ImageId", computer.ImageId);
await db.Computers.UpdateOneAsync(filter, update);
db.GridFS.Upload(file.ToBson(), file.FileName, new MongoGridFSCreateOptions
{
Id = imageId,
ContentType = file.ContentType
});
}
Does anyone know the correct way to upload a file in MongoDB using ASP.net Core?

public class CdnDbContext
{
public IGridFSBucket GridFsBucket { get; set; }
public CdnDbContext()
{
var config = new ConfigurationBuilder()
.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json")
.Build();
var connectionString = config.GetConnectionString("MongoCdn");
var connection = new MongoUrl(connectionString);
var settings = MongoClientSettings.FromUrl(connection);
var client = new MongoClient(settings);
var database = client.GetDatabase(connection.DatabaseName);
GridFsBucket = new GridFSBucket(database);
}
}

Related

How to connect to mongodb using FluentDocker

I am trying to use FluentDocker to run the tests against MongoDB, but I cannot connect to it, see the code below.
[Fact]
public async Task TestMongoDbConnection3()
{
const string root = "root";
const string secret = "secret";
using (
var container =
new Builder().UseContainer()
.UseImage("mongo")
.WithEnvironment($"MONGO_INITDB_ROOT_USERNAME:{root}")
.WithEnvironment($"MONGO_INITDB_ROOT_PASSWORD:{secret}")
.ExposePort(27018)
.WaitForPort("27018/tcp", 30000 /*30s*/)
.Build()
.Start())
{
var config = container.GetConfiguration(true);
Assert.Equal(ServiceRunningState.Running, config.State.ToServiceState());
const string connectionString = "mongodb://root:secret#localhost:27018";
// insert data
const string collectionName = "Users";
var mongoClient = new MongoClient(connectionString);
var database = mongoClient.GetDatabase ("Users");
var collection = database.GetCollection<User>(collectionName);
const int id = 1;
var data = new Fixture().Build<User>()
.With(x => x.Id, id)
.Create();
// delete if exists, but got timeout after 30000 ms
await collection.DeleteOneAsync(x => x.Id == data.Id);
...
}
}
I tried to replace the localhost for the IP from config (config.NetworkSettings.IPAddress), but still getting the timeout.
Any idea?
Many thanks,
here is the fix var ep = container.ToHostExposedEndpoint("27017/tcp"); which works when running locally on my macos.
here is the full code. It still falling when it is running on a docker-in-docker image (timeout).
[Fact]
public void Test_Run_PingCommand_returns_True()
{
const string root = "root";
const string secret = "secret";
using (
var container =
new Builder().UseContainer()
.UseImage("mongo")
.WithEnvironment(new []{$"MONGO_INITDB_ROOT_USERNAME={root}",
$"MONGO_INITDB_ROOT_PASSWORD={secret}"})
.ExposePort(27017)
.WaitForPort("27017/tcp", 30000 /*30s*/)
.Build()
.Start())
{
var config = container.GetConfiguration(true);
Assert.Equal(ServiceRunningState.Running, config.State.ToServiceState());
var ep = container.ToHostExposedEndpoint("27017/tcp");
var connectionString =
$"mongodb://{root}:{secret}#{ep}";
var setting = new UsageDbSettings();
var mongoClient = new MongoClient(connectionString);
var database = mongoClient.GetDatabase(setting.DatabaseName);
var isMongoLive = database.RunCommandAsync((Command<BsonDocument>)"{ping:1}").Wait(30000);
Assert.True(isMongoLive);
}
}

Consume and Configure Graphql request from .Net C# console application client

I'm trying to consume a Graphql Api from a C# client. For that I'm using the GraphQl.Net Nuget package. The problem is that, I have no idea how to set the Api Url as I don't have HttpRequest object and this results also with additional problems that I can't set the authentcation header and send the token with the request. My code looks like:
public void Post(TestGraphQl.GraphQLQuery query)
{
var inputs = query.Variables.ToInputs();
var queryToExecute = query.Query;
var result = _executer.ExecuteAsync(_ =>
{
_.Schema = _schema;
_.Query = queryToExecute;
_.OperationName = query.OperationName;
_.Inputs = inputs;
//_.ComplexityConfiguration = new ComplexityConfiguration { MaxDepth = 15 };
_.FieldMiddleware.Use<InstrumentFieldsMiddleware>();
}).Result;
var httpResult = result.Errors?.Count > 0
? HttpStatusCode.BadRequest
: HttpStatusCode.OK;
var json = _writer.Write(result);
}
And the caller looks like this:
var jObject = new Newtonsoft.Json.Linq.JObject();
jObject.Add("id", deviceId);
client.Post(new GraphQLQuery { Query = "query($id: String) { device (id: $id) { displayName, id } }", Variables = jObject });
I'm totally new to this topic and appreciate any help. Many thanks!!
This worked out for me. You will need the GraphQL.Client Package. My_class is the class for the deserialization.
var client = new GraphQLHttpClient(Api_Url, new NewtonsoftJsonSerializer());
var request = new GraphQLRequest
{
Query = {query}
};
var response = await client.SendQueryAsync<my_class>(request);
Not sure if you are still looking for it. One can always use GraphQl.Client nuget to achieve this. Sample code to consume is
var query = #"query($id: String) { device (id: $id) { displayName, id } }";
var request = new GraphQLRequest(){
Query = query,
Variables = new {id =123}
};
var graphQLClient = new GraphQLClient("http://localhost:8080/api/GraphQL");
graphQLClient.DefaultRequestHeaders.Add("Authorization", "yourtoken");
var graphQLResponse = await graphQLClient.PostAsync(request);
Console.WriteLine(graphQLResponse.Data);

MongoDb.GridFS.FindOneById returns null

I'm uploading image to server with following code:
public ActionResult AttachImage(HttpPostedFileBase file)
{
var options = new MongoGridFSCreateOptions
{
Id = ObjectId.GenerateNewId().ToString(),
ContentType = file.ContentType
};
Context.Database.GridFS.Upload(file.InputStream, file.FileName, options);
return RedirectToAction("Index");
}
and trying to get file like:
public ActionResult GetImage(string id)
{
var image = Context.Database.GridFS.FindOneById(new ObjectId(id));
if(image == null)
{
return HttpNotFound();
}
return File(image.OpenRead(), image.ContentType);
}
After upload I can see file in database, but when I'm trying to load it as
Context.Database.GridFS.FindOneById(new ObjectId(id));
I'm always geting null. Could you please suggest what I'm doing wrong?
public class DbContext
{
public MongoDatabase Database;
public DbContext()
{
var client = new MongoClient(Properties.Settings.Default.ConnectionString);
var server = client.GetServer();
Database = server.GetDatabase(Properties.Settings.Default.DatabaseName);
}
}
mongocsharpdriver 2.5.0
mongo server 3.6
It turned out I incorrectly searched for file by Id.
Instead of
var image = Context.Database.GridFS.FindOneById(new ObjectId(id));
I should use
var image = Context.Database.GridFS.FindOneById(id);
I used code from examples for previous version of driver but in 2.5 we don't need to use
new ObjectId(id)

Xamarin: Using HttpClient POST in combination with a dynamic Class

I have some services that require rather complex objects. Every service uses almost the same base object but it needs to be extended for each service.
A simple example:
The Standard Object would be something like:
ContextObject {
params {
Device {
Name: "MyMobileDevice",
ID: 123455691919238
}
}
}
and for my service I need to add some properties under params,
something like:
ContextObject {
params {
Device {
Name: "MyMobileDevice",
ID: 123455691919238
},
requested_employee_id: 112929
}
}
I tried to get this by using JObject and got it working so far but now I cant find a proper example on how to send this object to my server using HttpClient.
Edit:
Here is my full JObject which all Requests need:
public static JObject DefaultContext (string ServiceMethod) {
var Context = new JObject();
Context["version"] = "1.1";
Context["method"] = ServiceMethod;
Context["params"] = JObject.FromObject( new {
Context = JObject.FromObject( new {
User = App.UserSettings.USERNAME,
Password = App.UserSettings.PASSWORD,
SerialNumber = "1234567890", // TODO: use generated id
Locale = "de-DE",
Timestamp = DateTime.Now.ToString("yyyy-MM-ddTHH\\:mm\\:ss.fffzzz"),
Device = JObject.FromObject( new {
DeviceType = "phone",
ProductType = "D6603", // TODO: Get from Device-Info
screen = JObject.FromObject( new {
Density = "xxhdpi", // TODO: Get from Device-Info
resolution = JObject.FromObject( new {
Height = "1920", // TODO: Get from Device-Info
Width = "1080" // TODO: Get from Device-Info
})
}),
version = JObject.FromObject( new {
AppVersion = "myAppVersion", // TODO: Get App-Information LayoutVersion = "1.0"
} )
})
})
});
return mobileContext;
}
For my Requests I need to add parameters under the "params"-Node. Which works with:
mobileContext["params"]["mynewparameter"] = "FOO";
Now I wanted to send this JObject via System.Net.Http-Client to my server with something like this:
var client = new HttpClient ();
client.BaseAddress = new Uri (App.UserSettings.HOST + ":" + App.UserSettings.PORT + App.UserSettings.TYPE);
client.Timeout = 3000;
var context = MyContext.DefaultContext (ServiceMethods.CUSTOMER_LIST_METHOD);
context ["params"] ["myrequestparam"] = "FOO";
var jsonString = JsonConvert.SerializeObject (context);
var responseData = await client.Get???????
Is my general approach correct? How would you do it? Is there a sample on how to handle such dynamic stuff?
I couldn't find a example on how to use httpclient correctly with the Newtonsoft.JSON-Library how far am I from actually working code?

Couchbase configuring client programmatically

I want to configure couchbase c# driver programmatically, without web/app.config.
It looks like, configuration does not allow Urls to be set.
var cfg = new CouchbaseClientConfiguration()
{
Bucket = "a",
Urls = new List<Uri> () { .... } // It's readonly
};
Do i have to hack client? Is there another simple way?
this sample from documentation doesn't work?
var config = new CouchbaseClientConfiguration();
foreach (var uri in uris)
{
config.Urls.Add(uri);
}
config.Bucket = bucketName;
config.BucketPassword = bucketPassword;
_cbc = new CouchbaseClient(config);

Categories