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