How to post several photos and several text related to each other to the controller - asp.net-mvc

enter image description hereI want to post several photos and several texts related to each other to the controller.what should I do? My form is an Edit Form and I stored all the pictures and taxes separately. but now in Edit Form, I have to send them both together to the controller.
EditTempleViewModel
public class EditTempleViewModel
{
public string Date { get; set; }
public string Title { get; set; }
public string KeyWord { get; set; }
public int Pattern { get; set; }
public int Category { get; set; }
}
SectionViewModel
public class SectionViewModel
{
public int Id { get; set; }
public int PostId { get; set; }
public string Title { get; set; }
public List<string> Text { get; set; }
public IFormFileCollection Image { get; set; }
public string Pic { get; set; }
}
Form
#using Blogger.Models.BlogViewModels
#model EditTempleViewModel
<form id="editForm" enctype="multipart/form-data">
<div class="form-group">
<input asp-for="Title" type="text" class="form-control formClass" id="Title" placeholder="">
</div>
<div class="form-group">
<select asp-for="Category" asp-items="#ViewBag.Category" class="form-control formClass" id="Category">
<option value="" disabled selected>Select group</option>
</select>
</div>
<div class="form-group">
<label asp-for="Pattern"></label>
<select asp-for="Pattern" asp-items="#ViewBag.Pattern" class="form-control formClass ">
<option value="" disabled selected>select</option>
</select>
</div>
<div class="form-group div-textarea" id="inputTextarea">
<label asp-for="KeyWord"></label>
<textarea asp-for="KeyWord" class="form-control formClass" id="KeyWord" rows="1"></textarea>
</div>
<div id="c">
#foreach (var item in Model.sections)
{
<div class="form-group div-textarea" id="inputTextarea">
<label asp-for="#item.Text"></label>
<textarea name="Text" class="form-control formClass txtaraeClass" rows="3">#item.Text</textarea>
</div>
<div class="form-group div-img" id="inputImg">
<div class="custom-file">
<label class="custom-file-label" for="Image">Upload</label>
<input name="Image" type="file" class="custom-file-input formClass fileU" id="Image" multiple>
</div>
</div>
}
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary btnEdit">submit</button>
</div>
</form>
Script
$(".btnEdit").click(function (evt) {
evt.preventDefault();
var fileupload = $(".fileU").get();
var files = fileupload;
let myfiles = []
for (var i = 0; i < files.length; i++) {
myfiles.push(files[i]);
}
var data = new FormData();
data.append("Title", $('#Title').val());
data.append("Category", $('#Category').val());
data.append("Pattern", $('#Pattern').val());
data.append("KeyWord", $('#KeyWord').val());
data.append("files", myfiles)
let json =
{
"Title": $('#Title').val(),
"Category": $('#Category').val(),
"Pattern": $('#Pattern').val(),
"KeyWord": $('#KeyWord').val(),
files: data,
images: data
}
var frm = $('#editForm').serialize();
$.ajax({
type: "post",
url: "/Home/Uploadfilesajax",
contentType :false,
processData: false,
data: data,
success: function (message) {
alert(message);
},
error: function () {
alert("there was error uploading files!");
}
});
});
Cotroller
[HttpPost]
public async Task<IActionResult> UploadFilesAjax(EditTemple model, IFormCollection files)
{
}
I have Null data in both model and files
enter image description here

Related

Razor pages identity profile image

I am learning razor pages and followed several decent examples on Microsoft to create a very rudimentary application. I was wondering if anyone had any resources on how I could add a profile image to razor pages. I am scaffolding identity in Visual studio but nowhere can I find any tutorial on how to integrate an image.
I do have a simple model and controller that will save a file path to the DB but fail to integrate this to the razor templates.
If anyone has any resources for what I am looking to learn I would greatly appreciate it. Apologies if this is very basic, I'm probably not using the correct terminology to search in Google.
identity user in the Db.
I do have a simple model and controller that will save a file path to
the DB but fail to integrate this to the razor templates.
Model:
Let's assume you have Identity base Model as below:
public class IdentityUser
{
[Key]
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
Now you would like to add profile picture functionality there:
So you could extent your class as below:
public class IdentityExtendedModel : IdentityUser
{
public string ImageName { get; set; }
public string ProfilePictureLocation { get; set; }
}
Identity View Model:
We don't want to manipulate our identity Model directly while submitting our form inputso I will use viewModel
public class IdentityViewModel
{
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Display(Name = "Username")]
public string Username { get; set; }
[Phone]
[Display(Name = "Phone number")]
public string PhoneNumber { get; set; }
[Display(Name = "Profile Picture")]
public byte[] ProfilePicture { get; set; }
}
View Upload Profile Picture:
#model DotNet6MVCWebApp.Models.IdentityViewModel
<form asp-action="CreateIdentityProfilePic" method="post" enctype="multipart/form-data">
<div class="row">
<div class="col-md-6">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="FirstName"></label>
<input asp-for="FirstName" class="form-control" />
<span asp-validation-for="FirstName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="LastName"></label>
<input asp-for="LastName" class="form-control" />
<span asp-validation-for="LastName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Username"></label>
<input asp-for="Username" class="form-control" />
<span asp-validation-for="Username" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="PhoneNumber"></label>
<input asp-for="PhoneNumber" class="form-control" />
<span asp-validation-for="PhoneNumber" class="text-danger"></span>
</div>
<button id="update-profile-button" type="submit" class="btn btn-primary">Save</button>
</div>
<div class="col-md-6">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="ProfilePicture" style="width: 100%;"></label>
#if (Model.ProfilePicture != null)
{
<img id="profilePicture" style="width:350px;height:350px; object-fit:cover" src="data:image/*;base64,#(Convert.ToBase64String(Model.ProfilePicture))">
}
else
{
<img id="profilePicture" style="width:350px;height:350px; object-fit:cover" src="">
}
<input type="file"
accept=".png,.jpg,.jpeg,.gif,.tif"
asp-for="ProfilePicture"
class="form-control"
style="border:0px!important;padding: 0px;padding-top: 10px;padding-bottom: 30px;"
onchange="document.getElementById('profilePicture').src = window.URL.createObjectURL(this.files[0])" />
<span asp-validation-for="ProfilePicture" class="text-danger"></span>
</div>
</div>
</div>
</form>
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> CreateIdentityProfilePic(InputModel model, IFormFile profilePicture)
{
if (profilePicture == null || profilePicture.Length == 0)
{
return Content("File not selected");
}
var path = Path.Combine(_environment.WebRootPath, "ImageName/Cover", profilePicture.FileName);
using (FileStream stream = new FileStream(path, FileMode.Create))
{
await profilePicture.CopyToAsync(stream);
stream.Close();
}
if (model == null)
{
return Content("Invalid Submission!");
}
var identityModel = new IdentityModel
{
FirstName = model.FirstName,
LastName = model.LastName,
Username = model.Username,
PhoneNumber = model.PhoneNumber,
ImageName = profilePicture.FileName,
ProfilePictureLocation = path,
};
_context.Add(identityModel);
await _context.SaveChangesAsync();
return RedirectToAction("IdentityProfilePicList");
}
Note: When you would submit Upload profile Picture view this controller should receive the request.
Controller Profile Picture List:
public ActionResult IdentityProfilePicList()
{
var memberList = _context.identityModels.ToList();
return View(memberList);
}
View Profile Picure List:
#model IEnumerable<DotNet6MVCWebApp.Models.IdentityExtendedModel>
#{
ViewData["Title"] = "Index";
}
<div class="form-row">
<table>
<tr>
<td>
<a asp-action="Index" class="btn btn-success">Create New</a>
</td>
<form method="get" action="#">
<td style="padding-right:760px">
</td>
<td>
<input class="form-control" type="text" placeholder="Search for..." name="SearchString" value="#ViewData["CurrentFilter"]" aria-label="Search" aria-describedby="btnNavbarSearch" />
</td>
<td>
<input type="submit" value="Search" class="btn btn-primary" />
</td>
</form>
</tr>
</table>
</div>
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.FirstName)
</th>
<th>
#Html.DisplayNameFor(model => model.LastName)
</th>
<th>
#Html.DisplayNameFor(model => model.Username)
</th>
<th>
#Html.DisplayNameFor(model => model.ProfilePictureLocation)
</th>
<th>
Member Details
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Username)
</td>
<td>
<img src="~/ImageName/Cover/#item.ImageName"
class="rounded-square"
height="50" width="75"
style="border:1px"
asp-append-version="true" accept="image/*" />
</td>
<td>
<a asp-action="EditMember" class="btn btn-primary" asp-route-memberId="#item.Id">Details</a> | <a asp-action="EditMember" class="btn btn-warning" asp-route-memberId="#item.Id">Edit</a>
</td>
</tr>
}
</tbody>
</table>
Output:
Database:
Note: If you need any further assistance on this please check this GitHub repository.
Thanks for all the help it helped me massively to resolve the issue. At the end of registering the image in the scaffolded razor pages Identity I had to use the code behind file register.cshtl.cs and add it to the Input module there and be consumed by the register.cshtml which now works perfectly.
I hope this helps someone else.
First I extended the ApplicationUser and added the migration.
public class ApplicationUser : IdentityUser
{
[Required]
public string Name { get; set; }
public string? StreetAddress { get; set; }
public string? City { get; set; }
public string? PostalCode { get; set; }
[ValidateNever]
public string? ImageUrl { get; set; }
public int? CompanyId { get; set; }
[ForeignKey("CompanyId")]
[ValidateNever]
public Company Company { get; set; }
}
Then added to the Input model in the Register.cshtml.cs
public class InputModel
{
/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
/// <summary>
/// This API supports the ASP.NET Core Identity default UI infrastructure and is not intended to be used
/// directly from your code. This API may change or be removed in future releases.
/// </summary>
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
//Added custom fields
[Required]
public string Name { get; set; }
public string? StreetAddress { get; set; }
public string? City { get; set; }
public string? PostalCode { get; set; }
public string? PhoneNumber { get; set; }
[ValidateNever]
public string? ImageUrl { get; set; }
public string? Role { get; set; }
public int? CompanyId { get; set; }
[ValidateNever]
public IEnumerable<SelectListItem> RoleList { get; set; }
[ValidateNever]
public IEnumerable<SelectListItem> CompanyList { get; set; }
}`
Then in the on Post method add the file path to the database.
public async Task<IActionResult> OnPostAsync(IFormFile file, string returnUrl = null)
{
returnUrl ??= Url.Content("~/");
ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList();
if (ModelState.IsValid)
{
var user = CreateUser();
string wwwRootPath = _hostEnvironment.WebRootPath;
if (file != null)
{
string fileName = Guid.NewGuid().ToString();
var uploads = Path.Combine(wwwRootPath, #"images\companies");
var extension = Path.GetExtension(file.FileName);
if (Input.ImageUrl != null)
{
var oldImagePath = Path.Combine(wwwRootPath, Input.ImageUrl.TrimStart('\\'));
}
using (var fileStreams = new FileStream(Path.Combine(uploads, fileName + extension), FileMode.Create))
{
file.CopyTo(fileStreams);
}
Input.ImageUrl = #"\images\companies\" + fileName + extension;
}
else
{
Input.ImageUrl = #"\images\companies\QPQ-logo.jpg";
}
await _userStore.SetUserNameAsync(user, Input.Email, CancellationToken.None);
await _emailStore.SetEmailAsync(user, Input.Email, CancellationToken.None);
user.Name = Input.Name;
user.StreetAddress = Input.StreetAddress;
user.City = Input.City;
user.PostalCode = Input.PostalCode;
user.PhoneNumber = Input.PhoneNumber;
user.ImageUrl = Input.ImageUrl;
var result = await _userManager.CreateAsync(user, Input.Password);
if (result.Succeeded)
{
_logger.LogInformation("User created a new account with password.");
if (Input.Role == null)
{
await _userManager.AddToRoleAsync(user, SD.Role_User_Indi);
}
else
{
await _userManager.AddToRoleAsync(user, Input.Role);
}
var userId = await _userManager.GetUserIdAsync(user);
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code));
var callbackUrl = Url.Page(
"/Account/ConfirmEmail",
pageHandler: null,
values: new { area = "Identity", userId = userId, code = code, returnUrl = returnUrl },
protocol: Request.Scheme);
await _emailSender.SendEmailAsync(Input.Email, "Confirm your email",
$"Please confirm your account by <a href='{HtmlEncoder.Default.Encode(callbackUrl)}'>clicking here</a>.");
if (_userManager.Options.SignIn.RequireConfirmedAccount)
{
return RedirectToPage("RegisterConfirmation", new { email = Input.Email, returnUrl = returnUrl });
}
else
{
await _signInManager.SignInAsync(user, isPersistent: false);
return LocalRedirect(returnUrl);
}
}
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
// If we got this far, something failed, redisplay form
return Page();
}`
One of the first mistakes I made was not declaring the front-end form as a multipart form in the Register.cshtml.
<h1>#ViewData["Title"]</h1><div class="row pt-4">
<div class="col-md-8">
<form id="registerForm" class="row" asp-route-returnUrl="#Model.ReturnUrl" method="post" enctype="multipart/form-data">
<h2>Create a new account.</h2>
<hr />
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-floating py-2 col-12">
<input asp-for="Input.Email" class="form-control" aria-required="true" />
<label asp-for="Input.Email"></label>
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
<div class="form-floating py-2 col-6">
<input asp-for="Input.Name" class="form-control" aria-required="true" />
<label asp-for="Input.Name"></label>
<span asp-validation-for="Input.Name" class="text-danger"></span>
</div>
<div class="form-floating py-2 col-6">
<input asp-for="Input.StreetAddress" class="form-control" />
<label asp-for="Input.StreetAddress"></label>
<span asp-validation-for="Input.StreetAddress" class="text-danger"></span>
</div>
<div class="form-floating py-2 col-6">
<input asp-for="Input.City" class="form-control" />
<label asp-for="Input.City"></label>
<span asp-validation-for="Input.City" class="text-danger"></span>
</div>
<div class="form-floating py-2 col-6">
<input asp-for="Input.PostalCode" class="form-control" />
<label asp-for="Input.PostalCode"></label>
<span asp-validation-for="Input.PostalCode" class="text-danger"></span>
</div>
<div class="form-floating py-2 col-6">
<input asp-for="Input.Password" class="form-control" aria-required="true" />
<label asp-for="Input.Password"></label>
<span asp-validation-for="Input.Password" class="text-danger"></span>
</div>
<div class="form-floating py-2 col-6">
<input asp-for="Input.ConfirmPassword" class="form-control" aria-required="true" />
<label asp-for="Input.ConfirmPassword"></label>
<span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
</div>
<div class="form-floating py-2 col-6">
<select asp-for="Input.Role" asp-items="#Model.Input.RoleList" class=form-select>
<option disabled selected>-Select Role-</option>
</select>
</div>
<div class="form-floating py-2 col-6">
<select asp-for="Input.CompanyId" asp-items="#Model.Input.CompanyList" class=form-select>
<option disabled selected>-Select Company-</option>
</select>
</div>
<div class="form-floating py-2 col-12">
<label asp-for="Input.ImageUrl"></label>
<input asp-for="Input.ImageUrl" type="file" id="uploadBox" name="file" class="form-control" />
</div>
<button id="registerSubmit" type="submit" class="w-100 btn btn-lg btn-primary">Register</button>
</form>
</div>
<div class="col-md-4">
<section>
<h3>Use another service to register.</h3>
<hr />
#{
if ((Model.ExternalLogins?.Count ?? 0) == 0)
{
<div>
<p>
There are no external authentication services configured. See this <a href="https://go.microsoft.com/fwlink/?LinkID=532715">article
about setting up this ASP.NET application to support logging in via external services</a>.
</p>
</div>
}
else
{
<form id="external-account" asp-page="./ExternalLogin" asp-route-returnUrl="#Model.ReturnUrl" method="post" class="form-horizontal">
<div>
<p>
#foreach (var provider in Model.ExternalLogins)
{
<button type="submit" class="btn btn-primary" name="provider" value="#provider.Name" title="Log in using your #provider.DisplayName account">#provider.DisplayName</button>
}
</p>
</div>
</form>
}
}
</section>
</div>

how can i show the data that the user entered in the file input when he want to edit it

for your information the file is saved as a binary data
here is is the model:
public class Movie
{
[Key]
public int MovieId { get; set; }
public string MovieName { get; set; }
public string MovieDescription { get; set; }
public byte[] MovieImage { get; set; }
public string MovieTrailer { get; set; }
//FK
public int AdminId { get; set; }
//Navigation
public Admin Admin { get; set; }
public ICollection<Event> Events { get; set; }
public AddingCategory AddingCategory { get; set; }
public ViewingMovie ViewingMovie { get; set; }
}
}
And here is the controller :
public async Task<IActionResult> Edit(int? id)
{
if (id == null)
{
return NotFound();
}
var movie = await _context.tblMovies.FindAsync(id);
if (movie == null)
{
return NotFound();
}
ViewData["AdminId"] = new SelectList(_context.Set<Admin>(), "AdminId", "Email", selectedValue: movie.AdminId);
return View(movie);
}
// POST: Movies/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("MovieId,MovieName,MovieDescription,MovieImage,MovieTrailer,AdminId")] Movie movie, IFormFile MovieImage)
{
if (id != movie.MovieId)
{
return NotFound();
}
if (MovieImage != null)
{
//This code is used to copy image to DataBase
using (var myStream = new MemoryStream())
{
await MovieImage.CopyToAsync(myStream);
movie.MovieImage = myStream.ToArray();
}
}
if (ModelState.IsValid)
{
try
{
_context.Update(movie);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!MovieExists(movie.MovieId))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index));
}
ViewData["AdminId"] = new SelectList(_context.Set<Admin>(), "AdminId", "Email", movie.AdminId);
return View(movie);
}
and the last here is the edit view:
<div class="row">
<div class="col-md-4">
<form asp-action="Edit" method="post" enctype="multipart/form-data">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="MovieId" />
<div class="form-group">
<label asp-for="MovieName" class="control-label"></label>
<input asp-for="MovieName" class="form-control" />
<span asp-validation-for="MovieName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="MovieDescription" class="control-label"></label>
<input asp-for="MovieDescription" class="form-control" />
<span asp-validation-for="MovieDescription" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="MovieImage" class="control-label"></label>
<input asp-for="MovieImage" class="form-control" type="file" />
<span asp-validation-for="MovieImage" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="MovieTrailer" class="control-label"></label>
<input asp-for="MovieTrailer" class="form-control" />
<span asp-validation-for="MovieTrailer" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="AdminId" class="control-label"></label>
<select asp-for="AdminId" class="form-control" asp-items="ViewBag.AdminId"></select>
<span asp-validation-for="AdminId" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary" />
</div>
</form>
</div>
all i want is to show what the user entered in the file input and if he want to edit it or keep as it is.
i have been struggling with this problem in days PLEASE somebody help me out

How do I upload pdf into a folder and store the path into a database, and be able to view the uploaded file? Thank you

Here is my controller code
namespace MyClassWorkApplication.Areas.Admin.Controllers
{
[Area("Admin")]
[Authorize(Roles = "Admin")]
public class ContentController : Controller
{
private readonly ApplicationDbContext _context;
private IWebHostEnvironment _env;
public ContentController(ApplicationDbContext context, IWebHostEnvironment env)
{
_context = context;
_env = env;
}
// GET: Admin/Content/Create
public IActionResult Create(int categoryItemId, int categoryId)
{
Content content = new Content
{
CategoryId = categoryId,
CatItemId = categoryItemId
};
return View(content);
}
// POST: Admin/Content/Create
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Title,HTMLContent,VideoLink,CatItemId,CategoryId,PublicationPdfUrl")] Content content)
{
Profile profile = new Profile();
profile.Title = content.Title;
//loading remaining properties of the model from ViewModel
//uploading file....
string uniqueFileName = null;
if (content.PublicationPdfUrl != null)
{
string folder = "Publications/pdf/";
string serverFolder = Path.Combine(_env.WebRootPath, folder);
uniqueFileName = Guid.NewGuid().ToString() + "_" + content.PublicationPdfUrl.FileName;
string filePath = Path.Combine(serverFolder, uniqueFileName);
content.PublicationPdfUrl.CopyTo(new FileStream(filePath, FileMode.Create));
profile.PublicationPdfUrl = content.PublicationPdfUrl.FileName;
}
if (ModelState.IsValid)
{
content.CategoryItem = await _context.CategoryItem.FindAsync(content.CatItemId);
_context.Add(content);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index), "CategoryItem", new { categoryId = content.CategoryId });
}
return View(content);
}
// GET: Admin/Content/Edit/5
public async Task<IActionResult> Edit(int categoryItemId, int categoryId)
{
if (categoryItemId == 0)
{
return NotFound();
}
var content = await _context.Content.SingleOrDefaultAsync(item => item.CategoryItem.Id == categoryItemId);
content.CategoryId = categoryId;
if (content == null)
{
return NotFound();
}
return View(content);
}
// POST: Admin/Content/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Title,HTMLContent,VideoLink,CategoryId,PublicationPdfUrl")] Content content)
{
if (id != content.Id)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(content);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!ContentExists(content.Id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction(nameof(Index), "CategoryItem", new { categoryId = content.CategoryId });
}
return View(content);
}
private bool ContentExists(int id)
{
return _context.Content.Any(e => e.Id == id);
}
}
}
My Second Controller
namespace MyClassWorkApplication.Controllers
{
public class ContentController : Controller
{
private readonly ApplicationDbContext _context;
public ContentController(ApplicationDbContext context)
{
_context = context;
}
public async Task<IActionResult> Index(int categoryItemId)
{
Content content = await (from item in _context.Content
where item.CategoryItem.Id == categoryItemId
select new Content
{
Title = item.Title,
VideoLink = item.VideoLink,
HTMLContent = item.HTMLContent,
PublicationPdfUrl = item.PublicationPdfUrl
}).FirstOrDefaultAsync();
return View(content);
}
}
}
This is my Model class (Content). It was reporting error with the IFormFile until I added the [NotMapped] attributes to it before the error disappears. However, It does not add the pdf Url into that database as I wanted.
public class Content
{
public int Id { get; set; }
[Required]
[StringLength(200, MinimumLength = 2)]
public string Title { get; set; }
[Display(Name = "HTML Content")]
public string HTMLContent { get; set; }
[Display(Name = "Video Link")]
public string VideoLink { get; set; }
public CategoryItem CategoryItem { get; set; }
[NotMapped]
public int CatItemId { get; set; }
//Note: This property cannot be
//named CategoryItemId because this would
//interfere with future migrations
//It has been named like this
//so as not to conflict with EF Core naming conventions
[NotMapped]
public int CategoryId { get; set; }
[NotMapped]
public IFormFile PublicationPdfUrl { get; set; }
}
public class Profile
{
[Key]
public int Id { get; set; }
public string Title { get; set; }
public string HTMLContent { get; set; }
public string VideoLink { get; set; }
public CategoryItem CategoryItem { get; set; }
public int CatItemId { get; set; }
public int CategoryId { get; set; }
[Display(Name = "Upload your publication in pdf format")]
public string PublicationPdfUrl { get; set; }
}
}
This is my Create View
#{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>Content</h4>
<hr />
<div class="row">
<div class="col-md-10">
<form method="post" enctype="multipart/form-data" asp-action="Create">
<input type="hidden" asp-for="CategoryId">
<input type="hidden" asp-for="CatItemId">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="HTMLContent" class="control-label"></label>
<textarea asp-for="HTMLContent" row="10" class="form-control"></textarea>
<span asp-validation-for="HTMLContent" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="VideoLink" class="control-label"></label>
<input asp-for="VideoLink" class="form-control" />
<span asp-validation-for="VideoLink" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="PublicationPdfUrl" class="control-label"></label>
<div class="custom-file">
<input asp-for="PublicationPdfUrl" class="custom-file-input" id="customFile">
<label class="custom-file-label" for="customFile">Choose file...</label>
</div>
<span asp-validation-for="PublicationPdfUrl" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary float-right" />
<a asp-controller="CategoryItem" asp-action="Index" asp-route-categoryId="#Model.CategoryId" class="btn btn-outline-primary">Back to List</a>
</div>
</form>
</div>
</div>
This is my Edit View
#{
ViewData["Title"] = "Edit";
}
<h4>Edit</h4>
<h4>Content</h4>
<hr />
<div class="row">
<div class="col-md-10">
<form method="post" enctype="multipart/form-data" asp-action="Edit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="Id" />
<input type="hidden" asp-for="CategoryId" />
<div class="form-group">
<label asp-for="Title" class="control-label"></label>
<input asp-for="Title" class="form-control" />
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="HTMLContent" class="control-label"></label>
<textarea asp-for="HTMLContent" row="10" class="form-control"></textarea>
<span asp-validation-for="HTMLContent" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="VideoLink" class="control-label"></label>
<input asp-for="VideoLink" class="form-control" />
<span asp-validation-for="VideoLink" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="PublicationPdfUrl" class="control-label"></label>
<div class="custom-file">
<input asp-for="PublicationPdfUrl" class="custom-file-input" id="customFile">
<label class="custom-file-label" for="customFile">Choose file...</label>
</div>
<span asp-validation-for="PublicationPdfUrl" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Save" class="btn btn-primary float-right" />
<a asp-controller="CategoryItem" asp-action="Index" asp-route-categoryId="#Model.CategoryId" class="btn btn-outline-primary">Back to List</a>
</div>
</form>
</div>
</div>

MVC Url.Action causes NullReferenceException in post

I'm trying to have a button on my form page that takes me back to the previous view that requires a parameter, I'm passing a ViewModel into the view with the assigned value I'm using. If the button is un-commented the button works fine but the forms post sends a NullReferenceException, and if the button is commented the form works exactly as I want.
The button that breaks the form
<button type="button" onclick="location.href='#Url.Action("Assignments","Session", new { Model.CourseName })'">Go Back</button>
The Controller Code
public IActionResult CreateAssignment(string courseName)
{
CreateAssignmentModel assignmentModel = new CreateAssignmentModel();
assignmentModel.CourseName = courseName;
return View(assignmentModel);
}
[HttpPost]
public IActionResult CreateAssignment(CreateAssignmentModel assignment)
{
if (ModelState.IsValid)
{
ModelState.Clear();
return View(assignment.CourseName);
}
else
{
return View(assignment.CourseName);
}
}
public IActionResult Assignments(string courseName)
{
var assignments = storedProcedure.getAssignments(User.Identity.Name, courseName);
var AssignmentsView = new AssignmentsViewModel{CourseName = courseName};
foreach (var Assignment in assignments.ToList())
{
AssignmentsView.Assignments.Add(Assignment);
}
return View(AssignmentsView);
}
The Model Code
public class CreateAssignmentModel
{
public string UserName { get; set; }
public string CourseName { get; set; }
[Required]
public string AssignmentName { get; set; }
[Required]
public string AssignmentDescription { get; set; }
[Required]
public int TotalPoints { get; set; }
[Required]
public DateTime DueDate { get; set; }
}
The Form with Button
<button type="button" onclick="location.href='#Url.Action("Assignments","Session", new { Model.CourseName })'">Go Back</button>
<div class="row">
<div class="col-md-4">
<form asp-route-returnUrl="#ViewData["ReturnUrl"]" method="post">
<h4>Create an Assignment</h4>
<hr />
<div class="form-group">
<label asp-for="AssignmentName" class="control-label">Assignment Name</label>
<input asp-for="AssignmentName" class="form-control" placeholder="Assignment Name" />
<span asp-validation-for="AssignmentName" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="AssignmentDescription" class=" control-label">Assignment Description</label>
<input asp-for="AssignmentDescription" class="form-control" placeholder="Assignment Description" />
<span asp-validation-for="AssignmentDescription" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="TotalPoints" class=" control-label">Total Points</label>
<input asp-for="TotalPoints" class="form-control" placeholder="Points" />
<span asp-validation-for="TotalPoints" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="DueDate" class=" control-label">Due Date</label>
<input asp-for="DueDate" class="form-control" placeholder="Due Date" />
<span asp-validation-for="DueDate" class="text-danger"></span>
</div>
<br />
<button type="submit" class="btn btn-primary">Create</button>
</form>
</div>
</div>
Sorry for the lack of brevity, I've looked at NullReferenceException solutions for my problem but none have worked.

mvc getting and sending data from dropdown and datetimepicker

hello everyone I have a question. I have a form which consist of dropdown textbox and datetimepicker. I can fill my dropdown from my model but I cannot post the data to the database. Here are my codes
My Controller codes this is where the data selected and shown in view
public ActionResult orderProduct()
{
Repository<OrderProduct> _ro = new Repository<OrderProduct>();
IEnumerable<OrderProduct> _orderProduct = _ro.All().OrderByDescending(o => o.id);
return View(_orderProduct);
}
I am filling the dropdownlist from database
public ActionResult addOrderProduct()
{
/*
Repository<Workshop> _rw = new Repository<Workshop>();
IEnumerable<Workshop> _workshop = _rw.All().OrderByDescending(o => o.id);
IEnumerable<SelectListItem> _selectList = from w in _workshop
select new SelectListItem {
Text = w.name,
Value = w.id.ToString()
};
*/
Repository<Workshop> _rw = new Repository<Workshop>();
IEnumerable<SelectListItem> _workshopSelectListItem = _rw.All().AsEnumerable().Select(s =>
new SelectListItem {
Text = s.name, Value=s.id.ToString()
});
ViewData["dropdown"] = _workshopSelectListItem;
return View();
}
here I am trying to post my data to the database. I cannot select data from dropdown and datetimepicker also I cannot post this data by writing manually.
public ActionResult orderProductAdd(int adet, float cmt)
{
Repository<OrderProduct> _rp = new Repository<OrderProduct>();
OrderProduct _orderProduct = new OrderProduct { workshopId = 1, orderId = 1, value = adet, shipDate = new DateTime(2005, 02, 01), cmt = cmt };
return RedirectToAction("orderProduct");
}
this is my model
[Table("OrderProduct")]
public class OrderProduct
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int id { get; set; }
public int orderId { get; set; }
[ForeignKey("orderId")]
public virtual Order order { get; set; }
public int workshopId { get; set; }
[ForeignKey("workshopId")]
public virtual Workshop workshop { get; set; }
public int value { get; set; }
public float cmt { get; set; }
public DateTime shipDate { get; set; }
/*
[id]
,[orderId]
,[workshopId]
,[value]
,[cmt]
,[shipDate]
*/
}
and also this is my view "addOrderProduct"
<form action="/Order/orderProductAdd" class="form-horizontal">
<div class="control-group">
<label class="control-label">Atölye Seçiniz</label>
<div class="controls">
#Html.DropDownList("dropdown",(IEnumerable<SelectListItem>)ViewData["dropdown"],"secim yapınız", new { #class = "span6 chosen" })
#*<select class="span6 chosen" data-placeholder="Choose a Category" tabindex="1">
<option value=""></option>
<option value="Category 1">A1</option>
<option value="Category 2">A2</option>
<option value="Category 3">A3</option>
<option value="Category 4">A4</option>
</select>*#
</div>
</div>
<div class="control-group">
<label class="control-label">Adet Giriniz</label>
<div class="controls">
<input type="text" class="span6 " name="adet" />
<span class="help-inline">Sadece sayı giriniz</span>
</div>
</div>
<div class="control-group last">
<label class="control-label">İhracat Tarihi</label>
<div class="controls">
<div id="ui_date_picker_inline"></div>
</div>
</div>
<div class="control-group">
<label class="control-label">Cmt</label>
<div class="controls">
<input type="text" class="span6 " name="cmt" />
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-success">Onayla</button>
#*<button type="button" class="btn">Cancel</button>*#
</div>
</form>
How can I solve this ? Thank you.
The first argument in the DDL (below) is the assigned parameter being passed back to the server. When you call the action you're not passing the parameter dropdown. You're only calling int adet, float cmt but not a parameter called dropdown
#Html.DropDownList("dropdown",(IEnumerable<SelectListItem>)ViewData["dropdown"],
"secim yapınız", new { #class = "span6 chosen" })
So update your code to something like the one below:
public ActionResult orderProductAdd(int adet, float cmt, string dropdown){
// DO SOMETHING HERE
}
I can't see the input control which is being constructed for the DATETIME part of your query, however it will be similar to the above. Ensure the name of the INPUT matches the parameters being passed back to the server.

Resources