Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC: Ignore field(s) when editing

As I'm in the progress of learning ASP.NET MVC, I ran into a question and into some trouble

I'm trying to create a simple blog, just to test out what I have learned so far. But when it comes to editing and leaving a field i run into a problem.

I'm trying to edit an already submitted post on my blog, the post contains few fields: Id, Headline, Message, Author and Date for the submission which should not be edited, just left as it is.

Here is some code:

My post model:

namespace MyBlock.Models
{
    public class Post
    {
        public int Id { get; set; }

        [Required]
        public string Author { get; set; }

        [Required]
        public string Headline { get; set; }

        [Required]
        public string Message { get; set; }

        public DateTime Date { get; set; }
    }
}

My edit:

[HttpGet]
public ActionResult Edit(int id = 0)
{
    Post post = db.Posts.Find(id);

    if (post != null) {
        return View(post);          
    }

    return HttpNotFound();
}

[HttpPost]
public ActionResult Edit(Post post)
{
    if (ModelState.IsValid) {
        db.Entry(post).State = EntityState.Modified;
        db.SaveChanges();

        return RedirectToAction("Index", "Home");
    }

    return View(post);
}

And my view for edit:

@model MyBlock.Models.Post

@{
    ViewBag.Title = "Edit";
}

<h2>Rediger "@Model.Headline"</h2>

@using (Html.BeginForm()) {
    @Html.LabelFor(u => u.Author)
    @Html.TextBoxFor(u => u.Author)

    @Html.LabelFor(u => u.Headline)
    @Html.TextBoxFor(u => u.Headline)

    @Html.LabelFor(u => u.Message)
    @Html.TextAreaFor(u => u.Message)

    <input type="submit" value="Gem" />
}

I know I could throw in a @HiddenFor(u => u.Date) and the same date would be submitted. But I bet there is another way than having it as a hidden field in the source code? I mean this isn't that secure in another example? So I want something else than hidden field here. Can you guys help me out?

If I try to run this as it is. I'm getting an error which is my Date isn't set, which is logic because it want to update that one aswell. But I dont want it to. I want to leave it optional if you could say that.

like image 238
aventic Avatar asked Feb 17 '23 01:02

aventic


1 Answers

Don't take candy from strangers

In other words, don't take the information from the client and directly update the DB. You should enforce your business rules on the server side and not trust the client to do it for you.

[HttpPost]
public ActionResult Edit(Post post)
{
    if (ModelState.IsValid) {
        var dbPost = db.Posts.FirstOrDefault(p => p.Id == post.Id);
        if (dbPost == null)
        {
            return HttpNotFound();
        }

        dbPost.Author = post.Author;
        dbPost.Message = post.Message;
        dbPost.Headline = post.Headline;
        db.SaveChanges();

        return RedirectToAction("Index", "Home");
    }

    return View(post);
}

[HttpPost]
public ActionResult Add(Post post)
{
    if (ModelState.IsValid) {
        var dbPost = db.Create<Post>();
        dbPost.Author = post.Author;
        dbPost.Message = post.Message;
        dbPost.Headline = post.Headline;
        dbPost.Date = DateTime.Now(); // Don't trust client to send current date
        db.SaveChanges();

        return RedirectToAction("Index", "Home");
    }

    return View(post);
}

In my own project I enforce rules like this at the domain layer by adding custom validation rules to the ValidateEntity method.

like image 94
p.s.w.g Avatar answered Feb 28 '23 01:02

p.s.w.g