Hi @Amra Akmadzic,
Create.cshtml
@model VjencanjeIzSnova_WebApp.Models.Service
@{
ViewData["Title"] = "Create";
}
<h1>Create</h1>
<h4>Service</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form asp-action="Create" method="post" enctype="multipart/form-data">
@Html.AntiForgeryToken()
<div class="form-group">
<label asp-for="CategoryId" class="control-label">Category</label>
<select asp-for="CategoryId" class="form-control" asp-items="ViewBag.Category"></select>
<span asp-validation-for="CategoryId" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ContactEmail" class="control-label"></label>
<input asp-for="ContactEmail" class="form-control" />
<span asp-validation-for="ContactEmail" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="PriceRange" class="control-label"></label>
<input asp-for="PriceRange" class="form-control" />
<span asp-validation-for="PriceRange" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="CompanyInfo" class="control-label"></label>
<textarea asp-for="CompanyInfo" class="form-control"></textarea>
<span asp-validation-for="CompanyInfo" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Details" class="control-label"></label>
<div class="d-flex align-items-center">
<div id="details-container" class="flex-grow-1">
<input type="text" class="form-control" name="Details[]" />
</div>
<button type="button" id="add-new-detail" class="btn btn-secondary ml-2">+</button>
</div>
<span asp-validation-for="Details" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Name" class="control-label"></label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Description" class="control-label"></label>
<textarea asp-for="Description" class="form-control"></textarea>
<span asp-validation-for="Description" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="PartnerId" class="control-label">Partner</label>
<select asp-for="PartnerId" class="form-control" asp-items="ViewBag.Partner"></select>
<span asp-validation-for="PartnerId" class="text-danger"></span>
</div>
<div class="form-group">
<div class="d-flex align-items-center">
<label for="Images" class="mr-2">Images: </label>
<div id="image-container" class="flex-grow-1">
<input type="file" name="ImageFiles" class="form-control" multiple />
</div>
<button type="button" id="add-more-images" class="btn btn-secondary ml-2">+</button>
</div>
</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 {
<script>
document.getElementById('add-new-detail').addEventListener('click', function () {
var container = document.getElementById('details-container');
var input = document.createElement('input');
input.type = 'text';
input.className = 'form-control';
input.name = 'Details[]';
container.appendChild(input);
});
document.getElementById('add-more-images').addEventListener('click', function () {
var container = document.getElementById('image-container');
var input = document.createElement('input');
input.type = 'file';
input.name = 'ImageFiles';
input.className = 'form-control';
container.appendChild(input);
});
</script>
@{
await Html.RenderPartialAsync("_ValidationScriptsPartial");
}
}
After adding var errors = ModelState.Values.SelectMany(v => v.Errors);
like below, and I found the error message "The Partner field is required." "The Category field is required."
.
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(Service service, List<IFormFile> ImageFiles)
{
if (ModelState.IsValid)
{
// Concatenate Details inputs with semicolons
service.Details = string.Join(";", Request.Form["Details[]"]);
_context.Add(service);
await _context.SaveChangesAsync();
if (ImageFiles != null && ImageFiles.Count > 0)
{
foreach (var file in ImageFiles)
{
if (file != null && file.Length > 0)
{
var fileName = Guid.NewGuid().ToString() + Path.GetExtension(file.FileName);
string filePath = Path.Combine(_hostingEnvironment.WebRootPath, "serviceImages", fileName);
using (var stream = new FileStream(filePath, FileMode.Create))
{
await file.CopyToAsync(stream);
}
var image = new Image
{
Url = fileName,
ServiceId = service.ServiceId
};
_context.Images.Add(image);
}
}
await _context.SaveChangesAsync();
}
return RedirectToAction(nameof(Index));
}
else {
var errors = ModelState.Values.SelectMany(v => v.Errors);
}
ViewBag.Category = new SelectList(_context.Categories, "CategoryId", "Name", service.CategoryId);
ViewBag.Partner = new SelectList(_context.Partners, "PartnerId", "PartnerName", service.PartnerId);
return View(service);
}
Then I back to /Models/Service.cs
and change Partner
and Category
like below.
public virtual Category? Category { get; set; } = null!;
public virtual Partner? Partner { get; set; } = null!;
Then we can make ModelState.IsValid = true
.
If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.
Best regards,
Jason