【问题标题】:Property.GetValue - Test for null breaks with inner exception of null reference?Property.GetValue - 使用空引用的内部异常测试空中断?
【发布时间】:2018-05-11 13:08:43
【问题描述】:

我需要扫描一堆 Outlook '.msg' 文件并使用 MsgReader 库来执行此操作。 (MsgReader Library Project on Github) 我编写了以下方法,该方法打开消息,读取每个属性并提取任何标记为“字符串”的属性,以添加到字典中以返回给调用者。 代码如下:

    public Dictionary<string, string> GetMsgFileDetails(string filepath)
    {
        Dictionary<string, string> filedetails = new Dictionary<string, string>();
        //try
        {
            string fullpath = Path.Combine(SelectedFolder, filepath);
            var msg = new Storage.Message(fullpath);
            foreach (var prop in msg.GetType().GetProperties())
            {
                string pname = prop.Name;

                if (prop.GetValue(msg) != null)
                {
                    object pvalue = prop.GetValue(msg);
                }
                // We only want the strings
                if (prop.GetValue(msg) != null && (prop.GetValue(msg) is string))
                {
                    filedetails.Add(prop.Name, prop.GetValue(msg).ToString());
                }

            }
            return filedetails;
        }
        //catch (Exception ex)
        //{
        //    MessageBox.Show(ex.Message, "Error trying to load file");
        //    return null;
        //}
    }

 (the try-catch block is commented out to allow easier debugging).

这一切似乎都工作得很好,但它达到了导致

的值之一
   (prop.GetValue(msg) != null)

用系统反射 TargetInvocationException 中断的行。异常详情如下:


C:\Users\Brett\source\repos\FileMunger\FileMunger\ViewModels\FolderContext.cs:line 208
at FileThing.ViewModels.FolderContext.GetProperties(String filepath, Boolean showwindow) in C:\Users\Brett\source\repos\FileMunger\FileMunger\ViewModels\FolderContext.cs:line 159
at FileMunger.MainWindow.FileList_Selected(Object sender, RoutedEventArgs e) in C:\Users\Brett\source\repos\FileMunger\FileMunger\MainWindow.xaml.cs:line 121
at system.Windows.Controls.SelectionChangedEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs e)
at System.Windows.Controls.ListBox.OnSelectionChanged(SelectionChangedEventArgs e)
at System.Windows.Controls.Primitives.Selector.InvokeSelectionChanged(List`1 unselectedInfos, List`1 selectedInfos)
at System.Windows.Controls.Primitives.Selector.SelectionChanger.End()
at System.Windows.Controls.Primitives.Selector.SelectionChanger.SelectJustThisItem(ItemInfo info, Boolean assumeInItemsCollection)
at System.Windows.Controls.ListBox.MakeSingleSelection(ListBoxItem listItem)
at System.Windows.Controls.ListBox.NotifyListItemClicked(ListBoxItem item, MouseButton mouseButton)
at System.Windows.Controls.ListBoxItem.HandleMouseButtonDown(MouseButton mouseButton)
at System.Windows.Controls.ListBoxItem.OnMouseLeftButtonDown(MouseButtonEventArgs e)
at System.Windows.UIElement.OnMouseLeftButtonDownThunk(Object sender, MouseButtonEventArgs e)
at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
at System.Windows.UIElement.OnMouseDownThunk(Object sender, MouseButtonEventArgs e)
at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
at System.Windows.Input.InputManager.ProcessStagingArea()
at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run(Window window)
at System.Windows.Application.Run()
at FileMunger.App.Main()

Inner Exception 1:
 NullReferenceException: Object reference not set to an instance of an object.

这似乎是由于 prop.GetValue 的值评估为 null,但这是我要测试的。 我意识到这可能会深入到我不是专家的反思中,所以如果有人对如何进行此检查有任何想法,我将不胜感激。 干杯。

【问题讨论】:

  • 您应该尝试访问 InnerException 的堆栈跟踪。这很可能是 MsgReader 中的一个错误。您应该能够通过在它获取之前记录它正在获取的属性来测试它,然后您可以编写相同的代码而不用反射来查看会发生什么。
  • 如果你只想要字符串属性,那么在你知道属性是字符串之前不要调用GetValue。您可以通过prop.PropertyType == typeof(string)查看。
  • 好主意黛西,谢谢你.. 我知道它是哪个属性,所以我会按照你的建议不加思考地尝试它。感谢 Evk,但碰巧的是,失败的属性类型无论如何都是字符串。它是 MailingListHelp 属性。
  • 我基本上在foreach语句前加了一行:var msgmailhelp = msg.MailinglistHelp。它是字符串类型,如果不存在则返回空值。相反,它以 System.NullReferenceException 中断。所以我想我的下一站是 GitHub 问题部分......再次感谢 Daisy。

标签: c# .net wpf windows reflection


【解决方案1】:

我将此标记为答案,以防其他人遇到同样的问题。 MsgReader 库中确实存在错误。我已经在那里提出了这个问题,并且非常友好地提供了一些解决方法。该团队也将修复它,因此希望这只会是短暂的。 You can see the Github thread here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-16
    • 2013-01-10
    相关资源
    最近更新 更多