WCF trace logs all exceptions except System.Exception itself - wcf

I've made a basic WCF Service Library and created one method called GetResult(). I've set up WCF trace logging to log Warnings to a file. This is correctly logging all exceptions thrown except, for some strange reason, System.Exception itself. For instance, this logs fine:
[OperationContract]
public string GetResult()
{
// exception is logged in file:
throw new DivideByZeroException();
// or
// throw new ApplicationException();
// or
// throw new FileNotFoundException();
// or anything else, it seems
}
But this does not log anything:
[OperationContract]
public string GetResult()
{
// exception is not logged!
throw new Exception();
// or
// throw new Exception("my message");
}
In the latter case, the log file doesn't even get created. If it already exists then it doesn't get written to.
What am I doing wrong?
Here is my app.config setup:
<system.diagnostics>
<sources>
<source name="System.ServiceModel.MessageLogging" switchValue="Warning">
<listeners>
<add name="ServiceModelTraceListener" />
</listeners>
</source>
<source name="System.ServiceModel" switchValue="Warning">
<listeners>
<add name="ServiceModelTraceListener" />
</listeners>
</source>
<source name="System.Runtime.Serialization" switchValue="Warning">
<listeners>
<add name="ServiceModelTraceListener" />
</listeners>
</source>
</sources>
<trace autoflush="true" />
<sharedListeners>
<add initializeData="c:\temp\logs\wcf.svclog"
type="System.Diagnostics.XmlWriterTraceListener, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
name="ServiceModelTraceListener"
traceOutputOptions="Timestamp" />
</sharedListeners>
</system.diagnostics>

Related

How can read config file in Net5?

I using Vb.net , FW: Net5
This is my app.config:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="ConnectString" value="DB/Sample.db3" />
</appSettings>
<system.diagnostics>
<sources>
<!-- This section defines the logging configuration for My.Application.Log -->
<source name="DefaultSource" switchName="DefaultSwitch">
<listeners>
<add name="FileLog"/>
<!-- Uncomment the below section to write to the Application Event Log -->
<!--<add name="EventLog"/>-->
</listeners>
</source>
</sources>
<switches>
<add name="DefaultSwitch" value="Information" />
</switches>
<sharedListeners>
<add name="FileLog"
type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"
initializeData="FileLogWriter"/>
<!-- Uncomment the below section and replace APPLICATION_NAME with the name of your application to write to the Application Event Log -->
<!--<add name="EventLog" type="System.Diagnostics.EventLogTraceListener" initializeData="APPLICATION_NAME"/> -->
</sharedListeners>
</system.diagnostics>
</configuration>
I install "System.Configuration.ConfigurationManager" from Nuget
I had try get config as:
Dim str = System.Configuration.ConfigurationManager.AppSettings("ConnectString")
But it occur exception error:
Configuration system failed to initialize
How can read app.config in VB Net5?
I tried using an app.config file in a .NET 5.0 app and I got the same exception. Unlike you, I looked a bit further and saw that it also said that it encountered an unknown section, i.e. system.diagnostics. I then commented out the <system.diagnostics> element in my config file and it worked as expected. I'm not sure what you would do if you actually needed to use that section but it doesn't look like you do so it shouldn't be a problem to comment it out or delete it.

Connection string error between projects with EF

My solution exits out of 3 Projects:
SP_Class_Library contains my EF model
SP_Control_Library is a class library that contains all my custom and
user controls
SP_EF_TEST is my Form Application
I created a custom control cc_User_DropDown with the following code
Protected Overrides Sub OnCreateControl()
MyBase.OnCreateControl()
LoadUsers()
End Sub
Private Sub LoadUsers()
Dim UserList As List(Of SP_User) = Nothing
UserList = (From c In ent.SP_User
Where c.usr_Active = True
Select c
Order By c.usr_Name).ToList
Dim blank As New SP_User
blank.usr_ID = 0
blank.usr_Name = "Please select a user..."
UserList.Insert(0, blank)
Me.DisplayMember = "usr_Name"
Me.ValueMember = "usr_ID"
Me.DataSource = UserList
End Sub
The problem comes when I try and add the custom control to either u_Users or Form1 I get the error:
If I comment the code and build I can add the control, but as soon as I uncomment the code and build I get the following:
I have tried suggestions that say I must add the app.config to all the projects, Copy the connectionstring to all the .config files and remove the .config file from the dll and add it to the Form Application but it does not work.
Here is my app.config file:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
<system.diagnostics>
<sources>
<!-- This section defines the logging configuration for My.Application.Log -->
<source name="DefaultSource" switchName="DefaultSwitch">
<listeners>
<add name="FileLog" />
<!-- Uncomment the below section to write to the Application Event Log -->
<!--<add name="EventLog"/>-->
</listeners>
</source>
</sources>
<switches>
<add name="DefaultSwitch" value="Information" />
</switches>
<sharedListeners>
<add name="FileLog" type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" initializeData="FileLogWriter" />
<!-- Uncomment the below section and replace APPLICATION_NAME with the name of your application to write to the Application Event Log -->
<!--<add name="EventLog" type="System.Diagnostics.EventLogTraceListener" initializeData="APPLICATION_NAME"/> -->
</sharedListeners>
</system.diagnostics>
<connectionStrings>
<add name="SPEntities" connectionString="metadata=res://*/SP_Model1.csdl|res://*/SP_Model1.ssdl|res://*/SP_Model1.msl;provider=System.Data.SqlClient;provider connection string="data source=localhost\SPDEV;initial catalog=SP;persist security info=True;user id=sa;password=xxx;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
</connectionStrings>
<entityFramework>
<defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
<parameters>
<parameter value="v12.0" />
</parameters>
</defaultConnectionFactory>
</entityFramework>
</configuration>

WCF Rest ERR_CONNECTION_RESET not large response

The error code is absolutely terrible, ERR_CONNECTION_RESET has a host of causes and the causes that I found on other questions were related to having too small of a MaxRequestLength for large web service calls. The data I was returning was only a couple of kB though, so this couldn't be the issue.
Here is my interface code
[WebGet(RequestFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.WrappedRequest,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "GetReportByID?ReportID={ReportID}")]
[OperationContract]
UsageReport GetReportByID(int ReportID);
This was the implementation
public UsageReport GetReportByID(int ReportID)
{
return new UsageReport(ReportID);
}
And this was the class code for UsageReport
[DataContract]
public class UsageReport
{
[DataMember]
List<UsageItem> RL;
public UsageReport(int reportID)
{
RL = new List<UsageItem>();
using (SqlDataReader dr = DBUtility.ExecuteReader(cmd, "DBString"))
{
while (dr.Read())
{
ItemNumber = dr["ItemID"] as int? ?? 0;
RL.Add(new UsageItem(ItemNumber));
}
dr.Close();
}
}
public class UsageItem
{
int ItemNumber;
public UsageItem(int ItemNumber)
{
this.ItemNumber = ItemNumber;
}
}
The problem was my UsageItem class, I was missing the necessary DataContract and DataMember fields.
[DataContract]
public class UsageItem
{
[DataMember]
int ItemNumber;
public UsageItem(int ItemNumber)
{
this.ItemNumber = ItemNumber;
}
}
I'd like to add a solution related to a case where WCF is used on the server side:
Add diagnostics to web.config (taken from here):
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.diagnostics>
<sources>
<source name="System.Net" switchValue="Verbose">
<listeners>
<add name="SystemNetTrace"/>
</listeners>
</source>
<source name="System.ServiceModel" switchValue="Verbose, ActivityTracing" propagateActivity="true">
<listeners>
<add name="wcftrace" />
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging" switchValue="Verbose, ActivityTracing">
<listeners>
<add name="wcfmessages" />
</listeners>
</source>
<source name="System.Runtime.Serialization" switchValue="Verbose">
<listeners>
<add name="wcfmessages" />
</listeners>
</source>
</sources>
<sharedListeners>
<add name="SystemNetTrace" type="System.Diagnostics.TextWriterTraceListener" traceOutputOptions="LogicalOperationStack, DateTime, Timestamp, Callstack" initializeData="C:\Traces\System_Net.txt" />
<add name="wcftrace" type="System.Diagnostics.XmlWriterTraceListener" traceOutputOptions="LogicalOperationStack, DateTime, Timestamp, Callstack" initializeData="C:\Traces\WCFTrace.svclog" />
<add name="wcfmessages" type="System.Diagnostics.XmlWriterTraceListener" traceOutputOptions="LogicalOperationStack, DateTime, Timestamp, Callstack" initializeData="C:\Traces\WCFMessages.svclog" />
</sharedListeners>
<trace autoflush="true" />
</system.diagnostics>
</configuration>
Reproduce the error, then go to the trace folder (C:\Traces, in this example). There will be 2 svclog files there: WCFMessages.svclog and WCFTrace.svclog.
Open the file named WCFMessages.svclog. A "Microsoft Service Trace Viewer" window will open, showing errors with a red color.
If no errors are displayed, open WCFTrace.svclog, and the errors (in red) would be there.
In my case, it was a System.Runtime.Serialization error because of a lack of DataContract attribute.

WCF call causing memory leak

We are having problems with a WCF services call that is leaking memory. In our research we think we are calling the service correctly and handling errors that come back from it appropriately. We have even confirmed this with MSDN articles and sample WCF code obtained from a MS web site.
Here is a sample of the code that causes the leak. On the SaveAssociation call, the code on the other side throws an exception. This causes the channel to enter the faulted state. The first catch statement catches the exception (SystemException) and calls Abort() on the client which should immediately abort the session and close the client connection. However, watching this process run this code over and over in a loop we just see the memory used by the process climb and climb.
var client = new FrameworkServiceReference.MAServiceClient();
// Get User domain name
client.ClientCredentials.UserName.UserName = "username";
client.ClientCredentials.UserName.Password = "password";
OperationContextScope a1 = new OperationContextScope(client.InnerChannel);
MessageHeader<string> customHeaderAppID = new MessageHeader<string>("Account Management");
System.ServiceModel.Channels.MessageHeader a2 = customHeaderAppID.GetUntypedHeader("application", "http://www.ma.com");
OperationContext.Current.OutgoingMessageHeaders.Add(a2);
try
{
client.SaveAssociation(association);
client.Close();
}
catch (SystemException se)
{
client.Abort();
}
catch (Exception ex)
{
client.Abort();
}
Here is the error we receiveā€¦
System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail]: Object reference not set to an instance of an object. (Fault Detail is equal to An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is:
System.NullReferenceException: Object reference not set to an instance of an object.
at Multiview.Business.Core.CoreObject.ValidateItem(String Item, String Value)
at Multiview.Business.Core.User.UpdateUser()
at Multiview.Business.Core.User.Save()
at Multiview.Core.ServiceLibrary.MultiviewService.SaveCRMUser(User user, Guid CRMGuid)
at SyncInvokeSaveCRMUser(Object , Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage4(MessageRpc& rpc)
at System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage3(MessageRpc& rpc)
at System.ServiceMode...).
What can be done to stop this leak?
If memory on the server goes up, check the server log. Probably the object you return has a circular reference. This means that when it is returned, the server will throw a stack overflow when serializing the object.
Try to configure your service with:
IncludeExceptionDetailInFaults=true
And create some logs (server and client side):
<system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="Error, ActivityTracing" propagateActivity="true">
<listeners>
<add name="xml" />
</listeners>
</source>
<source name="CardSpace">
<listeners>
<add name="xml" />
</listeners>
</source>
<source name="System.IO.Log">
<listeners>
<add name="xml" />
</listeners>
</source>
<source name="System.Runtime.Serialization">
<listeners>
<add name="xml" />
</listeners>
</source>
<source name="System.IdentityModel">
<listeners>
<add name="xml" />
</listeners>
</source>
</sources>
<sharedListeners>
<add name="xml" type="System.Diagnostics.XmlWriterTraceListener" initializeData="C:\t\mylog.svclog" />
</sharedListeners>
</system.diagnostics>
If you have a problem with memory leaks you should start with some memory profiler and find which objects are living in your memory. That will lead you to the source of leakage.
You can start with the fact that OperationContextScope is disposable.

WCF tracing & message logging - trace level warning

Assume I have a config file which looks like this:
...
<system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="Warning,ActivityTracing" propagateActivity="true">
<listeners>
<add name="ServiceModelTraceListener" />
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="ServiceModelTraceListener" />
</listeners>
</source>
</sources>
<sharedListeners>
<add initializeData="LogServer.svclog" type="System.Diagnostics.XmlWriterTraceListener" name="ServiceModelTraceListener" />
</sharedListeners>
<trace autoflush="true" />
</system.diagnostics>
When using this config file every activity the caller performs against the service and each corresponding message that's sent to the service will be logged in the svclog file. Everything fine so far.
If I modify the 3rd line from the above listing to <source name="System.ServiceModel" switchValue="Warning" propagateActivity="true"> (the ActivityTracing is removed) then only those activities are logged that are at least labeled level warning. But it's still every message logged...
So is there a way to only log those message that correspond to those activities that are at least warnings? Those messages that succeeded aren't very interesting in that moment, but those messages that belong to the unsuccessful activities are!
Edit
To filter messages beyond the options below you may want to look into writing your own TraceSource.
Below is one I am using for a project. You could easily customize it to filter out the messages you want or perhaps hide activity if it is not in DEBUG, etc.
class DB : TraceSource
{
public DB(string name) : base(name)
{
}
public DB(string name, SourceLevels sourceLevels) : base (name, sourceLevels)
{
}
public void Log(object value)
{
WriteLine(value);
}
public void Error(object value)
{
WriteLine(value, TraceEventType.Error);
}
public void Error(RecordingResponseData errorResponse)
{
string errorMessage = "[Error] Code: "+errorResponse.ErrorCode +" Message: "+errorResponse.ErrorMessage;
WriteLine(errorMessage, TraceEventType.Error);
}
public void Warn(object value)
{
WriteLine(value, TraceEventType.Warning);
}
public void WriteLine(object value, TraceEventType type = TraceEventType.Information)
{
TraceEvent(type, 0, value.ToString());
}
}
Original
Your options are:
Critical
Error
Warning
Information
ActivityTracing
Verbose
All
Or a combination there of. If you have it set to Warning but are still getting too many messages then you may want to try Error or Critical.
ref: https://msdn.microsoft.com/en-us/library/ms733025%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
There's a switchValue available for the System.ServiceModel.MessageLogging trace switch as well. Just add that attribe to that source element and set it to Warning also and you will only see messages logged that are related to warnings.
Get rid of System.ServiceModel.MessageLogging source to get rid of logging messages to resolve "still every message logged".