Reputation: 29
I am new to dotnet and asp.net (C #) and want to get the image (s) from users and then show them on the index page. How can I do this?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace RealEstateSystem.Models
{
public class PropertyDetails
{
public PropertyDetails()
{
}
public int ID { get; set; }
public string ShortDetails { get; set; }
public string Description { get; set; }
public byte[] Images { get; set; }
}
}
insede views.PropertyDetails.(Create.cshtml):
@model RealEstateSystem.Models.PropertyDetails
@{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>PropertyDetails</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="ShortDetails" class="control-label"></label>
<input asp-for="ShortDetails" class="form-control" />
<span asp-validation-for="ShortDetails" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Description" class="control-label"></label>
<input asp-for="Description" class="form-control" />
<span asp-validation-for="Description" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Images" class="control-label"></label>
@*<input asp-for="Images" class="form-control" />*@
<input type="file" accept="image/*" asp-for="Images" class="form-control-file" />
<span asp-validation-for="Images" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
<div>
<a asp-action="Index">Back to List</a>
</div>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
inside views.PropertyDetails.(index.cshtml):
@model IEnumerable<RealEstateSystem.Models.PropertyDetails>
@{
ViewData["Title"] = "Index";
}
<h1>Index</h1>
<p>
<a asp-action="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.ShortDetails)
</th>
<th>
@Html.DisplayNameFor(model => model.Description)
</th>
<th>
@Html.DisplayNameFor(model => model.Images)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.ShortDetails)
</td>
<td>
@Html.DisplayFor(modelItem => item.Description)
</td>
<td>
@Html.DisplayFor(modelItem => item.Images)
</td>
<td>
<a asp-action="Edit" asp-route-id="@item.ID">Edit</a> |
<a asp-action="Details" asp-route-id="@item.ID">Details</a> |
<a asp-action="Delete" asp-route-id="@item.ID">Delete</a>
</td>
</tr>
}
</tbody>
</table>
inside Controllers.PropertyDetails:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.EntityFrameworkCore;
using RealEstateSystem.Data;
using RealEstateSystem.Models;
namespace RealEstateSystem.Controllers
{
public class PropertyDetailsController : Controller
{
private readonly ApplicationDbContext _context;
public PropertyDetailsController(ApplicationDbContext context)
{
_context = context;
}
// GET: PropertyDetails
public async Task<IActionResult> Index()
{
return View(await _context.PropertyDetails.ToListAsync());
}
// GET: PropertyDetails/Details/5
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return NotFound();
}
var propertyDetails = await _context.PropertyDetails
.FirstOrDefaultAsync(m => m.ID == id);
if (propertyDetails == null)
{
return NotFound();
}
return View(propertyDetails);
}
// GET: PropertyDetails/Create
public IActionResult Create()
{
return View();
}
// POST: PropertyDetails/Create
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("ID,ShortDetails,Description,Images")] PropertyDetails propertyDetails)
{
if (ModelState.IsValid)
{
_context.Add(propertyDetails);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(propertyDetails);
}
// GET: PropertyDetails/Edit/5
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var propertyDetails = await _context.PropertyDetails.FindAsync(id);
if (propertyDetails == null)
{
return NotFound();
}
return View(propertyDetails);
}
// POST: PropertyDetails/Edit/5
// To protect from overposting attacks, enable the specific properties you want to bind to.
// For more details, see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("ID,ShortDetails,Description,Images")] PropertyDetails propertyDetails)
{
if (id != propertyDetails.ID)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(propertyDetails);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!PropertyDetailsExists(propertyDetails.ID))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
return View(propertyDetails);
}
// GET: PropertyDetails/Delete/5
public async Task<IActionResult> Delete(int? id)
{
if (id == null)
{
return NotFound();
}
var propertyDetails = await _context.PropertyDetails
.FirstOrDefaultAsync(m => m.ID == id);
if (propertyDetails == null)
{
return NotFound();
}
return View(propertyDetails);
}
// POST: PropertyDetails/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
var propertyDetails = await _context.PropertyDetails.FindAsync(id);
_context.PropertyDetails.Remove(propertyDetails);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
private bool PropertyDetailsExists(int id)
{
return _context.PropertyDetails.Any(e => e.ID == id);
}
}
}
I searched the web but did not find any questions like this. Thank you for helping me.
Upvotes: 0
Views: 2745
Reputation: 949
Asp.net core use IFormFile to accept the file,you can check my demo:
The file in database is a string which is the name of the picture in wwwroot, it is transformed by the Iformfile.
Model:
public class PropertyDetails
{
public int ID { get; set; }
public string ShortDetails { get; set; }
public string Description { get; set; }
public string Images { get; set; } //to string
}
Create action:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("ID,ShortDetails,Description,Images")] PropertyDetails propertyDetails,IFormFile file)
{
if (ModelState.IsValid)
{
string uniqueFileName = null; //to contain the filename
if (file!= null) //handle iformfile
{
string uploadsFolder = Path.Combine(webHostEnvironment.WebRootPath, "Images");
uniqueFileName =file.FileName;
string filePath = Path.Combine(uploadsFolder, uniqueFileName);
using (var fileStream = new FileStream(filePath, FileMode.Create))
{
file.CopyTo(fileStream);
}
}
propertyDetails.Images = uniqueFileName; //fill the image property
_context.Add(propertyDetails); //save
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(propertyDetails);
}
Index.cshtml:
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.ShortDetails)
</td>
<td>
@Html.DisplayFor(modelItem => item.Description)
</td>
<td>
<img src="~/Images/@item.Images" height="40" width="40"
asp-append-version="true">
</td>
<td>
<a asp-action="Edit" asp-route-id="@item.ID">Edit</a> |
<a asp-action="Details" asp-route-id="@item.ID">Details</a> |
<a asp-action="Delete" asp-route-id="@item.ID">Delete</a>
</td>
</tr>
}
Create.cshtml:
<div class="row">
<div class="col-md-4">
<form asp-action="Create" enctype="multipart/form-data">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
//....
<div class="form-group">
<label asp-for="Images" class="control-label"></label>
<input type="file" name="file" class="form-control-file" />
<span asp-validation-for="Images" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
Result:
Upvotes: 1