Error in downloading a file in ASP.NET MVC - c#

I am working in ASP.NET MVC. I have stored a file in the database now I want to download and display its contents. I am working in layers.
Here is my code.
Controller Action used for uploading file
[HttpPost]
public ActionResult Edit(int id, UpdateAdvertisement model, HttpPostedFileBase file)
{
try
{
AdvertisementDTO add = new AdvertisementDTO();
add.DocImage = new byte[file.ContentLength];
add.ContentType = file.ContentType;
add.DocName = Convert.ToString(DateTime.Now.Ticks);
new AdvertisementHandler().Update(id, add);
return RedirectToAction("Index");
}
catch
{
return View();
}
}
Controller Action for downloading file
public FileContentResult DownloadFile(int id)
{
string DocumentContentType = new AdvertisementHandler().DownloadContent(id);
string DocumentName = new AdvertisementHandler().DownloadDocumentName(id);
byte[] DocumentImage = new AdvertisementHandler().DownloadImage(id);
//return File(filename, contentType, "Report.pdf");
return File(DocumentImage, DocumentContentType, DocumentName);
//return File.ReadAllBytes(DocumentName);
}
Business Logic Layer
These are the queries that are used to access database.
public byte[] DownloadImage(int id)
{
byte[] file = (from f in db.TBL_ADVERTISEMENT
where f.ID == id
select new AdvertisementDTO
{
DocImage = f.DOCUMENT_IMG
}
).ToArray();
return file;
}
public string DownloadContent(int id )
{
string file = (from f in db.TBL_ADVERTISEMENT
where f.ID == id
select new AdvertisementDTO
{
ContentType = f.CONTENTTYPE
}
).ToString();
return file;
}
public string DownloadDocumentName(int id)
{
string file = (from f in db.TBL_ADVERTISEMENT
where f.ID == id
select new AdvertisementDTO
{
DocName = f.DOC_NAME
}
).ToString();
return file;
}
This error arises when i compile this code
Error 1
Cannot implicitly convert type 'ORS.DTO.AdvertisementDTO[]' to 'byte[]'
F:\Projects\Online Recruitment System\ORS.BLL\AdvertisementHandler.cs 59 28 ORS.BLL
Here is my AdvertisementDTO...
namespace ORS.DTO
{
public class AdvertisementDTO
{
public int ID { get; set; }
public string AddNumber { get; set; }
public string Description { get; set; }
public byte[] DocImage { get; set; }
public string ContentType { get; set; }
public string DocName { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public int StatusID { get; set; }
public virtual RecordStatusDTO RecordStatus { get; set; }
}
}

Calling .ToArray() on an object does not convert it to a byte array. You omitted the definition of AdvertisementDTO so I can only guess that it is already a byte array. If that's not the case please post the code for AdvertisementDTO and I'll update this post.
byte[] file = (from f in db.TBL_ADVERTISEMENT
where f.ID == id
select f.DOCUMENT_IMG).SingleOrDefault();
return file;

Related

Bind List instead list c# linq From multiple source

i have my dto
public class DocumentForListDto
{
public int Id { get; set; }
public string Title { get; set; }
public string SubmittedBy { get; set; }
public DateTime SubmittedAt { get; set; }
public List<AuditsUpdateForListDto> UpdatedDocuments { get; set; }
}
public class AuditsForListDto
{
public string FullName { get; set; }
public DateTime UpdatedAt { get; set; }
}
and this code in my controller :
var docs = await _repo.Doc.Get();
and i have this audit to save any action in database
var aud = await _repo.Audit.FindByPrimaryKey(Constants.Doc, documents.Select(x => x.Id).ToList());
and this mapper for map my doc to dto(content)
var contents = _mapper.Map<IEnumerable<DocumentForListDto>>(docs);
and this my foreach to bind from audit to contents (CreatedBy/CreatedAt && UpdateBy/UpdatedAt)
if (contents.Any() && contents.Count() > 0 && audits.Any() && audits.Count()
> 0)
{
foreach (var content in contents)
{
//Search here by create Action
foreach (var audit in audits.Where(x =>
Convert.ToInt32(Regex.Match(x.PrimaryKey, #"\d+").Value) ==
content.Id && x.Type.Equals(Constants.Create)))
{
content.SubmittedBy = string.Concat(audit.User.FirstName, " ",
audit.User.LastName);
content.SubmittedAt = audit.DateTime;
}
}
//Here I need to bind list of Updated By and Updated At But I try many times but I don't find the right solution
}
i need to bind list of Updated By and Updated At i try with many logics but without success ??

How to use lambda expression to access correct data type?

I am using lambda expression to access values with data type, but the problem I have data type for Time as Time(7) on my local database and using Entity Framework. On my model this data type is define as DateTime.
How do I now access this data type to be time?
This is my code:
public List GetIncident_Details()
{
Entities incident = new Entities();
List result = new List();
var c_incident = incident.Incident_Template.Select(c => c).ToList();
if (c_incident != null && c_incident.Count() > 0)
{
foreach (var cData in c_incident)
{
Incident_DropDown model = new Incident_DropDown();
model.Title = cData.Title;
model.Description = cData.Description;
model.Date_Occurred = cData.Date_Occurred;
// How do I change this to have access?
// It's complaining about the data type object being set to a string?
model.Time = cData.Time;
model.Assignment_Group = cData.Assignment_Group;
model.Reported_CI = cData.Reported_CI;
result.Add(model);
}
}
return result;
}
public class Incident_DropDown
{
public string Title { get; set; }
public string Description { get; set; }
public string Date_Occurred { get; set; }
public DateTime Time { get; set; } // Time
public string Assignment_Group { get; set; }
public string Reported_CI { get; set; }
}
Took some advice from #alexey-rumyantsev, then had to test my code by interrogating model data type for Time it was Date Time, then change to Timespan. While testing this data type compare to my local database record and it was passing correct vales when debugging.
// Model name
public class Incident_DropDown
{
public string Title { get; set; }
public string Description { get; set; }
public string Date_Occured { get; set; }
public TimeSpan Time { get; set; } // had to change to work
public string Assignment_Group { get; set; }
public string Reported_CI { get; set; }
}
// Controller
public List<Incident_DropDown> GetIncident_Details()
{
Entities incident = new Entities();
List<Incident_DropDown> result = new List<Incident_DropDown>();
var c_incident = incident.Incident_Template.Select(c => c).ToList();
if (c_incident != null && c_incident.Count() > 0)
{
foreach (var cData in c_incident)
{
Incident_DropDown model = new Incident_DropDown();
model.Title = cData.Title;
model.Description = cData.Description;
model.Date_Occured = cData.Date_Occured;
model.Time = cData.Time; // This here enable to pass correct time as per database record
model.Assignment_Group = cData.Assignment_Group;
model.Reported_CI = cData.Reported_CI;
result.Add(model);
}
}
return result;
}

Problems passing parameter to an action

I'm trying to pass data to an action inside the same controller. I'm using RedirectToAction, but I'm not succeeding.
The action is called but the data I'm trying to pass to it has its values ​​null.
My Model:
public class PlaylistModel
{
public Guid PlayListID { get; set; }
[Display(Name = "Nome da Playlist")]
public string NomePlayList { get; set; }
[Display(Name = "Descrição")]
public string Descricao { get; set; }
[Display(Name = "Código")]
public string CodigoPlayList { get; set; }
public string Estado { get; set; }
public string EmailUser { get; set; }
public List<VideoThumbnails> VideosIdsYoutube { get; set; }
[Display(Name = "Categorias")]
public List<string> Categorias { get; set; }
}
This action receives the data, does the processing and calls the other action
[HttpPost]
public ActionResult CreatePlaylist(string Categorias, string NomePlayList)
{
PlaylistModel playListModel = new PlaylistModel();
playListModel.VideosIdsYoutube = AppCache.Instance.VideoParaAPI.VideoThumbnails.ToList();
playListModel.Categorias = Categorias.Split(',').ToList();
playListModel.NomePlayList = NomePlayList;
playListModel.Estado = EnumEstadoDaPlayList.Nova.ToString();
playListModel.EmailUser = AppUser.User.Email;
var api = new AccessAPI.Playlist.AccessAPIPlaylist();
var playlist = api.CriarNova(playListModel);
if(playlist != null)
{
return RedirectToAction("ExibirPlaylist", new RouteValueDictionary(new { controller = "Playlist", action = "ExibirPlaylist", pPlayList = playlist }));
}
else
{
return Problem("Não foi possível criar a playlist!");
}
}
This other action is called by the previous one, but the model arrives with null values
[HttpGet]
public ActionResult ExibirPlaylist(PlaylistModel pPlayList)
{
var apiVideo = new AccessAPI.Video.AccessAPIVideo();
var videos = apiVideo.ConsultarPorPlayListId(pPlayList.PlayListID).ToList();
if(videos.Count > 0)
{
videos.ForEach(v =>
{
pPlayList.VideosIdsYoutube.Add(new Dommain.Cache.VideoThumbnails() { CanalID = v.CanalID, DataDePublicacao = v.DataDePublicacao, NomeDoCanal = v.NomeDoCanal, NomeDoVideo = v.NomeDoVideo, Thumbnail = v.Thumbnail, VideoId = v.VideoIdYoutube});
});
}
return View();
}
The RouteValueDictionary in RedirectToAction() pass only simple types, like string, int etc. The RedirectToAction() doesn't serialize the complex data types. Therefore, may be the easiest way to use the TempData.
In the CreatePlaylist(string Categorias, string NomePlayList):
TempData["playListModel"] = playlist;
return RedirectToAction("ExibirPlaylist");
And then:
[HttpGet]
public ActionResult ExibirPlaylist()
{
if (TempData["playListModel"] is PlaylistModel pPlayList)
{
// Your code using `pPlayList`
}
return View("Index");
}
The MVC uses the binary serialization, by default. And in some cases the binary serialization can fail: Storing objects (non-string things) in TempDataDictionary does not round trip correctly. Therefore, it is preferably to serialize the specified object to a JSON string by JsonConvert.SerializeObject().

.NET 3.1: "An error occurred while updating the entries. See the inner exception for details"

I tried creating a log of the room containing the image and it reported this error
Error 500
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details
This is controller
[HttpPost]
public async Task<IActionResult> Create([FromForm]RoomCreateRequest request)
{
var roomId = await _manageRoomService.Create(request);
if (roomId == null)
return BadRequest();
var room = await _manageRoomService.GetById(roomId, request.LanguageId);
return CreatedAtAction(nameof(GetById), new { id = roomId }, room);
}
And this is service
public async Task<string> Create(RoomCreateRequest request)
{
var room = new Room()
{
Id = request.Id,
Price = request.Price,
NumberRoom = request.NumberRoom,
Status = RoomStatus.Empty,
RoomTranslations = new List<RoomTranslation>() {
new RoomTranslation()
{
Name = request.Name,
Description = request.Description,
SeoDescription = request.SeoDescription,
SeoTitle = request.SeoTitle,
SeoAlias = request.SeoAlias,
LanguageId = request.LanguageId
}
}
};
// Save Image
if (request.ThumbnailImage != null)
{
room.RoomImages = new List<RoomImage>()
{
new RoomImage()
{
Caption = "Thumbnail image",
DateCreated = DateTime.Now,
FileSize = request.ThumbnailImage.Length,
ImagePath = await this.SaveFile(request.ThumbnailImage),
IsDefault = true,
SortOrder = 1
}
};
}
_context.Rooms.Add(room);
await _context.SaveChangesAsync();
return room.Id;
}
Save File Image Method
// SaveFile Image
private async Task<string> SaveFile(IFormFile file)
{
var originalFileName =
ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
var fileName = $"{Guid.NewGuid()}{Path.GetExtension(originalFileName)}";
await _storageService.SaveFileAsync(file.OpenReadStream(), fileName);
return fileName;
}
This is FileStorageService code block await mediaBinaryStream.CopyToAsync(output); will copy name file and add to filename in "SaveFile" method, but in debug it not working.
public async Task SaveFileAsync(Stream mediaBinaryStream, string fileName)
{
var filePath = Path.Combine(_userContentFolder, fileName);
using var output = new FileStream(filePath, FileMode.Create);
await mediaBinaryStream.CopyToAsync(output);
}
This is Class RoomCreateRequest
public class RoomCreateRequest
{
public string Id { set; get; }
public decimal Price { set; get; }
public string NumberRoom { set; get; }
public string Name { set; get; }
public string Description { set; get; }
public string SeoDescription { set; get; }
public string SeoTitle { set; get; }
public string SeoAlias { get; set; }
public string LanguageId { set; get; }
public IFormFile ThumbnailImage { get; set; }
}
But if I don't add the image it works.
At the top of the exception it says Invalid Column name 'IsDefault'. In order to fix this problem you should have column named IsDefault in your your Room table.
※I am assuming your table is named Room based on your context object, it may be different in your case

Model for Post Request Edit Action Not being filled in by Model given by Get Request Edit Action

I have a ProductController with an Edit Action GetRequest and an Edit Action PostRequest .
The Edit GetRequest Action gets an individual Product entity based on route ID value from the request and builds a ProductViewModel. I have implicit conversion methods for these.
The View returned builds a ProductEditViewModel with the values fro the ProductViewModel:
// GET: Product/Edit/5
public async Task<ActionResult> Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
ProductViewModel product = await db.Products.FindAsync(id);
var categoryID = db.Categories.Single(c => c.Products.Any(p => p.Id == id)).Id;
if (product == null)
{
return HttpNotFound();
}
return View(new ProductEditViewModel { Id = product.Id, Name = product.Name, ByteImage = product.ByteImage, Price = product.Price, CategoryId = categoryID});
}
I have access to the Edit GetRequest page when running my applicion and can see a Product displayed successfully to edit, however, when I send back a Post request, the ProductEditViewModel that is given to the Edit PostRequest Action is empty. It should have the Name and Id properties filled in as the Image can be left unchanged. Here is my Edit PostRequest Action:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit([Bind(Include = "Id,Name,Image,Price")] ProductEditViewModel model)
{
var oldImage = db.Products.Where(p => p.Id == model.Id).Select(x => x.Image).FirstOrDefault();
if (ModelState.IsValid)
{
Product modifiedProduct = model;
if(modifiedProduct.Image == null)
{
modifiedProduct.Image = oldImage;
}
db.Entry(modifiedProduct).State = EntityState.Modified;
await db.SaveChangesAsync();
return RedirectToAction("Index/" + model.categoryID);
}
return View(model);
}
My ProductViewModels:
public class ProductViewModel
{
public int Id { get; set; }
[Required, Display(Name="Product Name")]
public string Name { get; set; }
[DataType(DataType.Upload)]
public HttpPostedFileBase Image { get; set; }
public string OutputImage { get; set; }
public Byte[] ByteImage { get; set; }
[Required]
public Decimal Price { get; set; }
public int CategoryId { get; set; }
public static byte[] ConvertToByte(ProductViewModel model)
{
if (model.Image != null)
{
byte[] imageByte = null;
BinaryReader rdr = new BinaryReader(model.Image.InputStream);
imageByte = rdr.ReadBytes((int)model.Image.ContentLength);
return imageByte;
}
return null;
}
// ViewModel => Model | Implicit type Operator
public static implicit operator Product(ProductViewModel viewModel)
{
var model = new Product
{
Id = viewModel.Id,
Name = viewModel.Name,
Image = ConvertToByte(viewModel),
Price = viewModel.Price
};
return model;
}
// Model => ViewModel | Implicit type Operator
public static implicit operator ProductViewModel(Product model)
{
var viewModel = new ProductViewModel
{
Id = model.Id,
Name = model.Name,
OutputImage = string.Format("data:image/jpg;base64,{0}", Convert.ToBase64String(model.Image)),
ByteImage = model.Image,
Price = model.Price,
CategoryId = model.Id
};
return viewModel;
}
}
ProductEditViewModel:
public class ProductEditViewModel
{
public int Id { get; set; }
[Required, Display(Name = "Product Name")]
public string Name { get; set; }
[DataType(DataType.Upload)]
public HttpPostedFileBase Image { get; set; }
public string OutputImage { get; set; }
public byte[] ByteImage { get; set; }
[Required]
public decimal Price { get; set; }
public int? CategoryId { get; set; }
public static implicit operator ProductViewModel(ProductEditViewModel viewModel)
{
var model = new Product
{
Id = viewModel.Id,
Name = viewModel.Name,
Image = ConvertToByte(viewModel),
Price = viewModel.Price
};
return model;
}
public static implicit operator ProductEditViewModel(ProductViewModel viewModel)
{
var model = new ProductEditViewModel
{
Id = viewModel.Id,
Name = viewModel.Name,
ByteImage = ConvertToByte(viewModel),
Price = viewModel.Price
};
return model;
}
private static byte[] ConvertToByte(ProductEditViewModel viewModel)
{
if (viewModel.Image != null)
{
byte[] imageByte = null;
BinaryReader rdr = new BinaryReader(viewModel.Image.InputStream);
imageByte = rdr.ReadBytes((int)viewModel.Image.ContentLength);
return imageByte;
}
return null;
}
}
I didn't have the getters and setters for the ProductEditViewModel to be able to assign values.

Categories

Resources