using System; using System.Collections.Generic; using System.Web.Mvc; using System.Web.Security; using log4net; using Sleis.Models; using Sleis.ViewModels; using Sleis.Service; using Sleis.Utility; using System.Web; using System.Collections; using Sleis.Models.CustomFields; using Sleis.Validation.Spring; using System.IO; using System.Web.Routing; using System.Linq; using Sleis.Models.ErrorHandling; namespace Sleis.Controllers { public abstract class BaseController : Controller { internal static ILog Log; public IPropertyPlaceholder Properties { get; set; } public UserService UserService { get; set; } public PageService PageService { get; set; } public IFacilityService FacilityService { get; set; } public EncryptionUtility EncryptionUtility { get; set; } public UserView AppUser { get { return SessionUtility.CurrentUserView; } private set { SessionUtility.CurrentUserView = value; } } public string BaseUri { get; set; } public string DocValidTypes { get; set; } public string ErrorOnSave { get; set; } public ObjectValidator Validator { get; set; } /// /// PageKey to be used for A_PAGE Help and Fields /// public string PageKey { get; set; } public BaseController() { Log = LogManager.GetLogger(this.GetType()); } public virtual void Init() { ArgumentValidationUtility.ThrowOnNull(Properties, "Properties"); ArgumentValidationUtility.ThrowOnNull(UserService, "UserService"); ArgumentValidationUtility.ThrowOnNull(PageService, "PageService"); ArgumentValidationUtility.ThrowOnNull(FacilityService, "FacilityService"); ArgumentValidationUtility.ThrowOnNull(EncryptionUtility, "EncryptionUtility"); //TODO: Uncomment once all the validation has been implemented //ArgumentValidationUtility.ThrowOnNull(Validator, "Validator"); ArgumentValidationUtility.ThrowOnEmpty(BaseUri, "BaseUri"); ArgumentValidationUtility.ThrowOnEmpty(DocValidTypes, "BaseUri"); foreach (KeyValuePair prop in Properties.ExposedProps) { ViewData[prop.Key] = prop.Value; } } public string GetPageContext(string controller, string action) { if (String.IsNullOrEmpty(PageKey)) { PageKey = String.Format("/{0}/{1}", controller, action); return PageKey; } else { return PageKey; } } public UserView ReloadUserContext(int userId) { Log.Debug(String.Format("Reloading User Context for user: {0}", userId)); AppUser = new UserView(); AppUser.User = UserService.GetUser(userId); Session.Remove(UserModel.SESSION_USER_KEY); Session.Add(UserModel.SESSION_USER_KEY, AppUser); //TempData[UserModel.SESSION_USER_KEY] = AppUser; TempData[Constants.GlobalErrorMessageKey] = ErrorOnSave; ViewData[Constants.PageKey] = PageKey; return AppUser; } protected override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); //TempData[Constants.GlobalErrorMessageKey] = ErrorOnSave; ViewData[Constants.PageKey] = PageKey; //setting Facility info here if in query string. This way logic doesn't have happen on every action, especially when linking from quickfind. SetSelectedFacility(filterContext.HttpContext.Request.QueryString["facilityId"]); SetAgencyReport(filterContext.HttpContext.Request.QueryString["reportId"]); } protected override void OnAuthorization(AuthorizationContext filterContext) { base.OnAuthorization(filterContext); AppUser = filterContext.HttpContext.Session[UserModel.SESSION_USER_KEY] as UserView; //restore user if not currently available. if (AppUser == null) { //restore session if possible SessionUtility.RestoreUserSession(UserService); } //restore current selected facility if not available if (AppUser != null && (AppUser.SelectedFacility == null || AppUser.SelectedFacility.Id < 1)) { SetSelectedFacility(filterContext.HttpContext.Request.QueryString["facilityId"]); } Session[UserModel.SESSION_USER_KEY] = AppUser; } public T GetTempData(string key) { object obj = TempData[key]; if (obj == null) { return default(T); } return (T)obj; } public void SetTempData(string key, T value) { if (value == null) { TempData.Remove(key); } else { TempData[key] = value; } } public void SetSelectedAgencyFacility(int facilityId) { if (AppUser == null) { throw new ArgumentNullException("Null AppUser"); } if (AppUser.SelectedFacility == null || AppUser.SelectedFacility.Facility == null || AppUser.SelectedFacility.Facility.Id != facilityId) { //HttpContext.Session.Remove(UserModel.SESSION_USER_KEY); //Populate the user facility roles AppUser.SelectedFacility = new SelectedFacilityView( FacilityService.FacilityData.GetSimpleAgencyFacility(facilityId), FacilityService.FacilityData.GetFacilityAddress(facilityId), UserService.RoleData.GetFacilityRoles(AppUser.User.Id, facilityId), UserService.RoleData.GetAgencyRoles(AppUser.User.Id, facilityId), UserService.UserData.GetAuthorizedUsers(AppUser.User.Id, facilityId)); //Set the user to session //HttpContext.Session.Add(UserModel.SESSION_USER_KEY, AppUser); } Session[UserModel.SESSION_USER_KEY] = AppUser; } public void SetSelectedFacility(int facilityId) { if (AppUser == null) { //throw new ArgumentNullException("Null AppUser"); SleisVisit identity = (SleisVisit)User.Identity; //try and repopulate user data. Since we check if AppUser is null on Constructor..this logic is getting ran prior to authorization logic. if (identity != null && identity.IsAuthenticated && !identity.Expired && identity.Id > 0) { AppUser = ReloadUserContext(identity.Id); } //user ticket is invalid. redirect to login else { //TempData[Constants.GlobalMessageKey] = new SimpleMessage("User session has expired. Please login again and retry your action."); Response.Redirect("~/Account/Login"); } } if (AppUser.SelectedFacility == null || AppUser.SelectedFacility.Facility == null || AppUser.SelectedFacility.Facility.Id != facilityId) { //HttpContext.Session.Remove(UserModel.SESSION_USER_KEY); //Populate the user facility roles AppUser.SelectedFacility = new SelectedFacilityView( FacilityService.FacilityData.GetSimpleFacility(facilityId), FacilityService.FacilityData.GetFacilityAddress(facilityId), UserService.RoleData.GetFacilityRoles(AppUser.User.Id, facilityId), UserService.RoleData.GetAgencyRoles(AppUser.User.Id, facilityId), UserService.UserData.GetAuthorizedUsers(AppUser.User.Id, facilityId)); //Set the user to session //HttpContext.Session.Add(UserModel.SESSION_USER_KEY, AppUser); } //TempData[UserModel.SESSION_USER_KEY] = AppUser; } public override string ToString() { return Utility.ReflectionUtility.GetPublicPropertiesString(this); } public List GetCustomFields(int entityId, int reportingYear, CustomFieldEntityType fieldEntityType) { switch (fieldEntityType) { case CustomFieldEntityType.Facility: return SessionUtility.CurrentUser.IsAgencyUser() ? FacilityService.GetCustomFields(entityId, reportingYear, fieldEntityType) : FacilityService.GetCustomFields(entityId, reportingYear, fieldEntityType); case CustomFieldEntityType.ControlDevice: return SessionUtility.CurrentUser.IsAgencyUser() ? FacilityService.GetCustomFields(entityId, reportingYear, fieldEntityType) : FacilityService.GetCustomFields(entityId, reportingYear, fieldEntityType); case CustomFieldEntityType.EmissionUnit: return SessionUtility.CurrentUser.IsAgencyUser() ?FacilityService.GetCustomFields(entityId, reportingYear, fieldEntityType) : FacilityService.GetCustomFields(entityId, reportingYear, fieldEntityType); case CustomFieldEntityType.UnitProcess : return SessionUtility.CurrentUser.IsAgencyUser() ?FacilityService.GetCustomFields(entityId, reportingYear, fieldEntityType) : FacilityService.GetCustomFields(entityId, reportingYear, fieldEntityType); case CustomFieldEntityType.ReleasePoint: return SessionUtility.CurrentUser.IsAgencyUser() ? FacilityService.GetCustomFields(entityId, reportingYear, fieldEntityType) : FacilityService.GetCustomFields(entityId, reportingYear, fieldEntityType); case CustomFieldEntityType.ProcessEmission: return FacilityService.GetCustomFields(entityId, reportingYear, fieldEntityType); case CustomFieldEntityType.AgencyFacility: //AgencyFacility entity type does not exist as type in table. need to use Facility instead. return FacilityService.GetCustomFields(entityId, reportingYear, CustomFieldEntityType.Facility); default: throw new ApplicationException(fieldEntityType.ToString() + " not defined yet"); } } protected override void OnException(ExceptionContext filterContext) { //if user account got locked, redirect to home page and notify. if (filterContext.Exception is AccountLockedException) { filterContext.ExceptionHandled = true; TempData[Constants.GlobalMessageKey] = new SimpleMessage(filterContext.Exception.Message, true); filterContext.Result = RedirectToAction("Home", "Public"); } base.OnException(filterContext); } /* public List GetCustomFields(int entityId) where T : CustomFieldEntityValue { return FacilityService.GetCustomFields(entityId); } public List GetCustomFields(int entityId, int reportId) where T : CustomFieldEntityValue { return FacilityService.GetCustomFields(entityId, reportId); } */ /* Old - Replaced with new model 5-3-2011 - ~B [Authorize, HttpPost] public virtual ActionResult Toggle(string actionType, string filterVal, int selectedRecordId, int reportId, int facilityId, int[] recordId, FormCollection args) { ToggleInfo toggleInfo = new ToggleInfo(selectedRecordId, recordId, filterVal); toggleInfo.ReportId = reportId; toggleInfo.FacilityId = facilityId; SetTempData(Constants.ToggleInfo, toggleInfo); switch (actionType) { case "details": return RedirectToAction("Details", new { id = selectedRecordId, reportId = reportId, facilityId = facilityId }); case "edit": return RedirectToAction("Edit", new { id = selectedRecordId, reportId = reportId, facilityId = facilityId }); default: throw new NotSupportedException(String.Format("{0} is an unsupported command.", actionType)); } } */ [Authorize, HttpPost] public ActionResult Toggle(string actionType, string filterVal, int selectedRecordId, int facilityId, int[] recordId, List records, int reportId = 0, string altIdKey = "", string altIdValue = "") { ToggleInfo toggleInfo = new ToggleInfo(selectedRecordId, recordId, filterVal, records); toggleInfo.ReportId = reportId; toggleInfo.FacilityId = facilityId; ToggleRecord selectedRecord = new ToggleRecord(); //in the event that Record Id is 0, due to records being listed but not yet created, we need an alternate unique identifier. if (records.Count(r => r.RecordId == 0) > 1) { selectedRecord = records.SingleOrDefault(r => r.UrlParams[altIdKey] == altIdValue); } else { selectedRecord = records.SingleOrDefault(r => r.RecordId == selectedRecordId); } //build route dictonary with primary values RouteValueDictionary routeVals = new RouteValueDictionary(); routeVals.Add("id", selectedRecordId); routeVals.Add("reportId", reportId); routeVals.Add("facilityId", facilityId); routeVals.Add("toggleIndex", toggleInfo.CurrentIndex); //add any additional Url Paramaters that might have been posted over if (selectedRecord.UrlParams != null && selectedRecord.UrlParams.Count > 0) { foreach (string key in selectedRecord.UrlParams.Keys) { routeVals.Add(key, selectedRecord.UrlParams[key]); } } SetTempData(Constants.ToggleInfo, toggleInfo); switch (actionType) { //case "details": return RedirectToAction("Details", new { id = selectedRecordId, reportId = reportId, facilityId = facilityId, unitProcessId = unitProcessId }); case "details": return RedirectToAction("Details", routeVals); case "edit": return RedirectToAction("Edit", routeVals); default: throw new NotSupportedException(String.Format("{0} is an unsupported command.", actionType)); } } //public void LoadListViewModel(int id, int facilityId, ListViewBaseModel baseModel) //{ // FacilityDetailModel fac = UserService.FacilityData.GetFacility(AppUser.Id, facilityId); // LoadFacilityUserRole(facilityId); // baseModel.Report = fac.SelectedReportDetail.Find(x => x.Id == id); // baseModel.FacilityId = facilityId; // baseModel.CurrentUser = AppUser; //} //public void LoadFacilityUserRole(int facilityId, bool update = false) //{ // if (!update) // { // if (AppUser.FacilityRoles == null || AppUser.FacilityRoles.Count == 0) // { // HttpContext.Session.Remove(UserModel.SESSION_USER_KEY); // //Populate the user facility roles // AppUser.FacilityRoles = UserService.RoleData.GetFacilityRoles(AppUser.Id, facilityId); // //Set the user to session // HttpContext.Session.Add(UserModel.SESSION_USER_KEY, AppUser); // } // } // else // { // HttpContext.Session.Remove(UserModel.SESSION_USER_KEY); // //Populate the user facility roles // AppUser.FacilityRoles = UserService.RoleData.GetFacilityRoles(AppUser.Id, facilityId); // //Set the user to session // HttpContext.Session.Add(UserModel.SESSION_USER_KEY, AppUser); // } //} protected override void OnActionExecuted(ActionExecutedContext filterContext) { //SetToggleInfo(); if (!String.IsNullOrWhiteSpace(PageKey)) { TempData[Constants.PageFieldsKey] = PageService.GetPageFields(PageKey); } //if enable error summary, attach errors to create detailed error messages. if (Convert.ToBoolean(Properties.Get(Constants.EnableDetailedErrorMessages))) { if (TempData[Constants.GlobalErrorMessageKey] != null) { string message = TempData[Constants.GlobalErrorMessageKey] as string; foreach (KeyValuePair modelState in ViewData.ModelState) { foreach (ModelError error in modelState.Value.Errors) { message += String.Format(" {0} Provider: {1}", error.ErrorMessage, modelState.Key); } } /* var alteredResult = filterContext.Result as ViewResult; if (alteredResult != null) { var alteredTempData = alteredResult.TempData; alteredTempData[Constants.GlobalMessageKey] = message; filterContext.Result = alteredResult; } */ TempData[Constants.GlobalErrorMessageKey] = message; } } } protected override void OnResultExecuting(ResultExecutingContext filterContext) { base.OnResultExecuting(filterContext); } public string RenderPartialViewToString(string viewName, object model) { ViewData.Model = model; using (StringWriter sw = new StringWriter()) { ViewEngineResult viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName); ViewContext viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw); viewResult.View.Render(viewContext, sw); return sw.GetStringBuilder().ToString(); } } private void SetSelectedFacility(string facilityId) { int facId = 0; Int32.TryParse(facilityId, out facId); if (facId > 0) { SetSelectedFacility(facId); } } private void SetAgencyReport(string reportId) { int id = 0; Int32.TryParse(reportId, out id); if (id > 0) { //check if current value changed if (SessionUtility.CurrentReport==null || id != SessionUtility.CurrentReport.Id) SessionUtility.CurrentReport = FacilityService.FacilityEmissionReportData.GetById(id); } } } }