我有 2 节课:
public class CustomerViewModel {
public SystemViewModel system { get;set; }
}
public class SystemViewModel {
public bool isReadOnly { get; set; }
}
在方法控制器操作上,我有一个自定义过滤器属性,它执行一些代码并确定用户是否具有只读或写入访问权限。此属性可以应用于跨多个控制器的多个操作。
到目前为止,使用反射我可以使用以下方法访问模型:
var viewModel = filterContext.Controller.ViewData.Model;
我无法将此模型转换为 CustomerViewModel,因为在不同的操作中它可能类似于 SalaryViewModel。我所知道的是,任何需要 readonly 属性的模型都将具有 SystemViewModel 属性。
从我的自定义过滤器中,我需要一种能够更改只读值的方法。
到目前为止,我有这个:
public override void OnActionExecuted(ActionExecutedContext filterContext) {
var viewModel = filterContext.Controller.ViewData.Model;
var systemViewModelPropertyInfo = model.GetType()
.GetProperties()
.FirstOrDefault(p => p.PropertyType == typeof(SystemViewModel));
if (systemViewModelPropertyInfo != null) {
// Up to here, everything works, systemViewModelPropertyInfo is of
// type PropertyInfo, and the systemViewModelPropertyInfo.PropertyType
// shows the SystemViewModel type
// If we get here, the model has the system property
// Here I need to try and set the IsReadOnly property to true/false;
// This is where I need help please
}
}
已解决 感谢所有参与解决此问题的人。特别感谢Julián Urbano提供了我一直在寻找的解决方案。这是我的过滤器中生成的代码:
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
try
{
var viewModel = filterContext.Controller.ViewData.Model;
var systemViewModelPropertyInfoCount = viewModel.GetType().GetProperties().Count(p => p.PropertyType == typeof(SystemViewModel));
if(systemViewModelPropertyInfoCount == 1)
{
var systemViewModelPropertyInfo = viewModel.GetType().GetProperties().First(p => p.PropertyType == typeof(SystemViewModel));
if(systemViewModelPropertyInfo != null)
{
var systemViewModel = systemViewModelPropertyInfo.GetValue(viewModel, null) as SystemViewModel;
if(systemViewModel != null)
{
var admin = GetAdmin(filterContext.HttpContext.User.Identity.Name);
if(admin != null && _adminService.HasPermission(admin, _privilege, Access.Level.ReadWrite))
systemViewModel.ReadOnly = false;
else
systemViewModel.ReadOnly = true;
}
}
} else if(systemViewModelPropertyInfoCount > 1)
{
throw new Exception("Only once instance of type SystemViewModel allowed");
}
}
catch (Exception exception)
{
Log.Error(MethodBase.GetCurrentMethod(), exception);
filterContext.Controller.TempData["ErrorMessage"] = string.Format("Technical error occurred");
filterContext.Result = new RedirectResult("/Error/Index");
}
finally
{
base.OnActionExecuted(filterContext);
}
}