diff --git a/Lib/Portoa.Web.dll b/Lib/Portoa.Web.dll
index 029d8be..a9d8e38 100644
Binary files a/Lib/Portoa.Web.dll and b/Lib/Portoa.Web.dll differ
diff --git a/Lib/Portoa.Web.xml b/Lib/Portoa.Web.xml
index 37ee86e..0394886 100644
--- a/Lib/Portoa.Web.xml
+++ b/Lib/Portoa.Web.xml
@@ -11,6 +11,18 @@
+
+
+ Enables you to dynamically add filters to a ControllerActionInvoker. This class will also
+ perform injection on all filters that are annotated with NeedsBuildUpAttribute.
+
+ Adapted from http://blog.ploeh.dk/2009/12/01/GlobalErrorHandlingInASPNETMVC.aspx
+
+
+
+ Overridden to add the new filters to the default filters
+
+
Signifies that this controller can handle errors that aren't handled by
@@ -32,6 +44,18 @@
Executed when the user is forbidden from seeing the requested page
+
+
+ whose lifetime lasts as long as the HTTP request.
+ The object is stored in HttpContext.Current.Items, keyed by a .
+
+
+
+
+ Matching rule that matches when a method is annotated with an attribute
+
+ The attribute to match against
+
Model binder that uses an IUnityContainer to resolve the model binder designated by
@@ -54,6 +78,11 @@
The service provider to use to resolve the model binder
+
+
+ Controller factory that uses a service provider to resolve controllers
+
+
Gets the HTML-safe string representation of the tag. Thanks, Microsoft, for making
@@ -91,6 +120,12 @@
The text that the button will display
Any additional HTML attributes for the input tag
+
+
+ Indicates that an object needs to be built up by the container
+
+
+
Service for authenticating users
@@ -203,6 +238,13 @@
not be null.
+
+
+ Flattens a FilterInfo object into a single IEnumerable containing
+ the ActionFilter, ExceptionFilter, ResultFilter and
+ AuthorizationFilter collections
+
+
This class exists to get rid of the SessionState and TempData error. Just google it.
@@ -261,6 +303,17 @@
Configures the application to use log4net
+
+
+ decorator that allows you to explicitly control
+ how the object disposes (useful for 3rd-party objects that do not implement
+ )
+
+
+
+ The LifetimeManager to decorate
+ Action to call when the value is removed to dispose of the object
+
Provides an interface for interacting with session data
@@ -336,6 +389,21 @@
The base class/interface to match against
+
+
+ Gets a value from the request and casts it to the specified type
+
+
+
+
+ Gets a value from the request
+
+
+
+
+ Adds an error to the model state
+
+
Error result factory that returns a result suitable
@@ -359,6 +427,17 @@
Session store that uses the current HttpContext
+
+
+ IControllerFactory that provides a mechanism to perform injection
+ on the controller after it is instantiated
+
+
+
+
+ Event that fires after a controller is instantiated
+
+
Controller for handling and displaying errors that aren't handled by application code
@@ -367,6 +446,11 @@
The factory to use to create the action results
+
+
+ Uses an IUnityContainer to create controllers
+
+
Call handler that wraps a method call in a unit of work
@@ -405,6 +489,18 @@
Gets or sets the currently logged in user, or null if no one is logged in
+
+
+ Provides an interface for identifying the current user
+
+ The user type
+
+
+
+ Returns the user currently performing actions on the site, or null
+ if the user cannot be identified
+
+
Gets all model state errors as a line feed-delimited string
@@ -513,22 +609,6 @@
later.
-
-
- Uses an IUnityContainer to create controllers
-
-
-
-
- IControllerFactory that provides a mechanism to perform injection
- on the controller after it is instantiated
-
-
-
-
- Event that fires after a controller is instantiated
-
-
Negates a matching rule
@@ -564,13 +644,19 @@
Reads the app config and applies the Unity configuration, if applicable
-
+
- Model for displaying a paging menu
+ Gets an object from the request variables, or its default value if
+ the key does not exist
+ The type to convert the value to
+ The request key of the object to retrieve
-
- The model used for displaying the paged data
+
+
+ Strongly-typed model for displaying data that should be paged
+
+ The type of data to be paged
@@ -627,11 +713,114 @@
Gets or sets filtered record set; Count() should be less than or equal to the page size
-
+
- Strongly-typed model for displaying data that is paged
+ Gets or sets filtered record set; Count() should be less than or equal to the page size
+
+
+
+
+ Model for displaying a paging menu
+
+
+
+ The model used for displaying the paged data
+
+
+
+ Gets the data needed to display a link to a certain page
+
+ The number of the page to retrieve
+
+
+
+ Gets or sets action to navigate to when going to the next or previous page
+
+
+
+
+ Gets or sets the controller to navigate to when going to the next or previous page
+
+
+
+
+ Gets the starting point of the current page
+
+
+
+
+ Gets the actual ending point of the current page
+
+
+
+
+ Gets the theoretical ending point of the current page
+
+
+
+
+ Gets the total number of pages in the set
+
+
+
+
+ Gets the current page number
+
+
+
+
+ Gets whether or not a previous page is possible
+
+
+
+
+ Gets whether or not a next page is possible
+
+
+
+
+ Gets the page size
+
+
+
+
+ Gets the total number of records
+
+
+
+
+ Gets whether or not the menu should be shown
+
+
+
+
+ Gets whether or not the current page is a valid page number for the given data
+
+
+
+
+ Gets the data needed to display a link to all the pages
+
+
+
+
+ Represents the data needed to show a link to a page
+
+
+
+
+ Gets or sets the starting point of this page
+
+
+
+
+ Gets or sets the ending point of this page
+
+
+
+
+ Gets or sets the page number
- The type of data to be paged
@@ -667,92 +856,11 @@
-
+
- Matching rule that matches when a method is annotated with an attribute
-
- The attribute to match against
-
-
-
- whose lifetime lasts as long as the HTTP request.
- The object is stored in HttpContext.Current.Items, keyed by a .
-
-
-
-
- decorator that allows you to explicitly control
- how the object disposes (useful for 3rd-party objects that do not implement
- )
-
-
-
- The LifetimeManager to decorate
- Action to call when the value is removed to dispose of the object
-
-
-
- Gets an object from the request variables, or its default value if
- the key does not exist
-
- The type to convert the value to
- The request key of the object to retrieve
-
-
-
- Gets a value from the request and casts it to the specified type
-
-
-
-
- Gets a value from the request
-
-
-
-
- Adds an error to the model state
-
-
-
-
- Indicates that an object needs to be built up by the container
-
-
-
-
-
- Flattens a FilterInfo object into a single IEnumerable containing
- the ActionFilter, ExceptionFilter, ResultFilter and
- AuthorizationFilter collections
-
-
-
-
- Enables you to dynamically add filters to a ControllerActionInvoker. This class will also
- perform injection on all filters that are annotated with NeedsBuildUpAttribute.
-
- Adapted from http://blog.ploeh.dk/2009/12/01/GlobalErrorHandlingInASPNETMVC.aspx
-
-
-
- Overridden to add the new filters to the default filters
-
-
-
-
- Controller factory that uses a service provider to resolve controllers
-
-
-
-
- Provides an interface for identifying the current user
-
- The user type
-
-
-
- Returns the user currently performing actions on the site, or null
- if the user cannot be identified
+ Disallows public access to a controller's action. This is basically a more useful version of
+ . When the action is accessed publicly, an
+ with a 404 status code is raised.
diff --git a/Src/VideoGameQuotes.Api/Quote.cs b/Src/VideoGameQuotes.Api/Quote.cs
index 0793e68..a127345 100644
--- a/Src/VideoGameQuotes.Api/Quote.cs
+++ b/Src/VideoGameQuotes.Api/Quote.cs
@@ -130,7 +130,7 @@ namespace VideoGameQuotes.Api {
Game = Game.ToDto(),
Created = Created,
Categories = Categories.Select(category => category.ToDto()),
- TotalVotes = Votes.Count(),
+ TotalVotes = UpVotes + DownVotes,
UpVotes = UpVotes,
DownVotes = DownVotes,
Score = Score
@@ -188,12 +188,12 @@ namespace VideoGameQuotes.Api {
return years == 1 ? "1 year ago" : years + " years ago";
}
- if (timespan.TotalDays >= 50) {
+ if (timespan.TotalDays >= 31) {
var months = (int)Math.Round(timespan.TotalDays / 30);
return months == 1 ? "1 month ago" : months + " months ago";
}
- if (timespan.TotalDays >= 10) {
+ if (timespan.TotalDays >= 7) {
var weeks = (int)Math.Round(timespan.TotalDays / 7);
return weeks == 1 ? "1 week ago" : weeks + " weeks ago";
}
@@ -202,11 +202,11 @@ namespace VideoGameQuotes.Api {
return (int)timespan.TotalDays == 1 ? "1 day ago" : (int)timespan.TotalDays + " days ago";
}
- if (timespan.TotalMinutes >= 90) {
+ if (timespan.TotalMinutes >= 60) {
return (int)timespan.TotalHours == 1 ? "1 hour ago" : (int)timespan.TotalHours + " hours ago";
}
- if (timespan.TotalSeconds >= 90) {
+ if (timespan.TotalSeconds >= 60) {
return (int)timespan.TotalMinutes == 1 ? "1 minute ago" : (int)timespan.TotalMinutes + " minutes ago";
}
diff --git a/Src/VideoGameQuotes.Web/Controllers/HomeController.cs b/Src/VideoGameQuotes.Web/Controllers/HomeController.cs
index 6dad0be..5eace87 100644
--- a/Src/VideoGameQuotes.Web/Controllers/HomeController.cs
+++ b/Src/VideoGameQuotes.Web/Controllers/HomeController.cs
@@ -6,6 +6,7 @@ using System.Text;
using System.Web.Mvc;
using Portoa.Web;
using Portoa.Web.Controllers;
+using Portoa.Web.Filters;
using Portoa.Web.Security;
using VideoGameQuotes.Api;
using VideoGameQuotes.Web.Models;
@@ -53,7 +54,7 @@ namespace VideoGameQuotes.Web.Controllers {
return Json(this.CreateJsonResponse());
}
- [ChildActionOnly]
+ [PrivateAction]
public ActionResult MainMenu() {
var model = new MainMenuModel { User = userProvider.CurrentUser };
return PartialView("MainMenu", model);
diff --git a/Src/VideoGameQuotes.Web/Controllers/QuoteController.cs b/Src/VideoGameQuotes.Web/Controllers/QuoteController.cs
index ed12483..b1ffd9d 100644
--- a/Src/VideoGameQuotes.Web/Controllers/QuoteController.cs
+++ b/Src/VideoGameQuotes.Web/Controllers/QuoteController.cs
@@ -6,6 +6,7 @@ using Portoa.Persistence;
using Portoa.Search;
using Portoa.Validation.DataAnnotations;
using Portoa.Web.Controllers;
+using Portoa.Web.Filters;
using Portoa.Web.Models;
using Portoa.Web.Results;
using Portoa.Web.Security;
@@ -135,7 +136,7 @@ namespace VideoGameQuotes.Web.Controllers {
return RedirectToAction("Quote", new { id = quote.Id, text = quote.GetUrlFriendlyText() });
}
- [ChildActionOnly]
+ [PrivateAction]
public ActionResult QuoteOfTheDay() {
var today = DateTime.UtcNow.DayOfYear;
var quote = quoteService.GetQuoteForDayOfYear(today);
diff --git a/VideoGameQuotes.sln b/VideoGameQuotes.sln
index f27059e..5645ba0 100644
--- a/VideoGameQuotes.sln
+++ b/VideoGameQuotes.sln
@@ -13,6 +13,47 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Src", "Src", "{C8E910E1-B84
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{236929F9-AE7D-4C78-A3D9-E0ED2EA84609}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Lib", "Lib", "{4C702D70-7D2E-410D-A3C6-50598863E102}"
+ ProjectSection(SolutionItems) = preProject
+ Lib\Antlr3.Runtime.dll = Lib\Antlr3.Runtime.dll
+ Lib\Iesi.Collections.dll = Lib\Iesi.Collections.dll
+ Lib\Iesi.Collections.xml = Lib\Iesi.Collections.xml
+ Lib\LinFu.DynamicProxy.dll = Lib\LinFu.DynamicProxy.dll
+ Lib\log4net.dll = Lib\log4net.dll
+ Lib\log4net.xml = Lib\log4net.xml
+ Lib\Lucene.Net.dll = Lib\Lucene.Net.dll
+ Lib\Lucene.Net.xml = Lib\Lucene.Net.xml
+ Lib\Microsoft.Practices.Unity.Configuration.dll = Lib\Microsoft.Practices.Unity.Configuration.dll
+ Lib\Microsoft.Practices.Unity.Configuration.xml = Lib\Microsoft.Practices.Unity.Configuration.xml
+ Lib\Microsoft.Practices.Unity.dll = Lib\Microsoft.Practices.Unity.dll
+ Lib\Microsoft.Practices.Unity.Interception.Configuration.dll = Lib\Microsoft.Practices.Unity.Interception.Configuration.dll
+ Lib\Microsoft.Practices.Unity.Interception.Configuration.xml = Lib\Microsoft.Practices.Unity.Interception.Configuration.xml
+ Lib\Microsoft.Practices.Unity.Interception.dll = Lib\Microsoft.Practices.Unity.Interception.dll
+ Lib\Microsoft.Practices.Unity.Interception.xml = Lib\Microsoft.Practices.Unity.Interception.xml
+ Lib\Microsoft.Practices.Unity.xml = Lib\Microsoft.Practices.Unity.xml
+ Lib\Moq.dll = Lib\Moq.dll
+ Lib\Moq.xml = Lib\Moq.xml
+ Lib\MySql.Data.dll = Lib\MySql.Data.dll
+ Lib\NHibernate.ByteCode.LinFu.dll = Lib\NHibernate.ByteCode.LinFu.dll
+ Lib\NHibernate.ByteCode.LinFu.xml = Lib\NHibernate.ByteCode.LinFu.xml
+ Lib\NHibernate.dll = Lib\NHibernate.dll
+ Lib\NHibernate.xml = Lib\NHibernate.xml
+ Lib\nunit.framework.dll = Lib\nunit.framework.dll
+ Lib\nunit.framework.xml = Lib\nunit.framework.xml
+ Lib\Portoa.dll = Lib\Portoa.dll
+ Lib\Portoa.Log4Net.dll = Lib\Portoa.Log4Net.dll
+ Lib\Portoa.Log4Net.xml = Lib\Portoa.Log4Net.xml
+ Lib\Portoa.Lucene.dll = Lib\Portoa.Lucene.dll
+ Lib\Portoa.Lucene.xml = Lib\Portoa.Lucene.xml
+ Lib\Portoa.NHibernate.dll = Lib\Portoa.NHibernate.dll
+ Lib\Portoa.NHibernate.xml = Lib\Portoa.NHibernate.xml
+ Lib\Portoa.Web.dll = Lib\Portoa.Web.dll
+ Lib\Portoa.Web.xml = Lib\Portoa.Web.xml
+ Lib\Portoa.xml = Lib\Portoa.xml
+ Lib\Remotion.Data.Linq.dll = Lib\Remotion.Data.Linq.dll
+ Lib\UnityGenerics.dll = Lib\UnityGenerics.dll
+ EndProjectSection
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU