I am trying to create a form in my actors page. Upon clicking the submit button, fields are validated and it should in theory submit, but it is not. I have tried renaming, creating a new function that intellisense suggests and my only ways of making this form to submit is either manually making the function go to _service.Add(actor); or by not going with the validation, but then if one of the required fields is not met, it throws an error in a different page, which is not ideal. I have no clue how to make this work, because the course, that I am recreating it from is able to do it just fine.
My code - controller:
namespace Cinema_World.Controllers
{
public class ActorsController : Controller
{
private readonly IActorsService _service;
public ActorsController(IActorsService service)
{
_service = service;
}
public async Task<IActionResult> Index()
{
var allActors = await _service.GetAll();
return View(allActors);
}
public async Task<IActionResult> Create()
{
return View();
}
[HttpPost]
public async Task<IActionResult> Create([Bind("FirstName,MiddleName,LastName,BirthYear,BirthPlace")] ActorModel actor)
{
if (!ModelState.IsValid) //when i use break-points, this part gets stepped into
{// also this part
return View(actor); //this part too
} // and this is the final part, then it skips to the end and nothing happens in the browser
_service.Add(actor);
return RedirectToAction(nameof(Index));
}
}
}
My models:
namespace Cinema_World.Models
{
public class ActorModel
{
[Key]
public int ActorID { get; set; }
[Display(Name = "First name")]
[Required(ErrorMessage = "First name is a required field")]
[StringLength(100, MinimumLength = 1, ErrorMessage = "First name can be between 1 and 100 characters long!")]
public string FirstName { get; set; }
[Display(Name = "Middle name")]
[StringLength(100, MinimumLength = 1, ErrorMessage = "Middle name can be between 1 and 100 characters long!")]
public string? MiddleName { get; set; }
[Display(Name = "Last name")]
[Required(ErrorMessage = "Last name is a required field")]
[StringLength(100, MinimumLength = 1, ErrorMessage = "Last name can be between 1 and 100 characters long!")]
public string LastName { get; set; }
[Display(Name = "Year of Birth")]
[Required(ErrorMessage = "Year of birth is a required field")]
[Range(999,9999, ErrorMessage = "Input a year between 999 and 9999")]
public int BirthYear { get; set; }
[Display(Name = "Place of Birth")]
[Required(ErrorMessage = "Place of birth is a required field")]
[StringLength(100, MinimumLength = 1, ErrorMessage = "Name of the place can be between 1 and 100 characters long!")]
public string BirthPlace { get; set; }
public List<Actor_CinematographyModel> Actors_Cinematography { get; set; }
}
}
Code from my service that gets called, when form submit is successful.
namespace Cinema_World.Data.Services
{
public class ActorsService : IActorsService
{
private readonly ApplicationDbContext _context;
public ActorsService(ApplicationDbContext context)
{
_context = context;
}
public void Add(ActorModel Actor)
{
_context.Actors.Add(Actor);
_context.SaveChanges();
}
public void Delete(int ActorID)
{
throw new NotImplementedException();
}
public async Task<IEnumerable<ActorModel>> GetAll()
{
var result = await _context.Actors.ToListAsync();
return result;
}
public ActorModel GetById(int ActorID)
{
throw new NotImplementedException();
}
public ActorModel Update(int ActorID, ActorModel newActor)
{
throw new NotImplementedException();
}
}
}
Interface for this specific service:
namespace Cinema_World.Data.Services
{
public interface IActorsService
{
Task<IEnumerable<ActorModel>> GetAll();
ActorModel GetById(int ActorID);
void Add(ActorModel Actor);
ActorModel Update(int ActorID, ActorModel newActor);
void Delete(int ActorID);
}
}
View markup:
<div >
<div >
<p>
<h1>Add a new Actor!</h1>
</p>
<div >
<div >
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" ></div>
<div >
<label asp-for="FirstName" ></label>
<input asp-for="FirstName" />
<span asp-validation-for="FirstName" ></span>
</div>
<div >
<label asp-for="MiddleName" ></label>
<input asp-for="MiddleName" />
<span asp-validation-for="MiddleName" ></span>
</div>
<div >
<label asp-for="LastName" ></label>
<input asp-for="LastName" />
<span asp-validation-for="LastName" ></span>
</div>
<div >
<label asp-for="BirthYear" ></label>
<input asp-for="BirthYear" />
<span asp-validation-for="BirthYear" ></span>
</div>
<div >
<label asp-for="BirthPlace" ></label>
<input asp-for="BirthPlace" />
<span asp-validation-for="BirthPlace" ></span>
</div>
<div >
<input type="submit" value="Create" />
<a asp-action="Index">Show all</a>
</div>
</form>
</div>
</div>
</div>
</div>
If anything else is required, please, let me know. I have been stuck hard on this for a while already, and if I am not able to fix this, I cannot progress with my other forms.
Like I said before, I tried replacing the !ModelState.IsValid
with ModelState.IsValid
and putting the executing code in there, intellisense suggestions and even manually, using break-points and I did manage to get it to work like that, but is not an ideal choice.
My knowledge in ASP.NET MVC is basic, so perhaps I messed up something or missed something.
Just for clarification - the called service works, i am able to post data, but if validation is present in the same method, i am unable to post anything and the button does not do anything.
CodePudding user response:
Turns out, the problem was not in the method, but the model.
public List<Actor_CinematographyModel> Actors_Cinematography { get; set; }
was somehow conflicting and not allowing me to post data. after making it possible to be a null value, everything works. not sure, why it did it, maybe i set up my database tables wrong. this thread is no longer in question :)