I'm seeing some weird behaviour debugging my C# code - I cant post my exact code but essentially I have a partial abstract base class that defines an Execute method:
public abstract partial class MyBase
{
public abstract void Execute();
protect static object SomeMethod()
{
object aaa = OtherClass.GetObject();
// etc...
}
}
I then have another partial class which implements this method, and calls some static methods on the base class:
partial abstract class MyParent : MyBase
{
public void Execute()
{
object myobj = SomeMethod();
// etc...
}
}
Both of these partial classes have are extensions of partial classes generated using xsd.exe from a schema.
What I'm seeing is that if I attempt to step-into my implementation of Execute(), the Visual Stuido debugger jumps through these methods - for example in this case it would step straight through to the OtherClass.GetObject() method. The call stack still shows all the frames inbetween Execute() and OtherClass.GetObject(), and even lets me set them to be the active frame, however I can't do a line-by-line step through the code unless I place a breakpoint on each and every line.
Why is this?
How can I fix it so I can debug normally again!?
xsd.exe typically decorates generated classes with the DebuggerStepThrough attribute, which means the debugger will .. well, you get the picture.
I've dealt with this in the past with a simple .vbs script that I call after invoking xsd.exe (typically as part of a pre-build step):
Const ForReading = 1
Const ForWriting = 2
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objFile = objFSO.OpenTextFile(WScript.Arguments(0), ForReading)
strText = objFile.ReadAll
objFile.Close
strNewText = Replace(strText,
"[System.Diagnostics.DebuggerStepThroughAttribute()]", "")
Set objFile = objFSO.OpenTextFile(WScript.Arguments(0), ForWriting)
objFile.WriteLine strNewText
objFile.Close
You call it with the name of the generated file as a parameter, as in:
wscript.exe remove_attribute.vbs XsdGeneratedClasses.cs
Also, make sure the Just My Code checkbox is unchechedk, just in case.
Related
I have a situation where I need to set oracle session variables/context before read & write events happen (this is a requirement by the client and not negotiable).
Where would be the best place to insert this code? I'm already overriding the DBContext.New() method as well as DBContext.OnModelCreating() for other purposes, but I can't tell if either of them are the true beginning of the entire database session (since EF is stateless...?)
Pretty sure the actual code would be a simple Me.Database.SqlQuery(), just need to be sure of where to put it.
My perceived options:
1
Protected Overrides Sub OnModelCreating(modelBuilder As DbModelBuilder)
[Other Code]
MyBase.OnModelCreating(modelBuilder)
Me.Database.ExecuteSqlCommand("SESSIONCOMMAND")
End Sub
2
Using CTX As New MyContext()
CTX.Database.ExecuteSqlCommand("SESSIONCOMMAND")
[OTHER CODE]
End Using
3
Public Sub New()
MyBase.New(
New OracleConnection(
ConfigurationManager.ConnectionStrings("MyContext").ConnectionString),
True)
Me.Database.ExecuteSqlCommand("SESSIONCOMMAND")
End Sub
I'm pretty sure #3 is not possible because EF opens the connection after this sub, so I can't execute a command against it yet at this point.
You could try doing it when the connection state changed from closed to open. Like this...
public partial class MyContext : DbContext
{
public MyContext()
{
this.Database.Connection.StateChange += Connection_StateChange;
}
void Connection_StateChange( object sender, System.Data.StateChangeEventArgs e )
{
if ( e.CurrentState == System.Data.ConnectionState.Open )
{
if ( sender is System.Data.Common.DbConnection )
{
var command = ( sender as System.Data.Common.DbConnection ).CreateCommand();
command.CommandText = "SESSIONCOMMAND";
command.CommandType = System.Data.CommandType.Text;
command.ExecuteNonQuery();
}
}
}
I have a simple outlook ribbon with an editBox. Once the user clicks the send button, I capture the string in the editBox and use it in the Application_ItemSend..
My problem is, after the function is done, I want to RESET the UI of the ribbon (just the editBox) so that the user won't have the previously typed string in the same box when opening up a new message screen. I tried the Ribbon.Invalidate but I can't seem to get rid of that string value. When I re-open the "New Email" screen, the old value is still there.
Here is the code:
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui" onLoad="Ribbon_Load_2010">
<ribbon>
<tabs>
<tab idMso="TabNewMailMessage">
<group id="TaskManager" insertBeforeMso="GroupSend" label="Task Manager">
<editBox id="editboxTaskID" label="Task ID #: " onChange="editboxTaskID_OnChange"
imageMso="RecordsAddFromOutlook" sizeString="wwwwww"/>
</group>
</tab>
</tabs>
</ribbon>
</customUI>
And the VB Code:
<Runtime.InteropServices.ComVisible(True)> _
Public Class CustomRibbon
Implements Office.IRibbonExtensibility
Private ribbon As Office.IRibbonUI
Public strTask_ID As String = ""
Public Sub New()
End Sub
Public Function GetCustomUI(ByVal ribbonID As String) As String Implements Office.IRibbonExtensibility.GetCustomUI
Return GetResourceText("Addin.Ribbon.xml")
End Function
Private Sub Application_ItemSend(ByVal Item As Object, ByRef Cancel As Boolean)
Me.ribbon.Invalidate()
Try
'SOME CODE HERE WHICH WORKS FINE!
Catch ex As Exception
End Try
End Sub
'Create callback methods here. For more information about adding callback methods, select the Ribbon XML item in Solution Explorer and then press F1.
Public Sub Ribbon_Load_2010(ByVal ribbonUI As Office.IRibbonUI)
Me.ribbon = ribbonUI
AddHandler Globals.ThisAddIn.Application.ItemSend, AddressOf Application_ItemSend
End Sub
Public Sub editboxTaskID_OnChange(ByVal control As Office.IRibbonControl, ByVal Text As String)
strTask_ID = Text
End Sub
Public Sub AttachmentRibonClick(ByVal control As Microsoft.Office.Core.IRibbonControl)
Globals.ThisAddIn.TriggerTaskWindow("Attachment")
End Sub
Private Shared Function GetResourceText(ByVal resourceName As String) As String
Dim asm As Reflection.Assembly = Reflection.Assembly.GetExecutingAssembly()
Dim resourceNames() As String = asm.GetManifestResourceNames()
For i As Integer = 0 To resourceNames.Length - 1
If String.Compare(resourceName, resourceNames(i), StringComparison.OrdinalIgnoreCase) = 0 Then
Using resourceReader As IO.StreamReader = New IO.StreamReader(asm.GetManifestResourceStream(resourceNames(i)))
If resourceReader IsNot Nothing Then
Return resourceReader.ReadToEnd()
End If
End Using
End If
Next
Return Nothing
End Function
End Class
The invalidate method is used to signal that a control has been updated and needs to be re-rendered on the screen. It will not clear data from a control. What you need to do is set the property on the control (the edit box in this case) that stores the offending string value to an empty string.
Ok, I figured it out.
Apparently after you invalidate the controls, you need to use GetText function of the Editbox to init the value.
Public Function editboxTaskID_GetText(ByVal control As Office.IRibbonControl) As String
Return ""
End Function
I also noticed other sites use different signature for the function - which does not work. I believe Microsoft changed this from a Sub to a Function when moving to 2010 Interop.
I wish Microsoft had better documentation for this.
Happy programming!
Im trying to create a windows service with vb.net but when I run:
InstallUtil.exe myservice.exe
I'm getting the following error in the MyService.InstallLog file:
Restoring event log to previous state for source DebtorInvoiceMailingService.
An exception occurred during the Rollback phase of the System.Diagnostics.EventLogInstaller installer.
System.Security.SecurityException: The source was not found, but some or all event logs could not be searched. Inaccessible logs: Security.
An exception occurred during the Rollback phase of the installation. This exception will be ignored and the rollback will continue. However, the machine might not fully
DebtorInvoiceMailingService.vb
Imports System.ServiceProcess
Imports System.Timers
Public Class DebtorInvoiceMailingService
Inherits ServiceBase
Private _timer As Timer
Private _lastRun As DateTime = DateTime.Now
Private _notificationsManager As Notifications
Public Sub New()
Me.ServiceName = "DebtorInvoiceMailingService"
End Sub
'When service starts
Protected Overrides Sub OnStart(ByVal args() As String)
MyBase.OnStart(args)
'This object will do what im looking for (monitore a folder)
Me._notificationsManager = New Notifications
Me._timer = New Timer
'Service will be executed every 24 hours
Me._timer.Interval = 1000 * 60 * 60 * 24
Me._timer.Enabled = True
'Service will execute timer_Elapsed()
AddHandler Me._timer.Elapsed, AddressOf timer_Elapsed
End Sub
'When service stops
Protected Overrides Sub OnStop()
MyBase.OnStop()
Me._timer.Dispose()
End Sub
'Function executed every 24 hours
Private Sub timer_Elapsed(ByVal sender As Object, ByVal e As ElapsedEventArgs)
If (Me._lastRun.Date > DateTime.Now.Date) Then
Me._timer.Stop()
'You have to stop your timer because if the task that you
'are about to perform takes longer than the timer.interval
'the task will be executed multiple times
Me._notificationsManager.execute() 'this function will send an email
Me._lastRun = DateTime.Now
Me._timer.Start()
End If
End Sub
Shared Sub Main()
ServiceBase.Run(New DebtorInvoiceMailingService)
End Sub
End Class
ProjectInstaller.vb
Imports System
Imports System.ServiceProcess
Imports System.ComponentModel
Imports System.Configuration.Install
<RunInstallerAttribute(True)> _
Public Class ProjectInstaller
Inherits System.Configuration.Install.Installer
Public WithEvents ServiceProcessInstaller1 As ServiceProcessInstaller
Public WithEvents ServiceInstaller1 As ServiceInstaller
Public Sub New()
MyBase.New()
Me.ServiceProcessInstaller1 = New ServiceProcessInstaller()
Me.ServiceInstaller1 = New ServiceInstaller()
'ServiceProcessInstaller1
Me.ServiceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem
Me.ServiceProcessInstaller1.Password = Nothing
Me.ServiceProcessInstaller1.Username = Nothing
'ServiceInstaller1
Me.ServiceInstaller1.Description = "Auto mailing invoices to debtors every 24 hours."
Me.ServiceInstaller1.DisplayName = "DebtorInvoiceMailingService"
Me.ServiceInstaller1.ServiceName = "DebtorInvoiceMailingService"
Me.ServiceInstaller1.StartType = ServiceStartMode.Manual
'ProjectInstaller
Me.Installers.Add(Me.ServiceProcessInstaller1)
Me.Installers.Add(Me.ServiceInstaller1)
End Sub
Please Can someone help me? Thanks :)
Be sure to run the InstallUtil from a command windows launched "As Administrator".
I'm trying to do an HTML Extension to render my telerik grid with the common settings
If I declare this code into a view everything its fine.
#imports Telerik.Web.Mvc
#imports Telerik.Web.Mvc.UI
#Code
Dim gridBuilder As Telerik.Web.Mvc.UI.Fluent.GridBuilder(Of TModel) =
Html.Telerik().Grid(Of TModel)().Name("myList")
#End Code
But I move it into a class library project to implement an HTML extension
Imports System.Web.Mvc
Imports Telerik.Web.Mvc
Imports Telerik.Web.Mvc.UI
Namespace Helpers
Module HelperList
<System.Runtime.CompilerServices.Extension()> _
Public Sub myTelerikList(Of TModel As Class)(helper As HtmlHelper)
Dim gridBuilder As Telerik.Web.Mvc.UI.Fluent.GridBuilder(Of TModel) = Html.Telerik().Grid(Of TModel)().Name("myList")
…
…
End Sub
I'm having an error like that
'Html' is ambiguous, imported from the
namespaces or types
'Telerik.Web.Mvc.UI, System.Web.Mvc'.
Try using the helper instance which you are extending:
<System.Runtime.CompilerServices.Extension()> _
Public Sub myTelerikList(Of TModel As Class)(helper As HtmlHelper)
Dim gridBuilder As Telerik.Web.Mvc.UI.Fluent.GridBuilder(Of TModel) = helper.Telerik().Grid(Of TModel)().Name("myList")
...
End Sub
Since your HtmlHelper instance is named helper, you need to write helper.Telerik().
I can't figure this out as I go through demos that seem to work. I have a WCF service I was trying to use Linq to SQL with. However, all I ever get is the error System.Data.Linq.Table cannot be serialized. So I started with my own class thinking I could build it back up until get the error. Problem is I get the error even trying to use an empty class. Just using the "As System.Linq.Table(Of xxx)" on my method gives me this error.
Type 'System.Data.Linq.Table`1[LinqADMRequest2b]' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. See the Microsoft .NET Framework documentation for other supported types.
Imports System.ServiceModel
Imports System.ServiceModel.Activation
Imports System.Runtime.Serialization
Imports System.Collections.Generic
Imports Linq
<ServiceContract(Namespace:="")> _
<ServiceBehavior(IncludeExceptionDetailInFaults:=True)> _
<AspNetCompatibilityRequirements(RequirementsMode:=AspNetCompatibilityRequirementsMode.Allowed)> _
Public Class ComplyTrackWCFService
_
Public Function GetTestRequests() As System.Data.Linq.Table(Of LinqADMRequest2b)
'Dim ct As New Linq2.ComplyTrackDataContext()
'Dim queryresults = ct.ADMRequests 'ct.ADMRequestGetListByUser("", "155")
'Return queryresults
End Function
End Class
<DataContract()> _
<Serializable()> _
Public Class LinqADMRequest2b
Implements ISerializable
Private _firstName As String
_
Public Property FirstName() As String
Get
Return _firstName
End Get
Set(ByVal Value As String)
_firstName = Value
End Set
End Property
Public Sub GetObjectData(ByVal info As System.Runtime.Serialization.SerializationInfo, ByVal context As System.Runtime.Serialization.StreamingContext) Implements System.Runtime.Serialization.ISerializable.GetObjectData
End Sub
End Class
As you can see the GetTestRequests() doesn't do anything other then say it's going to return a System.Data.Linq.Table(Of LinqADMRequest2b)
I can't get the LinqADMRequest2b to serialize.
Type 'System.Data.Linq.Table`1[LinqADMRequest2b]' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. See the Microsoft .NET Framework documentation for other supported types.
Don't return Table<T> from your service. It's a complex queryable type that depends on its DataContext and isn't an in-memory collection.
Do return List<T>, you can convert the Table<T> to a List<T> by calling System.Linq.Enumerable.ToList().
Try putting
<DataMember> attribute on your properties of you own class.
Also, it's better to create lightweight DataContract object to pass down the line rather than big bulky dude like the linq table.