Я опишу способ хранения файлов в SQL Server и Oracle. Во многом это зависит от того, как вы получаете файл, в первую очередь от того, как вы получите его содержимое, и от базы данных, которую вы используете для контента, в котором вы будете его хранить, и от того, как вы будете его хранить. Это 2 отдельных примера базы данных с 2 отдельными способами получения файла, который я использовал.
SQL Server
Краткий ответ: я использовал байтовую строку base64, которую я преобразовал в byte[]
и сохранил в поле varbinary(max)
.
Длинный ответ:
Допустим, вы загружаете через веб-сайт, поэтому вы используете элемент управления <input id="myFileControl" type="file" />
или React DropZone. Чтобы получить файл, вы делаете что-то вроде var myFile = document.getElementById("myFileControl")[0];
или myFile = this.state.files[0];
.
Оттуда я получу строку base64, используя здесь код: Преобразование ввода = файл в байтовый массив (используйте функцию UploadFile2
).
Затем я получу эту строку, имя файла (myFile.name
) и тип (myFile.type
) в объект JSON:
var myJSONObj = {
file: base64string,
name: myFile.name,
type: myFile.type,
}
и отправьте файл в серверную часть MVC с помощью XMLHttpRequest, указав Content-Type application/json
: xhr.send(JSON.stringify(myJSONObj);
. Вы должны построить ViewModel, чтобы связать его с:
public class MyModel
{
public string file { get; set; }
public string title { get; set; }
public string type { get; set; }
}
и укажите [FromBody]MyModel myModelObj
в качестве переданного параметра:
[System.Web.Http.HttpPost] // required to spell it out like this if using ApiController, or it will default to System.Mvc.Http.HttpPost
public virtual ActionResult Post([FromBody]MyModel myModelObj)
Затем вы можете добавить это в эту функцию и сохранить ее с помощью Entity Framework:
MY_ATTACHMENT_TABLE_MODEL tblAtchm = new MY_ATTACHMENT_TABLE_MODEL();
tblAtchm.Name = myModelObj.name;
tblAtchm.Type = myModelObj.type;
tblAtchm.File = System.Convert.FromBase64String(myModelObj.file);
EntityFrameworkContextName ef = new EntityFrameworkContextName();
ef.MY_ATTACHMENT_TABLE_MODEL.Add(tblAtchm);
ef.SaveChanges();
tblAtchm.File = System.Convert.FromBase64String(myModelObj.file);
является оперативной линией.
Вам потребуется модель для представления таблицы базы данных:
public class MY_ATTACHMENT_TABLE_MODEL
{
[Key]
public byte[] File { get; set; } // notice this change
public string Name { get; set; }
public string Type { get; set; }
}
Это сохранит данные в поле varbinary(max)
как byte[]
. Name
и Type
были nvarchar(250)
и nvarchar(10)
соответственно. Вы можете включить размер, добавив его в таблицу в виде столбца int
и MY_ATTACHMENT_TABLE_MODEL
как public int Size { get; set;}
и добавив строку tblAtchm.Size = System.Convert.FromBase64String(myModelObj.file).Length;
выше.
Oracle
Краткий ответ: преобразуйте его в byte[]
, присвойте его OracleParameter
, добавьте его в OracleCommand
и обновите поле BLOB
таблицы, используя ссылку на значение ParameterName
параметра: :BlobParameter
Длинный ответ:
Когда я делал это для Oracle, я использовал OpenFileDialog
и извлек и отправил информацию о байтах / файле следующим образом:
byte[] array;
OracleParameter param = new OracleParameter();
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
dlg.Filter = "Image Files (*.jpg, *.jpeg, *.jpe)|*.jpg;*.jpeg;*.jpe|Document Files (*.doc, *.docx, *.pdf)|*.doc;*.docx;*.pdf"
if (dlg.ShowDialog().Value == true)
{
string fileName = dlg.FileName;
using (FileStream fs = File.OpenRead(fileName)
{
array = new byte[fs.Length];
using (BinaryReader binReader = new BinaryReader(fs))
{
array = binReader.ReadBytes((int)fs.Length);
}
// Create an OracleParameter to transmit the Blob
param.OracleDbType = OracleDbType.Blob;
param.ParameterName = "BlobParameter";
param.Value = array; // <-- file bytes are here
}
fileName = fileName.Split('\\')[fileName.Split('\\').Length-1]; // gets last segment of the whole path to just get the name
string fileType = fileName.Split('.')[1];
if (fileType == "doc" || fileType == "docx" || fileType == "pdf")
fileType = "application\\" + fileType;
else
fileType = "image\\" + fileType;
// SQL string containing reference to BlobParameter named above
string sql = String.Format("INSERT INTO YOUR_TABLE (FILE_NAME, FILE_TYPE, FILE_SIZE, FILE_CONTENTS, LAST_MODIFIED) VALUES ('{0}','{1}',{2},:BlobParamerter, SYSDATE)", fileName, fileType, array.Length);
// Do Oracle Update
RunCommand(sql, param);
}
А внутри обновления Oracle, выполненного с помощью ADO:
public void RunCommand(string sql, OracleParameter param)
{
OracleConnection oraConn = null;
OracleCommand oraCmd = null;
try
{
string connString = GetConnString();
oraConn = OracleConnection(connString);
using (oraConn)
{
if (OraConnection.State == ConnectionState.Open)
OraConnection.Close();
OraConnection.Open();
oraCmd = new OracleCommand(strSQL, oraConnection);
// Add your OracleParameter
if (param != null)
OraCommand.Parameters.Add(param);
// Execute the command
OraCommand.ExecuteNonQuery();
}
}
catch (OracleException err)
{
// handle exception
}
finally
{
OraConnction.Close();
}
}
private string GetConnString()
{
string host = System.Configuration.ConfigurationManager.AppSettings["host"].ToString();
string port = System.Configuration.ConfigurationManager.AppSettings["port"].ToString();
string serviceName = System.Configuration.ConfigurationManager.AppSettings["svcName"].ToString();
string schemaName = System.Configuration.ConfigurationManager.AppSettings["schemaName"].ToString();
string pword = System.Configuration.ConfigurationManager.AppSettings["pword"].ToString(); // hopefully encrypted
if (String.IsNullOrEmpty(host) || String.IsNullOrEmpty(port) || String.IsNullOrEmpty(serviceName) || String.IsNullOrEmpty(schemaName) || String.IsNullOrEmpty(pword))
{
return "Missing Param";
}
else
{
pword = decodePassword(pword); // decrypt here
return String.Format(
"Data Source=(DESCRIPTION =(ADDRESS = ( PROTOCOL = TCP)(HOST = {2})(PORT = {3}))(CONNECT_DATA =(SID = {4})));User Id={0};Password{1};",
user,
pword,
host,
port,
serviceName
);
}
}
И тип данных для столбца FILE_CONTENTS
был BLOB
, FILE_SIZE
был NUMBER(10,0)
, LAST_MODIFIED
был DATE
, а остальные были NVARCHAR2(250)
.