2014-12-16 5 views
3

Привет им пытаются создать пользовательский визуализатор для объекта DbCommand, который должен использоваться в Visual Studio 2013.визуализатора для DbCommand

я не следующий код

using VisualizerTest; 
using Microsoft.VisualStudio.DebuggerVisualizers; 
using System; 
using System.Data.Common; 
using System.Diagnostics; 
using System.IO; 
using System.Runtime.Serialization.Formatters.Binary; 
using System.Windows.Forms; 

[assembly: DebuggerVisualizer(typeof(TestVisualizer), typeof(CommandObjectSource), Target = typeof(DbCommand), Description = "Test")] 

namespace VisualizerTest 
{ 
    public class TestVisualizer : DialogDebuggerVisualizer 
    { 
     protected override void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider) 
     { 
      DbCommand command; 
      try 
      { 
       using (Stream stream = objectProvider.GetData()) 
       { 
        BinaryFormatter formatter = new BinaryFormatter(); 
        command = (DbCommand)formatter.Deserialize(stream); 
       } 
       MessageBox.Show(command.CommandText); 
      } 
      catch(Exception ex) 
      { 
       MessageBox.Show(ex.ToString()); 
      } 
     } 
    } 
} 


namespace VisualizerTest 
{ 
    [Serializable] 
    public class CommandObjectSource : VisualizerObjectSource 
    { 
     public override void GetData(object target, Stream outgoingData) 
     { 
      if (target != null && target is DbCommand) 
      { 
       DbCommand command = (DbCommand)target; 

       BinaryFormatter formatter = new BinaryFormatter(); 

       formatter.Serialize(outgoingData, command); 
      } 
     } 
    } 
} 

Но CommandObjectSource не вызывается и вместо этого я получить исключение

Microsoft.VisualStudio.DebuggerVisualizers.DebugViewerShim.RemoteObjectSourceException: Type 'System.Data.SqlClient.SqlCommand' in Assembly 'System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' is not marked as serializable. 

Мое понимание было то, что с помощью пользовательского VisualizerObjectSource я бы обойти вопрос сериализации?

В качестве боковой заметки я попытался изменить Target = typeof(DbCommand) на Target = typeof(SqlCommand), и это не имело значения.

Код испытания:

class Program 
{ 
    static void Main(string[] args) 
    { 

     using (SqlCommand command = new SqlCommand("SELECT Field1 FROM table WHERE Field2 = @Value1")) 
     { 
      command.Parameters.AddWithValue("@Value1", 1338); 
      TestValue(command); 
     } 

     Console.ReadKey(); 
    } 

    static void TestValue(object value) 
    { 
     VisualizerDevelopmentHost visualizerHost = new VisualizerDevelopmentHost(value, typeof(TestVisualizer)); 
     visualizerHost.ShowVisualizer(); 
    } 
} 

ответ

3

Поскольку вы явно создавая VisualizerDevelopmentHost он не будет использовать DebuggerVisualizerAttribute так что вы должны пройти в вашем CommandObjectSource в качестве третьего параметра:

VisualizerDevelopmentHost visualizerHost = 
    new VisualizerDevelopmentHost(value, typeof(TestVisualizer),     
             typeof(CommandObjectSource)); 

С этим изменится ваш CommandObjectSource, но у вас все еще есть проблема с сериализацией, потому что BinaryFormatter также нуждается в классе, который будет помечен как Seralizabe ...

Таким образом, вы, вероятно, следует только включать CommandText (или создать новый объект DTO и seralize, что если вам нужно несколько свойств) с:

[Serializable] 
public class CommandObjectSource : VisualizerObjectSource 
{ 
    public override void GetData(object target, Stream outgoingData) 
    { 
     if (target != null && target is DbCommand) 
     { 
      DbCommand command = (DbCommand)target; 

      var writer = new StreamWriter(outgoingData); 
      writer.WriteLine(command.CommandText); 
      writer.Flush(); 
     } 
    } 
} 

И читать его:

public class TestVisualizer : DialogDebuggerVisualizer 
{ 
    protected override void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider) 
    { 
     string command; 
     try 
     { 
      command = new StreamReader(objectProvider.GetData()).ReadLine(); 
      MessageBox.Show(command); 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.ToString()); 
     } 
    } 
} 
+0

Ill попробовать это, когда я приступаю к работе, если он работает плохо, так счастлив :) – Peter

+0

Работает как рекламируемое спасибо много! – Peter

Смежные вопросы