tsunami

log in
history

tsunami RequestVariables.cs

Luke Breuer
0001-01-01 05:00 UTC

using System;
using System.Web;

namespace Time
{
    public class InvalidRequestVariableException : Exception
    {
        private string _friendlyMessage;

        public string FriendlyMessage
        {
            get { return _friendlyMessage; }
        }

        public InvalidRequestVariableException(string message, string friendlyMessage)
            : base(message)
        {
            _friendlyMessage = friendlyMessage;
        }

        public InvalidRequestVariableException(string message)
            : base(message)
        {
            _friendlyMessage = message;
        }
    }

    /// <summary>
    /// Encapsulates Querystring and Form variables, validating them and making them type-safe.
    /// </summary>
    public abstract class RequestVariables
    {
        public RequestVariables()
        { }

        protected static int GetNonNegativeInt32(string key)
        {
            return GetNonNegativeInt32(key, false);
        }

        protected static int GetNonNegativeInt32(string key, bool required)
        {
            string sVal = HttpContext.Current.Request[key];
            int nVal;

            if (sVal == null)
            {
                if (!required)
                    return -1;
                else
                    throw new InvalidRequestVariableException(string.Format(
                        "Querystring variable '{0}' was not specified and is required.", key));
            }
            if (!int.TryParse(sVal, out nVal))
                throw new InvalidRequestVariableException(string.Format(
                    "Querystring variable '{0}' ( = '{1}') must be an non-negative integer.", key, sVal));
            if (nVal < 0)
                throw new InvalidRequestVariableException(string.Format(
                    "Querystring variable '{0}' ( = '{1}') must be non-negative.", key, sVal));

            return nVal;
        }

        protected static string GetRequiredString(string key)
        {
            string s = HttpContext.Current.Request[key];

            if (s == null)
                throw new InvalidRequestVariableException(string.Format(
                    "Querystring variable '{0}' was not specified and is required.", key));
            if (s.Length == 0)
                throw new InvalidRequestVariableException(string.Format(
                    "Querystring variable '{0}' must not be zero length.", key));

            return s;
        }

        protected static T SelectValue<T>(string key, params object[] stringThenEnum)
            where T : struct
        {
            if (stringThenEnum == null || stringThenEnum.Length == 0 || stringThenEnum.Length % 2 == 1)
                throw new ArgumentException("stringThenEnum must have 2, 4, 6, ... elements.");

            string value = HttpContext.Current.Request[key];

            if (value == null)
                return default(T);

            value = value.ToLower();

            for (int i = 0; i < stringThenEnum.Length; i += 2)
                if (value == (string)stringThenEnum[i])
                    return (T)stringThenEnum[i + 1];

            string[] validValues = new string[stringThenEnum.Length / 2];

            for (int i = 0; i < stringThenEnum.Length; i += 2)
                validValues[i / 2] = (string)stringThenEnum[i];

            throw new InvalidRequestVariableException(string.Format(
                "Request variable '{0}' has an invalid value ('{1}'); valid values: ('{2}').",
                key, value, string.Join("', '", validValues)));
        }
    }

    public enum ItemPostReason
    {
        None,
        SaveEdit,
        CancelEdit
    }

    public enum AddRelationship
    {
        None,
        Subject,
        Object,
        Predicate
    }

    public class MasterRequestVariables : RequestVariables
    {
        private bool _noResponse;

        public bool NoResponse
        {
            get { return _noResponse; }
        }

        public MasterRequestVariables()
        {
            HttpRequest Request = HttpContext.Current.Request;

            _noResponse = Request["noresponse"] == "yes";
        }
    }

    public class ForumRequestVariables : RequestVariables
    {
        private int _forumPk;

        public int ForumPk
        {
            get { return _forumPk; }
        }

        public ForumRequestVariables()
        {
            HttpRequest Request = HttpContext.Current.Request;

            _forumPk = GetNonNegativeInt32("forumPk");
        }
    }

    public class ThreadRequestVariables : RequestVariables
    {
        private int _forumPk;
        private int _threadPk;

        public int ForumPk
        {
            get { return _forumPk; }
        }

        public int ThreadPk { get { return _threadPk; } }

        public ThreadRequestVariables()
        {
            HttpRequest Request = HttpContext.Current.Request;

            _forumPk = GetNonNegativeInt32("forumPk");
            _threadPk = GetNonNegativeInt32("threadPk");
        }
    }

    public class ItemRequestVariables : RequestVariables
    {
        private int _itemPk;
        private string _itemName;
        private bool _editRequested;
        private ItemPostReason _postReason;
        private string _searchText;
        private string _tagText;
        private AddRelationship _addRelationship;
        private string _ajaxSearch;
        private string _ajaxRelTextboxId;

        public string AjaxSearch
        {
            get { return _ajaxSearch; }
        }

        public int ItemPk
        {
            get { return _itemPk; }
        }

        public string ItemName
        {
            get { return _itemName; }
        }

        public bool EditRequested
        {
            get { return _editRequested; }
        }

        public ItemPostReason PostReason
        {
            get { return _postReason; }
        }

        public string SearchText
        {
            get { return _searchText; }
        }

        public string TagText
        {
            get { return _tagText; }
        }

        public AddRelationship AddRelationship
        {
            get { return _addRelationship; }
        }

        public bool ItemCriteriaSpecified
        {
            get { return _itemPk != -1 || _itemName != null; }
        }

        public string AjaxRelTextboxId
        {
            get { return _ajaxRelTextboxId; }
        }

        public ItemRequestVariables()
        {
            HttpRequest Request = HttpContext.Current.Request;

            _itemPk = GetNonNegativeInt32("pk");
            _itemName = Request["name"];
            _editRequested = Request["edit"] != null;
            _searchText = Request["search"];
            _tagText = Request["tag"];
            _ajaxSearch = Request["ajaxSearch"];
            _ajaxRelTextboxId = Request["relTxtId"];

            _addRelationship = SelectValue<AddRelationship>("add",
                "object", AddRelationship.Object,
                "subject", AddRelationship.Subject,
                "predicate", AddRelationship.Predicate);

            _postReason = SelectValue<ItemPostReason>("postReason",
                "save", ItemPostReason.SaveEdit,
                "cancel", ItemPostReason.CancelEdit);
        }
    }
}