Simple blog engine for educational purposes I am coding a simple blog engine for educational purposes.

In the PostsController I have two two methods that share some common code namely, Add and Edit:

[HttpPost]
public ActionResult Add(PostInputModel model)
{
    if (!ModelState.IsValid) return View(model);

    // map the input model to an entity model using AutoMapper (extension method). 
    var post = model.MapTo&lt;Post&gt;();
    post.Summary = Summarize(post.Content);
    post.PublishedAt = DateTime.Now;
    // convert the post title to a slug (Hello World becomes hello-world for example)
    post.Slug = SlugConverter.Convert(post.Title);
    AttachTags(post);

    // check whether the slug is occupied.  
    if (repository.Posts.Any(p =&gt; p.Slug == post.Slug))
    {
        ModelState.AddModelError("", "title in use");
        return View(model);
    }

    repository.Posts.Add(post);
    repository.SaveChanges();

    // indicates that a "post published. available here." message should be displayed.
    TempData["newPost"] = true;
    // redirect the user to the edit page 
    return RedirectToAction("Edit", new { slug = post.Slug });
}

[HttpPost]
public ActionResult Edit(PostInputModel model)
{
    if (!ModelState.IsValid) return View("Edit", model);

    var post = repository.Posts.SingleOrDefault(p =&gt; p.Slug == model.Slug);
    // if the post does not exist return an error
    if (post == null) return HttpNotFound("you cannot edit a post that doesn't exist");
    repository.Posts.Remove(post);
    repository.SaveChanges();

    // map the input model to an entity model using AutoMapper (extension method).
    model.MapPropertiesToInstance(post);
    AttachTags(post);

    // convert the title to a slug (Hello World becomes hello-world for example)
    post.Slug = SlugConverter.Convert(post.Title);
    post.Summary = Summarize(post.Content);

    // check whether the slug is occupied. 
    if (repository.Posts.Any(p =&gt; p.Slug == post.Slug))
    {
        ModelState.AddModelError("", "title in use");
        return View("Edit", model);
    }

    repository.Posts.Add(post);
    repository.SaveChanges();

    return Edit(post.Slug);
}

private static string Summarize(string content)
{
    if (!content.Contains(Environment.NewLine)) return content;
    return content.Split(new[] { Environment.NewLine }, StringSplitOptions.None)[0];
}

private void AttachTags(Post post)
{
    foreach (var tag in post.Tags)
    {
        if (repository.Tags.Any(x =&gt; x.Name == tag.Name))
        {
            repository.Tags.Attach(tag);
        }
    }
}


I have cleaned the code and reduced some duplication, but I am sure this code could be improved further. How can I make this code more DRY?
The common code is about updating the post, so I'd extract this into it's own method:

private bool UpdatePost(Post post)
{
    // convert the title to a slug (Hello World becomes hello-world for example)
    post.Slug = SlugConverter.Convert(post.Title);
    post.Summary = Summarize(post.Content);

    AttachTags(post);

    // check whether the slug is occupied. 
    if (repository.Posts.Any(p =&gt; p.Slug == post.Slug))
    {
        ModelState.AddModelError("", "title in use");
        return false;
    }

    repository.Posts.Add(post);
    repository.SaveChanges();
    return true;
}


With that your Edit and Add methods can be reduced to:

[HttpPost]
public ActionResult Add(PostInputModel model)
{
    if (!ModelState.IsValid) return View(model);

    // map the input model to an entity model using AutoMapper (extension method). 
    var post = model.MapTo&lt;Post&gt;();
    post.PublishedAt = DateTime.Now;

    if (!UpdatePost(post))
    {
        return View(model);
    }

    // indicates that a "post published. available here." message should be displayed.
    TempData["newPost"] = true;
    // redirect the user to the edit page 
    return RedirectToAction("Edit", new { slug = post.Slug });
}

[HttpPost]
public ActionResult Edit(PostInputModel model)
{
    if (!ModelState.IsValid) return View("Edit", model);

    var post = repository.Posts.SingleOrDefault(p =&gt; p.Slug == model.Slug);
    // if the post does not exist return an error
    if (post == null) return HttpNotFound("you cannot edit a post that doesn't exist");
    repository.Posts.Remove(post);
    repository.SaveChanges();

    // map the input model to an entity model using AutoMapper (extension method).
    model.MapPropertiesToInstance(post);

    if (!UpdatePost(post)) 
    {
        return View(model);
    }
    return Edit(post.Slug);
}