0
votes

I am developing a WPF application and I am targeting the .NET Framework 4

I have a TextBox bound to an Email Property and the binding has ValidatesOnException=True to catch any exceptions that may occur while setting the Email property.

My Email Property throws a security exception if the current principal is not in the role "edit-person".

When the security exception is thrown, the application crashes instead of highlighting the email TextBox in red.

Here is my XAML binding for the TextBox:

 <TextBox Text="{Binding Path=Email, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}" />

Here is my Email Property code:

 Public Property Email As String
    Get
        Return return _email
    End Get
    Set(value As String)
        If Not Thread.CurrentPrincipal.IsInRole("Edit-Person") Then Throw New Security.SecurityException("You are not permitted to edit the email address")
        _email = value
    End Set
End Property

If I throw a ValidationException or ArgumentException the binding catches the exception and the application does not crash. It seems to only be a problem with the SecurityException.

According to the MSDN documentation for the Binding.ValidatesOnException Property, I cannot understand why this does not work.

Implementing the IDataErrorInfo interface is not an option for me.

I could really use some advice here.

Edit: I created a new test project to make sure there wasn't something strange happening in the one that I was working with and found the same results.

I created a test WFP project called WPFSecurityException and copy pasted the example from the MSDN Documentation for the ValidationException property...and modified the exception thrown to be a SecurityExcpetion.

For example, here is my XAML for the MainWindow of the test WPF project:

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:src="clr-namespace:WPFSecurityExceptionTest"
    Title="MainWindow" Height="350" Width="525">
    <StackPanel Margin="20">
        <StackPanel.Resources>
            <src:PersonThrowException x:Key="data"/>

            <!--The tool tip for the TextBox to display the validation error message.-->
            <Style x:Key="textBoxInError" TargetType="TextBox">
                <Style.Triggers>
                    <Trigger Property="Validation.HasError" Value="true">
                        <Setter Property="ToolTip" Value="{Binding RelativeSource={x:Static RelativeSource.Self}, Path=(Validation.Errors)[0].ErrorContent}"/>
                    </Trigger>
                </Style.Triggers>
            </Style>

        </StackPanel.Resources>
        <TextBlock>Enter your age:</TextBlock>
        <TextBox Style="{StaticResource textBoxInError}">
            <TextBox.Text>
                <!--By setting ValidatesOnExceptions to True, it checks for exceptions
        that are thrown during the update of the source property.
        An alternative syntax is to add <ExceptionValidationRule/> within
        the <Binding.ValidationRules> section.-->
                <Binding Path="Age" Source="{StaticResource data}"
                         ValidatesOnExceptions="True"
                         UpdateSourceTrigger="PropertyChanged" 
                         >
                </Binding>
            </TextBox.Text>
        </TextBox>
        <TextBlock>Mouse-over to see the validation error message.</TextBlock>
    </StackPanel>
</Window>

And here is the VB.NET code for the window and the custom PersonThrowException class:

Class MainWindow 

End Class
Public Class PersonThrowException
    Private m_age As Integer

    Public Property Age() As Integer
        Get
            Return m_age
        End Get
        Set(ByVal value As Integer)

            If value < 0 OrElse value > 150 Then
                Throw New Security.SecurityException("Age must not be less than 0 or greater than 150.")
            End If
            m_age = value
        End Set
    End Property
End Class
1
Why are you fighting it? Just throw an ArgumentException. Would you want validation to swallow a general exception? - paparazzo
Because when you do not have permissions to something, it isn't an "ArugmentException", it is a security exception. - Frinavale
And there is Nothing to indicate that SecurityExceptions should not be caught and handled like other types of exceptions. If I throw a SystemException (the exception SecuirtyException inherits from) it is handled fine...if I throw any other type of exception that I can think of it is handled fine...What is with SecurityException? - Frinavale
How would throw new ArgumentException("Security Violation"); break your program or validation? I personally don't like that validation handles a general exception. You like that validation handles a general exception? - paparazzo
In my case, I am not using view models. I am binding directly to the business logic classes which are being used by multiple applications. It is not "correct" to be throwing a validation exception in the case when a security violation has occurred. To get around my WPF application crashing when a user doesn't have permissions to something, I have properly disabled/hidden controls according to the user permissions; however, I still do not understand WHY the security exception doesn't get caught while all others do. - Frinavale

1 Answers

0
votes

Have you tried building your code in Release mode and running the executable from outside Visual Studio?

From the answer to another question: https://stackoverflow.com/a/5510097/4456875

The solution is not so obvious nor well documented, but simple enough. The reason Visual Studio breaks for exceptions when running in debug mode is because it's configured that way

You can configure this behaviour in Debug->Exceptions menu or just run the executable