在设计模式下禁用 class 属性
Disable class attribute while on Design Mode
我正在编写一个 WPF 应用程序并使用自定义主体实现自定义安全身份验证和授权,并且效果很好。我使用 CaliburnMicro 作为 MVVM 框架。我正在使用它的设计模式支持,所以在我拥有的每个视图上:
xmlns:vm="clr-namespace:Project.ViewModels"
xmlns:cal="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro.Platform"
cal:Bind.AtDesignTime="True"
d:DataContext="{d:DesignInstance Type=vm:MyViewModel, IsDesignTimeCreatable=True}">
然后,当我在 Visual Studio 中工作时,我可以查看和编辑由视图模型填充的控件。然而,问题是 PrincipalPermission
属性:
[PrincipalPermission(SecurityAction.Demand)]
public class MyViewModel : Screen
因为如果我设置它,那么 View Model 就会受到限制(因此只有经过身份验证的用户才能查看它)并且它在运行时运行良好;我在哪里检查并重定向到登录视图模型;但后来我失去了 WPF 编辑器的所有设计功能(因为设计编辑器显示空白屏幕)。如果我评论那个属性,clean/rebuild 项目,然后编辑器再次工作;但这不是一个真正的选择,因为我有将近 70 次观看,而我们是 13 人一组 developers/designers。
有什么方法可以限制该属性仅在不处于设计模式时设置?所以我们可以 design/develop 和测试而无需手动评论 70 多个视图?
由于这些 CAS 属性的工作方式(相关权限基本上在编译时嵌入到生成的 dll 中),您必须创建自己的 PrincipalPermission
,但这并不难,因为您可以代理所有工作真实 PrincipalPermission
:
[ComVisible(true)]
[Serializable]
public sealed class PrincipalPermissionProxy : IPermission, IUnrestrictedPermission
{
private readonly PrincipalPermission _inner;
public PrincipalPermissionProxy(PrincipalPermission inner) {
_inner = inner;
}
public IPermission Copy()
{
return _inner.Copy();
}
public void Demand() {
// NOTE here we check if we are running under designer and if so - ignore demand
if (DesignerProperties.GetIsInDesignMode(new DependencyObject()))
return;
_inner.Demand();
}
public void FromXml(SecurityElement e)
{
_inner.FromXml(e);
}
public IPermission Intersect(IPermission target)
{
return _inner.Intersect(target);
}
public bool IsSubsetOf(IPermission target)
{
return _inner.IsSubsetOf(target);
}
public bool IsUnrestricted()
{
return _inner.IsUnrestricted();
}
public SecurityElement ToXml()
{
return _inner.ToXml();
}
public IPermission Union(IPermission target)
{
return _inner.Union(target);
}
}
然后我们将 PrincipalPermissionAttribute 复制到 return 我们的许可(属性很简单,我们完全复制它):
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
[ComVisible(true)]
[Serializable]
public sealed class MyPrincipalPermissionAttribute : CodeAccessSecurityAttribute {
public string Name { get; set; }
public string Role { get; set; }
public bool Authenticated { get; set; } = true;
public MyPrincipalPermissionAttribute(SecurityAction action)
: base(action) {
}
public override IPermission CreatePermission() {
if (this.Unrestricted)
return new PrincipalPermissionProxy(new PrincipalPermission(PermissionState.Unrestricted));
return new PrincipalPermissionProxy(new PrincipalPermission(this.Name, this.Role, this.Authenticated));
}
}
然后将所有属性替换为 MyPermissionAttribute
(当然还有一些奇特的名称 :))并完成 - 设计器现在可以正常工作了。
注意何时使用 WPF 设计器进行测试 - 不仅重建项目而且 kill 所有 XDesProc.exe 进程(那些是 WPF 设计器的进程)。
我正在编写一个 WPF 应用程序并使用自定义主体实现自定义安全身份验证和授权,并且效果很好。我使用 CaliburnMicro 作为 MVVM 框架。我正在使用它的设计模式支持,所以在我拥有的每个视图上:
xmlns:vm="clr-namespace:Project.ViewModels"
xmlns:cal="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro.Platform"
cal:Bind.AtDesignTime="True"
d:DataContext="{d:DesignInstance Type=vm:MyViewModel, IsDesignTimeCreatable=True}">
然后,当我在 Visual Studio 中工作时,我可以查看和编辑由视图模型填充的控件。然而,问题是 PrincipalPermission
属性:
[PrincipalPermission(SecurityAction.Demand)]
public class MyViewModel : Screen
因为如果我设置它,那么 View Model 就会受到限制(因此只有经过身份验证的用户才能查看它)并且它在运行时运行良好;我在哪里检查并重定向到登录视图模型;但后来我失去了 WPF 编辑器的所有设计功能(因为设计编辑器显示空白屏幕)。如果我评论那个属性,clean/rebuild 项目,然后编辑器再次工作;但这不是一个真正的选择,因为我有将近 70 次观看,而我们是 13 人一组 developers/designers。
有什么方法可以限制该属性仅在不处于设计模式时设置?所以我们可以 design/develop 和测试而无需手动评论 70 多个视图?
由于这些 CAS 属性的工作方式(相关权限基本上在编译时嵌入到生成的 dll 中),您必须创建自己的 PrincipalPermission
,但这并不难,因为您可以代理所有工作真实 PrincipalPermission
:
[ComVisible(true)]
[Serializable]
public sealed class PrincipalPermissionProxy : IPermission, IUnrestrictedPermission
{
private readonly PrincipalPermission _inner;
public PrincipalPermissionProxy(PrincipalPermission inner) {
_inner = inner;
}
public IPermission Copy()
{
return _inner.Copy();
}
public void Demand() {
// NOTE here we check if we are running under designer and if so - ignore demand
if (DesignerProperties.GetIsInDesignMode(new DependencyObject()))
return;
_inner.Demand();
}
public void FromXml(SecurityElement e)
{
_inner.FromXml(e);
}
public IPermission Intersect(IPermission target)
{
return _inner.Intersect(target);
}
public bool IsSubsetOf(IPermission target)
{
return _inner.IsSubsetOf(target);
}
public bool IsUnrestricted()
{
return _inner.IsUnrestricted();
}
public SecurityElement ToXml()
{
return _inner.ToXml();
}
public IPermission Union(IPermission target)
{
return _inner.Union(target);
}
}
然后我们将 PrincipalPermissionAttribute 复制到 return 我们的许可(属性很简单,我们完全复制它):
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
[ComVisible(true)]
[Serializable]
public sealed class MyPrincipalPermissionAttribute : CodeAccessSecurityAttribute {
public string Name { get; set; }
public string Role { get; set; }
public bool Authenticated { get; set; } = true;
public MyPrincipalPermissionAttribute(SecurityAction action)
: base(action) {
}
public override IPermission CreatePermission() {
if (this.Unrestricted)
return new PrincipalPermissionProxy(new PrincipalPermission(PermissionState.Unrestricted));
return new PrincipalPermissionProxy(new PrincipalPermission(this.Name, this.Role, this.Authenticated));
}
}
然后将所有属性替换为 MyPermissionAttribute
(当然还有一些奇特的名称 :))并完成 - 设计器现在可以正常工作了。
注意何时使用 WPF 设计器进行测试 - 不仅重建项目而且 kill 所有 XDesProc.exe 进程(那些是 WPF 设计器的进程)。