Allow user to see only their uploaded data (Asp.NET MVC5) - asp.net

I can upload and download the uploaded files, but I want that users to be able to see only their files. (user1 to see only his data, not also user2's data) How could I do it? Any idea could help. Thanks!
This is my controller, I know that between admin, user, editor I can restrict the access with Authorize, but this wouldn't help me restricting the access between user_id's.
(need to mention that privacy is a very important aspect of my project)
public class FileUploadController : Controller
{
// GET: FileUpload
public ActionResult Index()
{
var items = GetFiles();
return View(items);
}
// POST: FileUpload
[HttpPost]
public ActionResult Index(HttpPostedFileBase file)
{
if(file != null && file.ContentLength > 0 )
try
{
string path = Path.Combine(Server.MapPath("~/Files"),
Path.GetFileName(file.FileName));
file.SaveAs(path);
ViewBag.Message = "File uploaded successfully";
}
catch(Exception ex)
{
ViewBag.Message = "ERROR:" + ex.Message.ToString();
}
else
{
ViewBag.Message = "You have not specified a file.";
}
var items = GetFiles();
return View(items);
}
public FileResult Download(string downloadedfile)
{
var FileVirtualPath = "~/Files/" + downloadedfile;
return File(FileVirtualPath, "application/force-download", Path.GetFileName(FileVirtualPath));
}
private List <string> GetFiles()
{
var dir = new System.IO.DirectoryInfo(Server.MapPath("~/Files"));
System.IO.FileInfo[] fileNames = dir.GetFiles("*.*");
List<string> items = new List<string>();
foreach (var file in fileNames)
{
items.Add(file.Name);
}
return items;
}
}
This is the view:
<h2> File Upload </h2>
#model List<string>
#using (Html.BeginForm("Index", "FileUpload", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
<label for="file"> Upload </label>
<input type="file" name="file" id="file" />
<br /><br />
<input type="submit" value="Upload" />
<br /><br />
#ViewBag.Message
<br/>
<h2>Documents list</h2>
<table style="width:100%">
<tr>
<th> File Name </th>
<th> Link </th>
</tr>
#for (var i = 0; i <= (Model.Count)-1 ; i++)
{
<tr>
<td>#Model[i].ToString() </td>
<td>#Html.ActionLink("Download", "Download", new { downloadedfile = Model[i].ToString() }) </td>
</tr>
}
</table>
}
<style>
table, th, td {
border: 1px solid white;
}
</style>

You can separate to folder, create a folder with the id of the user, and put the data in user folder.
When you gonna list, only show the folder of the user

Related

ASP.NET CORE 5 MVC How Can I Implement A Working Search Bar?

I have created a project site to which you can upload, download, delete and preview files. I want to have a search bar implemented, but being new to C# I have no idea how to link it or implement it correctly in the controller. Can anyone help me out? Thank you so much! (keep in mind I do not have a database)
<form methord="post" enctype="multipart/form-data" asp-controller="Home" asp-action="Index">
<input type="file" name="fifile" />
<input type="submit" value="Upload" />
<hr />
</form>
<table class="table">
<tr>
<th>File Name</th>
</tr>
#foreach (var item in FileClass.Filename)
{
<tr>
<td>#item.Name</td>
<td>Download</td>
#if (User.IsInRole("Admin"))
{
<td>Delete</td>
}
<td>Viewer</td>
</tr>
}
</table>
this is the razor view page, and I will also leave my controller code for the file manipulation:
FileClass fc = new FileClass();
[HttpPost]
public async Task<IActionResult> Index(IFormFile fifile)
{
string ext = Path.GetExtension(fifile.FileName);
var fisave = Path.Combine(_iweb.WebRootPath, "Uploads", fifile.FileName);
var stream = new FileStream(fisave, FileMode.Create);
await fifile.CopyToAsync(stream);
stream.Close();
return RedirectToAction("Index");
}
public IActionResult Index()
{
var displayfc = Path.Combine(_iweb.WebRootPath, "Uploads");
DirectoryInfo di = new DirectoryInfo(displayfc);
List<FileInfo> fileinfo = di.GetFiles().ToList(); ;
FileClass.Filename = fileinfo;
return View();
}
public IActionResult Delete(string filedel)
{
filedel = Path.Combine(_iweb.WebRootPath, "Uploads", filedel);
FileInfo fi = new FileInfo(filedel);
if (fi != null)
{
System.IO.File.Delete(filedel);
fi.Delete();
}
return RedirectToAction("Index");
}
public async Task<IActionResult> Download(string filename)
{
if (filename == null)
return Content("filename is not avaiable");
var path = Path.Combine(_iweb.WebRootPath, "Uploads", filename);
var memory = new MemoryStream();
using (var stream = new FileStream(path, FileMode.Open))
{
await stream.CopyToAsync(memory);
}
memory.Position = 0;
return File(memory, GetContentType(path), Path.GetFileName(path));
}
private string GetContentType(string path)
{
var types = GetMimeTypes();
var ext = Path.GetExtension(path).ToLowerInvariant();
return types[ext];
}
private Dictionary<string, string> GetMimeTypes()
{
return new Dictionary<string, string>
{
{".txt", "text/plain"},
{".pdf", "application/pdf"},
{".doc", "application/vnd.ms-word"},
{".docx", "application/vnd.ms-word"},
{".xls", "application/vnd.ms-excel"},
{".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
{".png", "image/png"},
{".jpg", "image/jpeg"},
{".jpeg", "image/jpeg"},
{".gif", "image/gif"},
{".csv", "text/csv"}
};
}
I do not know how to properly route , a sample code would be greatly appreciated, God Bless!
If you want to add search bar to the table,you only need to use js to filter the table data,here is a demo:
<form methord="post" enctype="multipart/form-data" asp-controller="Home" asp-action="Index">
<input type="file" name="fifile" />
<input type="submit" value="Upload" />
<hr />
</form>
<div>
File Name:<input id="search" />
<button onclick="search()">search</button>
</div>
<table class="table">
<tr>
<th>File Name</th>
</tr>
#foreach (var item in FileClass.Filename)
{
<tr>
<td>#item.Name</td>
<td>Download</td>
#if (User.IsInRole("Admin"))
{
<td>Delete</td>
}
<td>Viewer</td>
</tr>
}
</table>
#section scripts
{
<script>
function search() {
$("tr").each(function (index, value) {
if (index > 0 && !$(this).find("td")[0].innerText.includes($("#search").val())) {
$(this).attr("hidden", true);
} else {
$(this).removeAttr("hidden");
}
console.log(value);
})
}
</script>
}
result:

Why role.Name can get data?

I built "Role edit page" but role.Name can't get role data and It Happens NulReference eror. There is Two role in data but role.Name isn`t get them I research about that But I can't fixed this problem
what do you think about that?
Please Help me I Don't know what am I doing
Controller
public async Task<IActionResult> RoleEdit(string id)
{
var role = await _roleManager.FindByIdAsync(id);
var members = new List<User>();
var nonMembers = new List<User>();
foreach (var user in _userManager.Users.ToList())
{
var list = await _userManager.IsInRoleAsync(user, role.Name) ?
members : nonMembers;
list.Add(user);
}
var model = new RoleDetails()
{
Role = role,
Members = members,
NonMembers = nonMembers
};
return View();
}
RoleEdit View
#model RoleDetails
<div class="row">
<div class="col-md-12">
<form asp-controller="Admin" asp-action="RoleEdit">
<h6 class="bg-info text-white p-1"> Add To #Model.Role.Name</h6>
<table>
#if (Model.NonMembers.Count() == 0)
{
<tr>
<td>
Bütün istfadəçilər rola aid
</td>
</tr>
}
else
{
foreach (var user in Model.NonMembers)
{
<tr>
<td>
#user.UserName
</td>
<td>
<input type="checkbox" name="IdsToAdd" value="#user.Id" />
</td>
</tr>
}
}
</table>
<hr />
</form>
</div>
</div>
Try this:
public ActionResult Edit(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
RoleDetails roleDetails = db.RoleDetails.Find(id);
if (RoleDetails == null)
{
return HttpNotFound();
}
return View(RoleDetails);
}
I don't know what your database name is but you can change it.
If your goal is to have a crud system try this

Pass modelstate errors of Image upload to a view

I need validation for Image uploading. I have written validations using modelstate in my controller and I need to pass those validations in my view.
my view is
<div id="MemberPicture">
#using (Html.BeginForm("UpdateMemberPhotoDetails", "Member",FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<b> Pictures </b>
<table>
<tr>
<td>
<img src= "#Url.Content(Model.ImagePath)" alt="Image" width="200" height="200"/>
</td>
</tr>
<tr>
<td>
<input type="file" style="width:500px;" name="imgfile" id="file" data-val="true" data-val-required="File is required" />
</td>
</tr>
<tr>
<td><input type="submit" value="Upload" class="ButtonStyleForProfiles"/></td></tr>
</table>
}
</div>
and my control code is
public ActionResult UpdateMemberPhotoDetails( HttpPostedFileBase imgfile)
{
if (ModelState.IsValid)
{
if (imgfile == null)
{
ModelState.AddModelError("File", "Please Upload Your imgfile");
}
else if (imgfile.ContentLength > 0)
{
int MaxContentLength = 1024 * 1024; //1 MB
string[] AllowedFileExtensions = new string[] { ".jpg", ".png" };
var fileExtension = imgfile.FileName.Substring(imgfile.FileName.LastIndexOf('.'));
if (!AllowedFileExtensions.Contains(fileExtension))
{
ModelState.AddModelError("File", "Please imgfile of type: " + string.Join(", ", AllowedFileExtensions));
}
else if (imgfile.ContentLength > MaxContentLength)
{
ModelState.AddModelError("File", "Your imgfile is too large, maximum allowed size is: " + MaxContentLength + " MB");
}
else
{
var folderName = UserDetailsUtil.GetMemberPhotoPathFolderName(SessionData.UserID);
var fileName = SessionData.UserID;
var path = Path.Combine(Server.MapPath("~/Content/Upload/MemberProfilePhotos/" + folderName), fileName + fileExtension);
imgfile.SaveAs(path);
ModelState.Clear();
ViewBag.Message = "Image uploaded successfully";
}
}
}
return View();
}
How can I return modelstate errors to my view. and the viewbag message should print once the image is saved. can someone help me
after
#using (Html.BeginForm())
{
write this line:
#Html.ValidationSummary(true)
or you can do an if statement to show an error message:
#if (!ViewData.ModelState.IsValid)
{
//show error
}

How to retrieve form data and assign it to a text as a url on MVC 4

i would like to return below url from a search submit where id will be get from database.
So when a user search something by id it will search my database and display the result on my home view. then i want to transform my ID a clickable url which is this one:
http://myadress.com:8787/Handlers/DataExport.ashx?format=pdf&id=???&direction=0
Any idea how to do?
This is my home view:
<body>
<p>
#using (Html.BeginForm("Index", "Home", FormMethod.Get))
{
<b>SEARCH BY:</b> #Html.RadioButton("searchby", "ID", true) <text>ID</text>
#Html.RadioButton("searchby", "NAME") <text>NAME</text>
<br /><br />
#Html.TextBox("search") <input type="submit" value="SEARCH" />
}
</p>
<table>
<tr>
<th>
ID
</th>
<th>
NAME
</th>
<th>Actions</th>
</tr>
#if (Model.Count() == 0)
{
<tr>
<td colspan="2">NO DATA FOUND.</td>
</tr>
}
else
{
foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.ID)
</td>
<td>
#Html.DisplayFor(modelItem => item.NAME)
</td>
<td>
#Html.ActionLink("Details", "Details", new { id = item.id })
</td>
</tr>
}
}
this is my controller:
public class HomeController : Controller
{
private mydbEntities db = new mydbEntities();
//
// GET: /Home/
public ActionResult Index(string searchBy, string search)
{
if (searchBy == "ID")
{
return View(db.mytable.Where(x => x.ID == search).ToList());
}
else (searchBy == "NAME")
{
return View(db.mytable.Where(x => x.NAME == search).ToList());
}
}
You could just create an anchor tag and substitute the id in the href attribute
your link text
you have to use jquery for this. something like
$('.btnSearch').on('click', function(){
$('.lnkSubmit').attr('href', '#Url.Action("Action", "Controller", new { id = "----" })'.replace("----", (returned id here));
});
this will replace the url of a link with class lnkSubmit and will include the id that you put in it. Let me know if you have any questions.
In my Blog application, this is how I implemented search functionality for searching posts.
Partial view for search:
#using (Html.BeginForm("Search", "Blog", FormMethod.Get, new {id = "search-form"}))
{
<input type="text" name="s" placeholder="Search">
<button type="submit">Go</button>
}
Search action in controller:
public ActionResult Search(string s)
{
var model = _dbPostRepository.GetPostsForSearch(s);
ViewBag.TotalPosts = _dbPostRepository.TotalSearchPosts(s);
return View("Posts");
}
Posts View:
#model FirstBlog.Core.Post
#if (#ViewBag.TotalPosts > 0)
{
foreach (var item in Model)
{
Html.RenderPartial("_PostTemplate", item);
}
}
else
{
<p>No posts found!</p>
}
_PostTemplate is the view for each post. Hope this would help.

ASP.NET MVC 3 Logic for dynamically generated dropdown controls

I have a form that I generate dynamically, based on the amount of rows in an Excel file that I upload. Where can I add logic that looks through the Description string and sets the dynamically generated dropdownlist to a specified value, based on text in the Description?
I want to add a list of checks, such as:
if "blabla" is in the Description string, set dropdownlist value to 4.
Do I have to do this in Javascript? Cause that doesn't feel that clean to me. I'd prefer my business logic be handled in my Controller, but I'm not sure how that would go in this design.
My code looks like this:
Preview page, which basically just links to my Editor Template named Transaction:
#using (Html.BeginForm("Preview", "Import", FormMethod.Post))
{
<table border="1" style="border-color: #FFFFFF">
#Html.EditorFor(m => m.Transactions, new { Categories = Model.Categories })
</table>
<input id="btnSave" type="submit" value="Opslaan in database" />
}
In this Editor Template transaction, I display some static data, and a textbox and dropdownlist for each row in the Excel that I have previously uploaded in another page:
<tr>
<td style="width: 40px; padding: 5px; background-color: #CurrencyHelper.GetCurrencyColor(Model.Amount)" align="right" nowrap="nowrap">#Html.Raw(CurrencyHelper.GetCurrency(Model.Currency, Model.Amount))
</td>
<td style="white-space: nowrap; padding: 5px;">#Model.DateTime.ToString("dd-MM-yyyy")
</td>
<td style="padding: 5px;">#Model.Description
</td>
<td style="padding: 5px;">#Html.EditorFor(m => m.ShortDescription)
</td>
<td style="padding: 5px;">#Html.DropDownListFor(m => m.CategoryId, new SelectList(ViewData["Categories"] as IEnumerable<Category>, "CategoryId", "Name"))
</td>
</tr>
My controller, which enters the data in the View Model:
//Attach unique Transactions and Categories to ViewModel
var viewModel = new ImportViewModel()
{
Transactions = uniqueTransactions.ToList(),
Categories = categoryRepository.GetCategories().OrderBy(c => c.Name).ToList()
};
Static Binding
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Welcome to the Training Courses...";
List objcourses = new List();
objcourses.Add("Asp.Net");
objcourses.Add("MVC");
objcourses.Add("WCF");
objcourses.Add("WPF");
objcourses.Add("C#.Net");
ViewBag.Courses = new SelectList(objcourses);
return View();
}
}
#{
ViewBag.Title = "Home Page";
}
Index
#using(#Html.BeginForm(“Index”,”Home”,FormMethod.Get)) {
Courses List; #Html.DropDownList(“Courses“)
}
Dynamic Binding
public class HomeController : Controller
{
public ActionResult Index()
{
private MovieDBContext db = new MovieDBContext();
var GenreLst = new List();
var GenreQry = from d in db.Movies
orderby d.Genre
select d.Genre;
GenreLst.AddRange(GenreQry.Distinct());
ViewBag.Courses = new SelectList(GenreLst);
return View();
}
}
#{
ViewBag.Title = "Home Page";
}
Index
#using(#Html.BeginForm("Index","Home",FormMethod.Get)) {
Courses List; #Html.DropDownList("Courses")
}

Resources