I need to store the path of the file along with its properties into a sql database. Currently all I can do is store the file on the server. I can see the file properties in the controller but I do not know how to access them.
public class File
{
public int FileId { get; set; }
public string FileType { get; set; }
public string FileDate { get; set; }
public string FilePdf { get; set; }
public string FileLocation { get; set; }
public string FilePlant { get; set; }
public string FileTerm { get; set; }
public DateTime? FileUploadDate { get; set; }
public string FileUploadedBy { get; set; }
public string CompanyName { get; set; }
public virtual ApplicationUser User { get; set; }
}
Controller
[HttpPost]
public async Task<HttpResponseMessage> PostFile()
{
if (!Request.Content.IsMimeMultipartContent())
{
this.Request.CreateResponse(HttpStatusCode.UnsupportedMediaType);
}
string root = HttpContext.Current.Server.MapPath("~/App_Data");
var provider = new MultipartFormDataStreamProvider(root);
var result = await Request.Content.ReadAsMultipartAsync(provider);
foreach (var key in provider.FormData.AllKeys)
{
foreach (var val in result.FormData.GetValues("companyname")
.FirstOrDefault())
{
if (key == "companyName")
{
var companyName = val;
var fileDate = val;
var fileLocation = val;
var filePlant = val;
var fileTerm = val;
var fileType = val;
var fileUploadDate = val;
var fileUploadedBy = val;
}
}
}
// On upload, files are given a generic name like "BodyPart_26d6abe1-3ae1-416a-9429-b35f15e6e5d5"
// so this is how you can get the original file name
var originalFileName = GetDeserializedFileName(result.FileData.First());
var uploadedFileInfo = new FileInfo(result.FileData.First().LocalFileName);
string path = result.FileData.First().LocalFileName;
//Do whatever you want to do with your file here
//db.Files.Add();
db.SaveChanges();
return this.Request.CreateResponse(HttpStatusCode.OK, originalFileName);
}
private string GetDeserializedFileName(MultipartFileData fileData)
{
var fileName = GetFileName(fileData);
return JsonConvert.DeserializeObject(fileName).ToString();
}
public string GetFileName(MultipartFileData fileData)
{
return fileData.Headers.ContentDisposition.FileName;
}
Try using a function like this. You can replace with
private object GetFormData<T>(MultipartFormDataStreamProvider result)
{
if (result.FormData.HasKeys())
{
var unescapedFormData = Uri.UnescapeDataString(result.FormData
.GetValues(0).FirstOrDefault() ?? String.Empty);
if (!String.IsNullOrEmpty(unescapedFormData))
return JsonConvert.DeserializeObject<T>(unescapedFormData);
}
return null;
}
Use it like this
File file = GetFormData(result);
The main line of code you want is:
JsonConvert.DeserializeObject<File>(result.FormData.GetValues(0).FirstOrDefault());
Related
I have send a formData from react app with some value and image files and i also want to send a obj with same formData on .net core api
Here is my class
[Bind]
public class ServiceInfo
{
public int id { get; set; }
[NotMapped]
public IFormFile[] ImgFile { get; set; }
[NotMapped]
public IFormFile ImgFilen { get; set; }
//public int { get; set; }
public string title { get; set; }
public string serImg1 { get; set; }
public string serImg2 { get; set; }
public string serImg3 { get; set; }
public string serImg4 { get; set; }
public int serCategoryId { get; set; }
public SerCategory serCategory { get; set; }
public string time { get; set; }
public string location { get; set; }
public string serviceClose { get; set; }
public string serviceOpen { get; set; }
public int CompanyInfoId { get; set; }
public virtual CompanyInfo companyInfo { get; set; }
public string serviceDetails { get; set; }
public string offeredServices { get; set; }
public bool active { get; set; }
public bool status { get; set; }
public string extraServices { get; set; }
public string whyUs { get; set; }
}
.net core controler:
serCategory always getting null
[Route("PotService")]
[HttpPost]
public IActionResult Post([FromForm] ServiceInfo service)
{
//using (MemoryStream stream = new MemoryStream())
//{
// ImgFile.CopyToAsync(stream);
// service.Data = stream.ToArray();
//}
if (string.IsNullOrWhiteSpace(_rootPath.WebRootPath))
{
_rootPath.WebRootPath = Path.Combine(Directory.GetCurrentDirectory(), "Images");
}
string uploadsFolder = Path.Combine(_rootPath.WebRootPath);
int index = 0;
foreach (var item in service.ImgFile)
{
index++;
if (item != null)
{
var uniqueFileName = service.title.ToString()+index.ToString()+ DateTime.Now.ToString("ddMMyyy") + "_" + item.FileName;
string filePath = Path.Combine(uploadsFolder, uniqueFileName);
switch (index)
{
case 1 :
service.serImg1 = uniqueFileName;
break;
case 2:
service.serImg2 = uniqueFileName;
break;
case 3:
service.serImg3 = uniqueFileName;
break;
case 4:
service.serImg4 = uniqueFileName;
break;
}
}
}
//bool result = _serManager.AddService(service);
foreach (var item in service.ImgFile)
{
if (item != null)
{
var uniqueFileName = service.title.ToString() + index.ToString() + DateTime.Now.ToString("ddMMyyy") + "_" + item.FileName;
string filePath = Path.Combine(uploadsFolder, uniqueFileName);
using (var fileStream = new FileStream(filePath, FileMode.Create))
{
item.CopyTo(fileStream);
}
}
}
return Ok(true);
}
And react code :
const formData = new FormData();
formData.append("id", 0);
formData.append("CompanyInfoId", activeComId);
formData.append("title", data.title);
formData.append("time", "");
formData.append("location", data.location.value);
formData.append("serviceClose", data.serviceClose.value);
formData.append("serviceOpen", data.serviceOpen);
formData.append("serviceDetails", data.serviceDetails);
formData.append("serCategoryId", data.serType.id);
formData.append("serCategory", data.serType);
formData.append("offeredServices", data.offeredServices);
formData.append("active", false);
formData.append("status", false);
formData.append("extraServices", data.extraServices);
formData.append("whyUs", data.whyUs);
formData.append("ImgFile", data.serImg1);
formData.append("ImgFile", data.serImg2);
formData.append("ImgFile", data.serImg3);
formData.append("ImgFile", data.serImg4);
for (const [key, value] of formData.entries()) {
console.log(key, value);
}
console.log(data.serType);
const res = await fetch(serPost, {
method: "POST",
body: formData,
});
I created a personal info page to display all the data according to specific username entered. Unfortunately, the edit text didn't display all the data from the SQL Server. It only shows 2/8 data. I'm using a WEB API to retrieve the data and the data is stored in SQL Server. Can you help me to fix this problem please!!
I obtained this code from a website and i follow step by step according to the website. I've tried using Web services, it didn't work ass well.
VehicleRecord.cs
public class VehicleRecord
{
public string clFullName{ get; set; }
public string clGender{ get; set; }
public string clICNo { get; set; }
public string clAddress { get; set; }
public string clPhoneNo { get; set; }
public string clEmail { get; set; }
public string clUsername { get; set; }
public string clPwd { get; set; }
public string clVehicPlateNo { get; set; }
public string clVehicModel { get; set; }
public string clVehicCol { get; set; }
public string clPaymentMethod { get; set; }
public VehicleRecord()
{
this.clFullName = "";
this.clGender = "";
this.clICNo = "";
this.clAddress = "";
this.clPhoneNo = "";
this.clEmail = "";
this.clUsername = "";
this.clPwd = "";
this.clVehicPlateNo = "";
this.clVehicModel = "";
this.clVehicCol = "";
this.clPaymentMethod = "";
}
}
Service.cs
public class Service
{
public static async Task<dynamic> getServiceData(string queryString)
{
dynamic acc = null;
HttpClient client = new HttpClient();
var response = await client.GetAsync(queryString);
if(response != null)
{
string json = response.Content.ReadAsStringAsync().Result;
acc = JsonConvert.DeserializeObject(json);
}
return acc;
}
}
Acc.cs
public class Acc
{
public static async Task<VehicleRecord> GetAcc(string username)
{
string queryString = "http://xxx.xxx.x.xxx/PMSAPI1/api/users/" + username;
dynamic results = await Service.getServiceData(queryString).ConfigureAwait(false);
if(results != null)
{
VehicleRecord vehicleRecord = new VehicleRecord();
vehicleRecord.clFullName = (string)results["clFullName"];
vehicleRecord.clGender = (string)results["clGender"];
vehicleRecord.clICNo = (string)results["clICNo"];
vehicleRecord.clAddress = (string)results["clAddress"];
vehicleRecord.clPhoneNo = (string)results["clPhoneNo"];
vehicleRecord.clEmail = (string)results["clEmail"];
vehicleRecord.clPwd = (string)results["clPwd"];
vehicleRecord.clVehicPlateNo = (string)results["clVehicPlateNo"];
vehicleRecord.clVehicModel = (string)results["clVehicModel"];
vehicleRecord.clVehicCol = (string)results["clVehicCol"];
vehicleRecord.clPaymentMethod = (string)results["clPaymentMethod"];
return vehicleRecord;
}
else
{
return null;
}
}
}
PersonalInfoActivity.cs
private async void BtnGetAcc_Click(object sender, EventArgs e)
{
EditText username = FindViewById<EditText>(Resource.Id.txtUsername);
if (!String.IsNullOrEmpty(username.Text))
{
VehicleRecord vehicleRecord = await Acc.GetAcc(username.Text);
FindViewById<EditText>(Resource.Id.txtFullName).Text = vehicleRecord.clFullName;
FindViewById<EditText>(Resource.Id.txtGender).Text = vehicleRecord.clGender;
FindViewById<EditText>(Resource.Id.txtIC).Text = vehicleRecord.clICNo;
FindViewById<EditText>(Resource.Id.txtAddress).Text = vehicleRecord.clAddress;
FindViewById<EditText>(Resource.Id.txtPhoneNo).Text = vehicleRecord.clPhoneNo;
FindViewById<EditText>(Resource.Id.txtEmail).Text = vehicleRecord.clEmail;
FindViewById<EditText>(Resource.Id.txtPwd).Text = vehicleRecord.clPwd;
FindViewById<EditText>(Resource.Id.txtPayMethod).Text = vehicleRecord.clPaymentMethod;
}
}
The expected output should display all the data according to the username entered, but the actual output only displayed 2/8 data.
The error that i get is System.NullReferenceException:Object reference not set to an instance of an object.
The output displayed on screen
It seems to me that the issue starts at this line
vehicleRecord.clICNo = (string)results["clICNo"];
IMO results does not contains "clICNo". Check this by surrounding this line in try - catch block.
I am using visual studio 2017 with asp mvc 5.0 and angularJS v1.6.10. I need to send object from angularJS to asp controller via $http service see the following code
public class Patient
{
public int Age { get; set; }
public byte Gender { get; set; }
public bool IsSmoker { get; set; }
public string[] Symptoms { get; set; }
public bool FractionWithTbPatient { get; set; }
public bool PreviousTbInfection { get; set; }
public bool Inheritedcysricfibrosis { get; set; }
public bool Inheritedasthma { get; set; }
public bool Smokermother { get; set; }
public bool OrganicDust { get; set; }
public bool FractionWithanimals { get; set; }
public bool PreviousSurgery { get; set; }
public bool Longbonebroken { get; set; }
public bool Pregnant { get; set; }
public bool CancerInfection { get; set; }
public bool LongTimeInBed { get; set; }
public bool PreviousInfectionWithPulmonaryEmbolism { get; set; }
}
and the asp controller method is the following
public class ConditionDiagnosisController : Controller{
[HttpPost]
public void GetCaseResult(Patient patient)
{
int i = 0;
i++;
}
}
and the angularJS controller is the follwoing
myApp.controller("mainController",
function ($scope, $http) {
var patient = new Object();
patient.Age = 1;
patient.Gender = 0;
patient.IsSmoker = false;
patient.Inheritedasthma = false;
patient.Symptoms = ['x','y'];
patient.Pregnant = false;
patient.FractionWithTbPatient = false;
patient.PreviousTbInfection = false;
patient.Inheritedcysricfibrosis = false;
patient.Inheritedasthma = false;
patient.Smokermother = false;
patient.OrganicDust = false;
patient.FractionWithanimals = false;
patient.PreviousSurgery = false;
patient.Longbonebroken = false;
patient.Pregnant = false;
patient.CancerInfection = false;
patient.LongTimeInBed = false;
patient.PreviousInfectionWithPulmonaryEmbolism = false;
$scope.go = function () {
$http({
method: "POST",
url: "/ConditionDiagnosis/GetCaseResult",
dataType: 'json',
data: $scope.patient,
headers: { "Content-Type": "application/json" }
});
};
});
when I send it I get in the asp method all values of the object correctly else the Symptoms variable which is a string array, I get it null. Any help?
Try with this data : JSON.stringify($scope.patient)
in the ASP.NET class, you should assign the Array in the constructor.
the issue will be that you can't assign the array so the best way is to use List
change the type of Symptoms to List and then in the constructor write this code:
public Patient(){
Symptoms = new List();
}
I'm trying to download an file what can be pdf, cvs, word, jpg or png. To do this, I'm using angularjs + filesaver.js. don't know why but, my downloads are always corrupted.
Someone can help me ?
Note:
midia.Nome - Name of my file.
midia.Tipo - The type of the file.
midia.Path - Physical path on project.
midia.MidiaBytesString - Bytes
on Base64 to convert to blob.
Download <br />
My File download method:
$scope.Download = function(bytes,nome,tipo){
var file = new File([bytes], nome , {type: "application/octet-stream"});
saveAs(file);
};
My View Model
public class MidiaViewModel
{
public int MidiaId { get; set; }
public string MidiaDescricao { get; set; }
//public string MidiaPath { get; set; }
public byte[] MidiaBytes { get; set; }
public string MidiaBytesString { get; set; }
public int OsId { get; set; }
public virtual OsViewModel Os { get; set; }
public string MidiaNome { get; set; }
public string MidiaType { get; set; }
public string MidiaPath { get; set; }
public long MidiaSize { get; set; }
}
My register Midia:
[HttpPost]
public JsonResult AtualizarMidias(IEnumerable<HttpPostedFileBase> arquivos, IEnumerable<string> descricoes, int osId)
{
var ordermDeServico = _osService.ObterPorIdLazyLoad(osId);
foreach (var file in arquivos)
{
string targetFolder = HttpContext.Server.MapPath("~/Content/uploads/");
string targetPath = Path.Combine(targetFolder, file.FileName);
if (file != null && file.ContentLength > 0)
{
var itens = arquivos.ToList();
var des = descricoes.ToList();
var index = itens.FindIndex(c => c.FileName == file.FileName);
var midiaViewModel = new MidiaViewModel
{
MidiaType = file.ContentType,
MidiaNome = file.FileName,
MidiaPath = targetPath,
MidiaSize = file.ContentLength,
MidiaDescricao = des[index].ToString(),
MidiaBytes = converterArquivo(file)
};
var midia = Mapper.Map<MidiaViewModel, Midia>(midiaViewModel);
midia.OsId = ordermDeServico.OSId;
file.SaveAs(targetPath);
_midiaService.Salvar(midia);
}
}
return Json(new { resultado = true }, JsonRequestBehavior.AllowGet);
}
And where i make the call to my angular $scope:
[HttpPost]
public string getMidiasOS(int idOS)
{
var getMidias = _midiaService.ObterMidiaPorIdOs(idOS);
List<MidiaAngularViewModel> midiaNova = new List<MidiaAngularViewModel>();
foreach (var midia in getMidias)
{
midiaNova.Add(new MidiaAngularViewModel
{
Id = midia.MidiaId,
Path = midia.MidiaPath,
Tipo = midia.MidiaType,
Descricao = midia.MidiaDescricao,
MidiaBytesString = Convert.ToBase64String(midia.MidiaBytes),
Nome = midia.MidiaNome
});
}
return JsonConvert.SerializeObject(midiaNova);
}
EDIT
Guys, I solved my problem using the Ameni topic in the follow link: download file using angularJS and asp.net mvc
All I need to do was create like the Post method on the Ameni topic and the download by path function.
Simply add/use the download attribute and you will be fine. More about download attribute can be found at w3c download documentation.
Download
I am using Simple Membership and a UserProfile table that maintains UserId and UserName:
public partial class UserProfile
{
public UserProfile()
{
this.webpages_Roles = new List<webpages_Roles>();
}
public int UserId { get; set; }
public string UserName { get; set; }
public virtual ICollection<webpages_Roles> webpages_Roles { get; set; }
}
With Entity Framework I am running the following which is inside my Context:
public partial class UowContext : DbContext
// code to set up DbSets here ...
public DbSet<Content> Contents { get; set; }
private void ApplyRules()
{
var r1 = new Random();
var r2 = new Random();
foreach (var entry in this.ChangeTracker.Entries()
.Where(
e => e.Entity is IAuditableTable &&
(e.State == EntityState.Added) ||
(e.State == EntityState.Modified)))
{
IAuditableTable e = (IAuditableTable)entry.Entity;
if (entry.State == EntityState.Added)
{
e.CreatedBy = // I want to put the integer value of UserId here
e.CreatedDate = DateTime.Now;
}
e.ModifiedBy = // I want to put the integer value of UserId here
e.ModifiedDate = DateTime.Now;
}
}
Here is the schema showing how user information is stored. Note that I store the integer UserId and not the UserName in the tables:
public abstract class AuditableTable : IAuditableTable
{
public virtual byte[] Version { get; set; }
public int CreatedBy { get; set; }
public DateTime CreatedDate { get; set; }
public int ModifiedBy { get; set; }
public DateTime ModifiedDate { get; set; }
}
Here's an example of a controller action that I use:
public HttpResponseMessage PostContent(Content content)
{
try
{
_uow.Contents.Add(content);
_uow.Commit();
var response = Request.CreateResponse<Content>(HttpStatusCode.Created, content);
return response;
}
catch (DbUpdateException ex)
{
return Request.CreateErrorResponse(HttpStatusCode.Conflict, ex);
}
}
I then have:
public class UowBase : IUow, IDisposable
{
public UowBase(IRepositoryProvider repositoryProvider)
{
CreateDbContext();
repositoryProvider.DbContext = DbContext;
RepositoryProvider = repositoryProvider;
}
public IRepository<Content> Contents { get { return GetStandardRepo<Content>(); } }
and:
public class GenericRepository<T> : IRepository<T> where T : class
{
public GenericRepository(DbContext dbContext)
{
if (dbContext == null)
throw new ArgumentNullException("An instance of DbContext is required to use this repository", "context");
DbContext = dbContext;
DbSet = DbContext.Set<T>();
}
public virtual void Add(T entity)
{
DbEntityEntry dbEntityEntry = DbContext.Entry(entity);
if (dbEntityEntry.State != EntityState.Detached)
{
dbEntityEntry.State = EntityState.Added;
}
else
{
DbSet.Add(entity);
}
}
How can I determine the UserId from inside of my Context so I can populate the Id in my tables?
In Code you will have UserName with you through:
HttpContext.Current.User.Identity.Name
you can than query UserProfile table against that Name and get the UserId from there and than assign it to ModifiedBy attribute.
Make sure that you query UserProfile table outside the foreach loop :)