Could you simply call the built in Create method for that table and specify the filename and the order ID to create it? Does it have to be a custom method? I didn't see the filename sample. Was that in the UploadFiles example application? Also all of the files get dropped into a single folder. Is there a way to create a folder for an order and drop the files in that location. The reason I ask is that if a user happens to upload a file with the same name it simply overrides the old file with the new one with no warning. My users will definitely have issues with this.
Could you simply call the built in Create method for that table and specify the filename and the order ID to create it?
Yes, this would work.
I didn't see the filename sample. Was that in the UploadFiles example application?
I meant theupload file section from the invoke custom method documentation. It shows how to return the URL of the uploaded file which can be later used for other purposes.
Is there a way to create a folder for an order and drop the files in that location.
Yes, you can do that. You have full control over where the file gets stored. For example you can add a parameter and pass the current OrderID.
[HttpPost]
public IActionResult UploadFiles(IEnumerable<IFormFile> files, int orderId)
{
// Combine the orderId with the WebRootPath so files are stored per orderId
var dir = Path.Combine(hostingEnvironment.WebRootPath, orderId.ToString());
// Create the directory if it doesn't exist
Directory.CreateDirectory(dir);
var result = files.Select(file => {
// Save the files in the directory
var path = Path.Combine(dir, file.FileName);
using (var stream = new FileStream(path, FileMode.Create))
{
// Save the file
file.CopyTo(stream);
var request = HttpContext.Request;
// Create the URL for the uploaded file - not that orderId is part of the URL
var url = $"{request.Scheme}://{request.Host.Value}/{orderId}/{file.FileName}";
// Return the FileName and Url
return new {
FileName = file.FileName,
Url = url
};
}
}).ToList();
// Return the file names and URL of the uploaded files
return Json(new { value = result }, new JsonSerializerSettings() {
ContractResolver = new DefaultContractResolver()
});
}
That does work for uploading the files and creating the directory structure. It is giving me an error when it is trying to create the record for the attachment in the DB. I am storing 3 columns, the related OrderId, the FileName, and the Url. I added OrderId so that all 3 items needed where returned values.
The custom method returns an array of files. The createOrderAttachment method however accepts a single item. Passing an array as the argument will not work.
If you want to support multiple file uploads it would be easier to just insert the records from the UploadFiles method itself.
Good to know. Is this what you mean by inserting the data in the method? Also is there already a database connection created I can call that was setup when I attached the database to the app as a datasource?
using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Hosting;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.Data.SqlClient;
namespace UploadFiles.Controllers
{
[Route("upload")]
public partial class UploadController : Controller
{
private readonly IHostingEnvironment hostingEnvironment;
public UploadController(IHostingEnvironment hostingEnvironment)
{
this.hostingEnvironment = hostingEnvironment;
}
[HttpPost]
public IActionResult UploadFiles(IEnumerable<IFormFile> files, int orderId)
{
// Combine the orderId with the WebRootPath so files are stored per orderId
var dir = Path.Combine(hostingEnvironment.WebRootPath, orderId.ToString());
// Create the directory if it doesn't exist
Directory.CreateDirectory(dir);
var result = files.Select(file => {
// Save the files in the directory
var path = Path.Combine(dir, file.FileName);
using (var stream = new FileStream(path, FileMode.Create))
{
// Save the file
file.CopyTo(stream);
var request = HttpContext.Request;
// Create the URL for the uploaded file - not that orderId is part of the URL
var url = $"{request.Scheme}://{request.Host.Value}/{orderId}/{file.FileName}";
// Return the FileName and Url
return new {
FileName = file.FileName,
Url = url,
OrderId = orderId
};
}
}).ToList();
SqlConnection conn = new SqlConnection("Data source=localhost; Database=Northwind;User Id=sa;Password=!QAZxsw2");
conn.Open();
SqlCommand cmd = new SqlCommand("insert into dbo.OrderAttachments values(OrderId,FileName,Url);", conn);
cmd.ExecuteNonQuery();
conn.Close();
// Return the file names and URL of the uploaded files
return Json(new { value = result }, new JsonSerializerSettings() {
ContractResolver = new DefaultContractResolver()
});
}
Also is there already a database connection created I can call that was setup when I attached the database to the app as a datasource?
Radzen doesn't keep any open connections to the database. However you can inject the EF context that has been created for your data source so you don't need to write SQL and embed the connection string in your code. Here is how this is done (step 4):
[Route("api/[controller]/[action]")]
public class ServerMethodsController : Controller
{
private NorthwindContext northwind;
public ServerMethodsController(NorthwindContext context)
{
this.northwind = context;
}
}
This is obviously beyond me to a point. I feel like I have something out of order. I'm not sure how to get the result values assigned to the fields to insert.
using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Hosting;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.Data.SqlClient;
using FunTimes.Models.Northwind;
using static Microsoft.AspNetCore.Hosting.Internal.HostingApplication;
namespace UploadFiles.Controllers
{
[Route("upload")]
public partial class UploadController : Controller
{
private readonly IHostingEnvironment hostingEnvironment;
public UploadController(IHostingEnvironment hostingEnvironment)
{
this.hostingEnvironment = hostingEnvironment;
}
[HttpPost]
public IActionResult UploadFiles(IEnumerable<IFormFile> files, int orderId)
{
// Combine the orderId with the WebRootPath so files are stored per orderId
var dir = Path.Combine(hostingEnvironment.WebRootPath, orderId.ToString());
// Create the directory if it doesn't exist
Directory.CreateDirectory(dir);
var result = files.Select(file =>
{
// Save the files in the directory
var path = Path.Combine(dir, file.FileName);
using (var stream = new FileStream(path, FileMode.Create))
{
// Save the file
file.CopyTo(stream);
var request = HttpContext.Request;
// Create the URL for the uploaded file - not that orderId is part of the URL
var url = $"{request.Scheme}://{request.Host.Value}/{orderId}/{file.FileName}";
// Return the FileName and Url
return new
{
FileName = file.FileName,
Url = url,
OrderId = orderId
};
}
}).ToList();
// Return the file names and URL of the uploaded files
return Json(new { value = result }, new JsonSerializerSettings()
{
ContractResolver = new DefaultContractResolver()
});
}
// Connect to Northwind to store Order Attachment Record details
private FunTimes.Data.NorthwindContext northwind;
public UploadController(FunTimes.Data.NorthwindContext context)
{
this.northwind = context;
var t = new OrderAttachment
{
FileName = ,
Url = ,
OrderId =
};
context.OrderAttachments.Add(t);
context.SaveChanges();
}
}
}
I think it's about there. I know it is trying to save to the DB now as I get an error about my foreign key constraint. When I debug in VS Code I can now see that my ordId parameter is not being passed in now and I don't know why. It was working yesterday as I could see the value. I checked the parameter setting for the invoke custom method in Radzen and it is still there and is using the ${parameters.OrderID} that is being used to pull the record on the edit screen.
using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Hosting;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.Data.SqlClient;
using FunTimes.Models.Northwind;
using static Microsoft.AspNetCore.Hosting.Internal.HostingApplication;
namespace UploadFiles.Controllers
{
[Route("upload")]
public partial class UploadController : Controller
{
private readonly IHostingEnvironment hostingEnvironment;
private FunTimes.Data.NorthwindContext context;
public UploadController(IHostingEnvironment hostingEnvironment, FunTimes.Data.NorthwindContext context)
{
this.hostingEnvironment = hostingEnvironment;
this.context = context;
}
[HttpPost]
public IActionResult UploadFiles(IEnumerable<IFormFile> files, int ordId)
{
// Combine the orderId with the WebRootPath so files are stored per orderId
var dir = Path.Combine(hostingEnvironment.WebRootPath, ordId.ToString());
// Create the directory if it doesn't exist
Directory.CreateDirectory(dir);
var result = files.Select(file =>
{
// Save the files in the directory
var path = Path.Combine(dir, file.FileName);
using (var stream = new FileStream(path, FileMode.Create))
{
// Save the file
file.CopyTo(stream);
var request = HttpContext.Request;
// Create the URL for the uploaded file - not that orderId is part of the URL
var url = $"{request.Scheme}://{request.Host.Value}/{ordId}/{file.FileName}";
//Save the Record as an Order Attachment.
var t = new OrderAttachment
{
FileName = file.FileName,
Url = url,
OrderId = ordId
};
this.context.OrderAttachments.Add(t);
this.context.SaveChanges();
// Return the FileName and Url
return new
{
fileName = file.FileName,
Url = url,
OrderId = ordId
};
}
}).ToList();
// Return the file names and URL of the uploaded files
return Json(new { value = result }, new JsonSerializerSettings()
{
ContractResolver = new DefaultContractResolver()
});
}
}
Hello!
Please help me figure out how to upload files, and by writing file links and id orders to the database
Everything turned out like Josh did, but I can’t insert the record
MySQL database
thank
//Save the Record as an Order Attachment.
var t = new OrderAttachment
{
FileName = file.FileName,
Url = url,
OrderId = ordId
};
this.context.OrderAttachments.Add(t);
this.context.SaveChanges();
It is thanks to @joshwilliam that I am now at this stage.
But nothing works, I fight for a very long time, no strength)
Here is the upload controller code:
using System;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Hosting;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.Data.SqlClient;
using static Microsoft.AspNetCore.Hosting.Internal.HostingApplication;
namespace UploadFiles.Controllers
{
using Models;
using Data;
using Models.Northwind;
[Route("upload")]
public partial class UploadController : Controller
{
private readonly IHostingEnvironment hostingEnvironment;
private UploadFiles.Data.NorthwindContext context;
public UploadController(IHostingEnvironment hostingEnvironment, UploadFiles.Data.NorthwindContext context)
{
this.hostingEnvironment = hostingEnvironment;
this.context = context;
}
[HttpPost]
public IActionResult UploadFiles(IEnumerable<IFormFile> files, int orderId)
{
// Combine the orderId with the WebRootPath so files are stored per orderId
var dir = Path.Combine(hostingEnvironment.WebRootPath, orderId.ToString());
// Create the directory if it doesn't exist
Directory.CreateDirectory(dir);
var result = files.Select(file =>
{
// Save the files in the directory
var path = Path.Combine(dir, file.FileName);
using (var stream = new FileStream(path, FileMode.Create))
{
// Save the file
file.CopyTo(stream);
var request = HttpContext.Request;
// Create the URL for the uploaded file - not that orderId is part of the URL
var url = $"{request.Scheme}://{request.Host.Value}/{orderId}/{file.FileName}";
//Save the Record as an Order Attachment.
var t = new OrderAttachment
{
FileName = file.FileName,
Url = url,
OrderId = orderId
};
this.context.OrderAttachments.Add(t);
this.context.SaveChanges();
// Return the FileName and Url
return new
{
fileName = file.FileName,
Url = url,
OrderId = orderId
};
}
}).ToList();
// Return the file names and URL of the uploaded files
return Json(new { value = result }, new JsonSerializerSettings()
{
ContractResolver = new DefaultContractResolver()
});
}
}
}