Reputation: 89
I have a controller which retrieves data from a form using model binding. I need to make some edits to the model before validating, so I use TryValidateModel as the docs suggest. But for some reason "Author" is always invalid even though "user" is not null. Really confused as to what's going on here, any help would be very much appreciated.
Debugger showing a valid model:
Controller:
[Authorize]
[HttpPost]
public async Task<IActionResult> Create([Bind("Id, Title, Content")] Post post)
{
var user = await userManager.GetUserAsync(User);
post.Author = user;
post.UpvotedBy.Add(user);
if (post.Title != null && post.Content != null)
{
post.Title = post.Title.Trim();
post.Content = post.Content.Trim();
}
if (TryValidateModel(post)) // Never true
{
context.Add(post);
context.SaveChanges();
return RedirectToAction("Details", new { id = post.Id });
}
else return View(post);
}
Model:
public abstract class Entry
{
public Entry()
{
DateCreated = DateTime.Now;
Upvotes = 1;
Downvotes = 0;
VoteScore = 1;
Replies = new List<Comment>();
SavedBy = new List<ApplicationUser>();
HiddenBy = new List<ApplicationUser>();
UpvotedBy = new List<ApplicationUser>();
DownvotedBy = new List<ApplicationUser>();
}
public int Id { get; set; }
[Required, StringLength(40000)]
public string Content { get; set; }
[Required, DataType(DataType.DateTime)]
public DateTime DateCreated { get; set; }
[Required]
public int Upvotes { get; set; }
[Required]
public int Downvotes { get; set; }
[Required]
public int VoteScore { get; set; }
[Required]
public ApplicationUser Author { get; set; }
[Required]
public ICollection<Comment> Replies { get; set; }
[Required]
public ICollection<ApplicationUser> SavedBy { get; set; }
[Required]
public ICollection<ApplicationUser> HiddenBy { get; set; }
[Required]
public ICollection<ApplicationUser> UpvotedBy { get; set; }
[Required]
public ICollection<ApplicationUser> DownvotedBy { get; set; }
}
public class Post : Entry
{
[Required, StringLength(300, MinimumLength = 1)]
public string Title { get; set; }
}
Form:
@model Post
@{
ViewData["Title"] = "New post";
}
<div class="container">
<form asp-action="Create">
<div class="form-group mb-3">
<h3>Title</h3>
<input asp-for="Title" class="form-control bg-dark text-white border-secondary"
placeholder="Make it descriptive!"/>
<span asp-validation-for="Title" class="text-danger"></span>
</div>
<div class="form-group mb-3">
<h3>Content</h3>
<textarea asp-for="Content" class="form-control bg-dark text-white border-secondary"
placeholder="What do you have to say?" rows="5"></textarea>
<span asp-validation-for="Content" class="text-danger"></span>
</div>
<a href="javascript:history.go(-1)" class="btn btn-outline-danger" role="button">
<i class="fas fa-ban me-1"></i> Cancel
</a>
<button type="submit" class="btn btn-outline-primary">
<i class="fas fa-save me-1"></i> Submit
</button>
</form>
</div>
Upvotes: 4
Views: 1023
Reputation: 142253
Try clearing ModelState
before calling TryValidate
:
// your model update code
ModelState.Clear();
if (TryValidateModel(post))
{
....
}
Another option is to implement custom model binder to bind Author
via UserManager
before the validation happens.
Upvotes: 4