Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TryValidateModel returning false despite a valid model

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: 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>
like image 513
chmorgan Avatar asked Sep 11 '25 16:09

chmorgan


1 Answers

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.

like image 169
Guru Stron Avatar answered Sep 14 '25 08:09

Guru Stron