【问题标题】:Disable class attribute while on Design Mode在设计模式下禁用类属性
【发布时间】:2016-11-28 17:48:58
【问题描述】:

我正在编写一个 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

因为如果我设置它,那么视图模型就会受到限制(因此只有经过身份验证的用户才能查看它)并且它在运行时工作得很好;我在哪里检查并重定向到登录视图模型;但后来我失去了 WPF 编辑器的所有设计功能(因为设计编辑器显示空白屏幕)。如果我评论该属性并清理/重建项目,那么编辑器将再次工作;但这不是一个真正的选择,因为我有近 70 个视图,我们是一个由 13 名开发人员/设计师组成的小组。

有没有一种方法可以限制该属性仅在它不在设计模式下时才设置?所以我们可以设计/开发和测试,而无需手动评论 70 多个视图?

【问题讨论】:

  • 您使用此属性来限制基于当前 Windows 用户的访问?
  • @Evk 没有。我针对现有的服务总线实现了自定义身份验证服务。但我使用的是框架内置机制。

标签: c# wpf authentication caliburn.micro custom-attributes


【解决方案1】:

由于这些 CAS 属性的工作方式(相关权限基本上在编译时嵌入到生成的 dll 中),您必须创建自己的PrincipalPermission,但这并不难,因为您可以将所有工作代理到真实的@987654322 @:

[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 来返回我们的权限(属性很简单,我们完全复制它):

[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 设计器进行测试 - 不仅仅是重建项目,而是杀死所有 XDesProc.exe 进程(这些是 WPF 设计器的进程)。

【讨论】:

  • 谢谢@Evk,我会尽力让你知道的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-06-03
  • 1970-01-01
  • 2015-01-26
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
相关资源
最近更新 更多