HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Simple blog engine for educational purposes

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
enginesimpleeducationalforblogpurposes

Problem

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();
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 => 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 => 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 => p.Slug == post.Slug))
{
ModelState.AddModelError("", "title in use");

Solution

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 => 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();
    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 => 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);
}

Code Snippets

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 => p.Slug == post.Slug))
    {
        ModelState.AddModelError("", "title in use");
        return false;
    }

    repository.Posts.Add(post);
    repository.SaveChanges();
    return true;
}
[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<Post>();
    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 => 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);
}

Context

StackExchange Code Review Q#58137, answer score: 4

Revisions (0)

No revisions yet.