1 of 2

Let's see what's going on here:

var posts = repository.All();

So posts is all posts that exist in the database. If it's an IEnumerable<Post> you've probably already hit the database and returned all posts; if it's an IQueryable<Post> then the query probably gets materialized in the Paginate method. I'm not a fan of leaking IQueryable<T> outside of a repository, but it's not the repository that's up for review.

var page = posts.Paginate(pageNumber, PageSize);

If I get this right, then Paginate is an extension method, either on IEnumerable<T> or IQueryable<T> - strike 1, page is a collection of posts; the name is misleading. Rename it to something more meaningful, like pagePosts.

Which gets us to this line:

if (page.Count == 0 && pageNumber != 1)

You're calling .Count, which at this point is a surprise: it looks like page is actually a IList<Post> - but you don't want a list here: an IEnumerable<T> would suffice. Yep, that's strike 2.

I presume your repository does something like this:

var result = _context.Posts.ToList();

When you do that, result will be a List<Post> indeed. That doesn't mean it has to be exposed through its IList<T> interface: result could just as well be exposed as an IEnumerable<T> - the fact that it's really a List<T> is a mere implementation detail that your controller doesn't need to care about. All the controller needs to know, is that posts can be enumerated.

This means the condition would look like this - notice Count() being a method:

if (page.Count() == 0 && pageNumber != 1)

And this is a problem. You don't want to iterate the whole page just to know whether there's at least one item. LINQ has a pretty way of doing this:

if (!page.Any() && pageNumber != 1)

Any() will return as soon as it finds an item - without iterating the whole thing. And that's more efficient.

Then pageNumber needs to be one. This is where having page named pagePosts pays off - it would be much clearer that page contains the posts for the requested page number.

Now the condition is still backwards: "page does not contain any posts and page number is not one".

The inverse condition would be "page contains at least one post, or page number is one".

That would make it look like this:

if (pagePosts.Any() || pageNumber == 1)
{
    return View(pagePosts);
}
else
{
    return RedirectToAction("Index", new { pageNumber = pagePosts.TotalPageCount });
}

The only thing that's bothering me, is that with .TotalPageCount, I'm not sure anymore - is that another extension method on IEnumerable<Post>/IQueryable<Post>, or pagePosts is a completely different type? What type is it anyway?

I'm a HUGE fan of var. But in this case, it's making things much harder than they need to be, because it's far from obvious what types are being involved here. And that's strike 3.