Memory leak in Moq? - moq

I found this while attempting to find a memory leak in my code. I kept isolating more and more of my code and still leaking memory.
public interface IClient
{
Task<List<string>> GetNothing();
}
public class Client : IClient
{
public async Task<List<string>> GetNothing()
{
//await Task.Delay(1); // appears to have no effect on memory usage
return new List<string> { "I am", "Client" };
}
}
public interface IService
{
Task<List<string>> DoNothing();
}
public class Service : IService
{
private IClient client;
public Service(IClient client)
{
this.client = client;
}
public async Task<List<string>> DoNothing()
{
return await client.GetNothing();
}
}
[TestFixture]
public class MoqTests
{
[Test]
public async Task Memory_leak_test1()
{
IClient client = new Client();
Service service = new Service(client);
while (true)
{
await service.DoNothing(); // runs indefinitely
}
}
[Test]
public async Task Memory_leak_test2()
{
Mock<IClient> clientMock = new Mock<IClient>();
clientMock.Setup(x => x.GetNothing()).ReturnsAsync(new List<string> { "I am", "a mock" });
Service service = new Service(clientMock.Object);
while (true)
{
//create a little busy work in the loop... appears to have no effect
Guid g = new Guid();
var z = Math.Sqrt(50670780805d);
//await Task.Delay(1); // uncomment this line else out of memory in ~ 2 mins.
await service.DoNothing();
}
}
}
Dependencies
<ItemGroup>
<Reference Include="Autofac, Version=4.7.1.0, Culture=neutral, PublicKeyToken=17863af14b0044da, processorArchitecture=MSIL">
<HintPath>..\packages\Autofac.4.7.1\lib\net45\Autofac.dll</HintPath>
</Reference>
<Reference Include="Castle.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=407dd0808d44fbdc, processorArchitecture=MSIL">
<HintPath>..\packages\Castle.Core.4.2.1\lib\net45\Castle.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.DotNet.InternalAbstractions, Version=1.0.500.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.DotNet.InternalAbstractions.1.0.500-preview2-1-003177\lib\net451\Microsoft.DotNet.InternalAbstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.DotNet.PlatformAbstractions, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.DotNet.PlatformAbstractions.2.1.0-preview1-26216-03\lib\net45\Microsoft.DotNet.PlatformAbstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.EntityFrameworkCore, Version=2.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.EntityFrameworkCore.2.0.2\lib\netstandard2.0\Microsoft.EntityFrameworkCore.dll</HintPath>
</Reference>
<Reference Include="Microsoft.EntityFrameworkCore.Design, Version=2.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.EntityFrameworkCore.Design.2.0.2\lib\net461\Microsoft.EntityFrameworkCore.Design.dll</HintPath>
</Reference>
<Reference Include="Microsoft.EntityFrameworkCore.Relational, Version=2.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.EntityFrameworkCore.Relational.2.0.2\lib\netstandard2.0\Microsoft.EntityFrameworkCore.Relational.dll</HintPath>
</Reference>
<Reference Include="Microsoft.EntityFrameworkCore.SqlServer, Version=2.0.2.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.EntityFrameworkCore.SqlServer.2.0.2\lib\netstandard2.0\Microsoft.EntityFrameworkCore.SqlServer.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Caching.Abstractions, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Caching.Abstractions.2.1.0-preview1-final\lib\netstandard2.0\Microsoft.Extensions.Caching.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Caching.Memory, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Caching.Memory.2.1.0-preview1-final\lib\netstandard2.0\Microsoft.Extensions.Caching.Memory.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Configuration, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Configuration.2.1.0-preview1-final\lib\netstandard2.0\Microsoft.Extensions.Configuration.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Configuration.Abstractions, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Configuration.Abstractions.2.1.0-preview1-final\lib\netstandard2.0\Microsoft.Extensions.Configuration.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Configuration.Binder, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Configuration.Binder.2.1.0-preview1-final\lib\netstandard2.0\Microsoft.Extensions.Configuration.Binder.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Configuration.FileExtensions, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Configuration.FileExtensions.2.1.0-preview1-final\lib\netstandard2.0\Microsoft.Extensions.Configuration.FileExtensions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Configuration.Json, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Configuration.Json.2.1.0-preview1-final\lib\netstandard2.0\Microsoft.Extensions.Configuration.Json.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.DependencyInjection, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.DependencyInjection.2.1.0-preview1-final\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.DependencyInjection.Abstractions, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.DependencyInjection.Abstractions.2.1.0-preview1-final\lib\netstandard2.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.DependencyModel, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.DependencyModel.2.1.0-preview1-26216-03\lib\net451\Microsoft.Extensions.DependencyModel.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.FileProviders.Abstractions, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.FileProviders.Abstractions.2.1.0-preview1-final\lib\netstandard2.0\Microsoft.Extensions.FileProviders.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.FileProviders.Physical, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.FileProviders.Physical.2.1.0-preview1-final\lib\netstandard2.0\Microsoft.Extensions.FileProviders.Physical.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.FileSystemGlobbing, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.FileSystemGlobbing.2.1.0-preview1-final\lib\netstandard2.0\Microsoft.Extensions.FileSystemGlobbing.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Logging.2.1.0-preview1-final\lib\netstandard2.0\Microsoft.Extensions.Logging.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Logging.Abstractions.2.1.0-preview1-final\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging.Configuration, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Logging.Configuration.2.1.0-preview1-final\lib\netstandard2.0\Microsoft.Extensions.Logging.Configuration.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging.Console, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Logging.Console.2.1.0-preview1-final\lib\netstandard2.0\Microsoft.Extensions.Logging.Console.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Options, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Options.2.1.0-preview1-final\lib\netstandard2.0\Microsoft.Extensions.Options.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Options.ConfigurationExtensions, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Options.ConfigurationExtensions.2.1.0-preview1-final\lib\netstandard2.0\Microsoft.Extensions.Options.ConfigurationExtensions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Primitives, Version=2.1.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Primitives.2.1.0-preview1-final\lib\netstandard2.0\Microsoft.Extensions.Primitives.dll</HintPath>
</Reference>
<Reference Include="Moq, Version=4.8.0.0, Culture=neutral, PublicKeyToken=69f491c39445e920, processorArchitecture=MSIL">
<HintPath>..\packages\Moq.4.8.2\lib\net45\Moq.dll</HintPath>
</Reference>
<Reference Include="MySqlConnector, Version=0.38.0.0, Culture=neutral, PublicKeyToken=d33d3e53aa5f8c92, processorArchitecture=MSIL">
<HintPath>..\packages\MySqlConnector.0.38.0\lib\net46\MySqlConnector.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.11.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="nunit.framework, Version=3.10.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\packages\NUnit.3.10.1\lib\net45\nunit.framework.dll</HintPath>
</Reference>
<Reference Include="Pomelo.EntityFrameworkCore.MySql, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Pomelo.EntityFrameworkCore.MySql.2.0.1\lib\netstandard2.0\Pomelo.EntityFrameworkCore.MySql.dll</HintPath>
</Reference>
<Reference Include="Pomelo.JsonObject, Version=1.1.1.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Pomelo.JsonObject.1.1.1\lib\net451\Pomelo.JsonObject.dll</HintPath>
</Reference>

The Garbage collector just isn't getting the opportunity to collect things. I wrapped this up in a program like this...
public class Program
{
static void Main(string[] args)
{
new MoqTests().Memory_leak_test2().GetAwaiter().GetResult();
}
}
and watched the memory usage, and like you said, for test1 the memory usage stays absolutely flat. For test2, it just keeps climbing. However, if you add GC.Collect(); in test2 on the line before await service.DoNothing();, then the memory usage stays flat. So it's not leaking memory. (If it was leaking, then the garbage collector wouldn't be able to collect it.) Hope this helps.

Related

Web API 2 EnableCors not working when I post data with DHC Chrome extension

I am developing a Web API 2 project and I using EnableCors attribute like this:
Controller:
[EnableCors(origins: "http://localhost:32454, http://localhost:25234", headers: "*", methods: "POST")]
WebApiConfig:
config.EnableCors();
Web.config:
<system.webServer>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
When I am posting data to my Web API via DHC Chrome extension, my controller is working fine. But, I set two origin. I don't want to access my Web API via DHC. Because, I didn't allow it.
What should I do?
I usually use Owin with Web Api and this should resolve:
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
var config = new HttpConfiguration();
WebApiConfig.Register(config);
ConfigureOAuth(app);
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
app.UseWebApi(config);
}
}

404 when WebAPI 2 Controller is called

i have developed a simple WebAPI 2 Controller with only one Controller and some simple GET Methods. I have created for this a Visual Studio 2015 Emtpy ASP.Net Web Application and added a WebAPI 2 Controller to it.
I have published it to a Windows 2012 R2 Machine with IIS 8.5 and ASP.Net 4.0 installed on it. It has thelatest updates etc.
When i call the Method from a browser i get an error 404 - 0x80070002 Notification: MapRequestHandler
You can download my solution here: VS2015 WebAPI2 Solution
This is the error message:
This is my webapplication:
These are the handlers:
This is the WebApplication configuration:
This is the Application Pool configuration:
These are the ISAPI filters:
Has anybody an idea about the possible reason why this it not working?
This is my controller:
using System.Collections.Generic;
using System.Web.Http;
namespace WebApi2Routes1.Controllers
{
// [Controller wird api/Default in diesem Fall genommen, also Controller Name ohne 'Controller'
[RoutePrefix("api/[controller]")]
public class BuecherController : ApiController
{
// GET: api/buecher/default
// [HttpGet]
[Route("")]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET: api/buecher/show
[Route("show")]
public string Show()
{
return "Show";
}
[Route("value/{id:int}")]
public string GetValue(int id)
{
return "value" + id.ToString();
}
}
}
This is my web.config
<?xml version="1.0" encoding="utf-8"?>
<!--
Weitere Informationen zum Konfigurieren Ihrer ASP.NET-Anwendung finden Sie unter
http://go.microsoft.com/fwlink/?LinkId=301879
-->
<configuration>
<appSettings></appSettings>
<system.web>
<compilation debug="true" targetFramework="4.5.2"/>
<httpRuntime targetFramework="4.5.2"/>
</system.web>
<system.webServer>
<modules>
<remove name="UrlRoutingModule-4.0" />
<add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" preCondition="" />
</modules>
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0"/>
<remove name="OPTIONSVerbHandler"/>
<remove name="TRACEVerbHandler"/>
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler"
preCondition="integratedMode,runtimeVersionv4.0"/>
</handlers>
</system.webServer>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0"/>
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35"/>
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs"
type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701"/>
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb"
type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+"/>
</compilers>
</system.codedom>
</configuration>
I this is the url which throws the error:
http://localhost:8080/api/buecher
and
http://localhost:8080/api/buecher/show
Update 1:
I also have a global.asax
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Routing;
namespace WebApi2Routes1
{
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
}
}
}
and a WebApiConfig.cs
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Formatting;
using System.Web.Http;
namespace WebApi2Routes1
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web-API-Konfiguration und -Dienste
// Web-API-Routen
config.MapHttpAttributeRoutes();
// var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
// jsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
}
}
}
Solved by myself. There where two issues:
[RoutePrefix("api/[controller]")]
[controller] as a token does not work! You have to replace it with a static string like "books" or anything else.
The second issue was that methods need an explicite HHTPGET or HTTPPOST etc. This does not work
[Route("show")]
public string Show()
{
return "Show";
}
This works
[Route("show")]
[HttpGet]
public string show()
{
return "Show";
}
Only if the Method itself is called Get() or Post() or ... then there is no need for [HttpGet].
After replacing the [controller] token in RoutePrefix by a static value and adding [HTTPGET] to the method it worked!

Implementing Rolling log file in ASP.NET and EntLib 5.0

I am using EntLib 5 to create rolling flat file. This does not use the Rolling Flat File trace listener but the Flat File Trace listener with some modifications in the code.
Rolling Flat File trace listener was not used becuase of issues with it's inherent design as such does not fit the requirement here.
Here is the configuration section:
<configuration>
<configSections>
<section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true"/>
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="Everywhere"/>
<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
<section name="roleService" type="System.Web.Configuration.ScriptingRoleServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" allowDefinition="MachineToApplication"/>
</sectionGroup>
</sectionGroup>
</sectionGroup>
</configSections>
<loggingConfiguration name="" tracingEnabled="true" defaultCategory="General">
<listeners>
<add name="Flat File Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
fileName="./Logs/MyLog.log" formatter="Text Formatter" />
</listeners>
<formatters>
<add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
template="Timestamp: {timestamp(local)}{newline}
Message: {message}{newline}
Category: {category}{newline}
Priority: {priority}{newline}
EventId: {eventid}{newline}
Severity: {severity}{newline}
Title:{title}{newline}
Machine: {localMachine}{newline}
App Domain: {localAppDomain}{newline}
ProcessId: {localProcessId}{newline}
Process Name: {localProcessName}{newline}
Thread Name: {threadName}{newline}
Win32 ThreadId:{win32ThreadId}{newline}
Extended Properties: {dictionary({key} - {value}{newline})}"
name="Text Formatter" />
</formatters>
<categorySources>
<add switchValue="All" name="General">
<listeners>
<add name="Flat File Trace Listener" />
</listeners>
</add>
</categorySources>
<specialSources>
<allEvents switchValue="All" name="All Events" />
<notProcessed switchValue="All" name="Unprocessed Category" />
<errors switchValue="All" name="Logging Errors & Warnings">
<listeners>
<add name="Flat File Trace Listener" />
</listeners>
</errors>
</specialSources>
</loggingConfiguration>
<appSettings>
<add key="LogFolder" value="./Logs"/>
<add key="LogFileName" value="MyLog.log"/>
</appSettings>
<system.web>
Then I create a static class with the following code to configure the logging process:
public static class LoggingHelper {
private static string date = String.Format(System.Globalization.CultureInfo.InvariantCulture, "{0:yyyyMMdd}", DateTime.Now);
public static void SetLogFile(string logFileFolder,string logFileName) {
if (!string.IsNullOrEmpty(logFileName)) {
string strfileName = logFileFolder + "/" + date + logFileName;
LoggingHelper.SetTraceLogPath(strfileName, "FlatFile TraceListener", "General", "My Login System");
LoggingHelper.WriteLogFile("General", "Log file path " + logFileFolder + "/" + logFileName, " My Login System");
}
}
public static void SetTraceLogPath(string logFile, string logFileName, string category, string message) {
ConfigurationFileMap configFileMap = new ConfigurationFileMap();
configFileMap.MachineConfigFilename = "Web.config";
Configuration entLibConfig = WebConfigurationManager.OpenWebConfiguration("/ASP.NET_Logging");
LoggingSettings loggingSettings = (LoggingSettings)entLibConfig.GetSection(LoggingSettings.SectionName);
FlatFileTraceListenerData data = loggingSettings.TraceListeners.Get("Flat File Trace Listener") as FlatFileTraceListenerData;
data.FileName = logFile;
entLibConfig.Save();
LogEntry objLog = new LogEntry();
objLog.TimeStamp = System.DateTime.Now;
objLog.Categories.Add(category);
objLog.Message = message;
objLog.Priority = 1;
Logger.Write(objLog);
}
public static void WriteLogFile(string category, string msg, string title) {
try {
LogEntry le = new LogEntry();
le.TimeStamp = System.DateTime.Now;
le.Categories.Add(category);
le.Severity = TraceEventType.Information;
le.Priority = 1;
le.Message = msg;
le.Title = title;
le.Priority = 1;
Logger.Write(le);
} catch (LoggingException ex) {
LoggingHelper.WriteLogFile("General", "Error in writing log file " + ex.ToString(), "My Login System");
}
}}
The SetLogFile is called in the Application_Start method is Global.aspx page like so:
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
LoggingHelper.SetLogFile(ConfigurationSettings.AppSettings["LogFolder"].Trim (), ConfigurationSettings.AppSettings["LogFileName"].Trim());
LoggingHelper.WriteLogFile("General", "*** Application_Start ***", "");
}
Then I just call the WriteLogFile method wherever logging is required like so:
protected void btn_Page2_Click(object sender, EventArgs e) {
LoggingHelper.WriteLogFile("General", "btn_Page2_Click on Default.aspx", "");
Response.Redirect("SecongPage.aspx");
}
This works fine but for a minor issue. When the webpage is accessed for the first time it does not create the log file with Logfilename.log format, it just creates MyLog.log or whatever name is specified in Web.config and the log file is created outside the specified folder, in this case 'Log', for the first time. For consequent requests it will create the desired file with the desired filename in the configured folder.
This pattern is repeated on daily basis, the next day for the first request, the log will be written in yesterday's file and from the next request onwards a new file with today's date is created and all the log messages will be written in that file.
What did I do in my code which is causing this to happen?
We use the above code, with minor changes, for logging in our WinForms applications with no issues.
The website is currently not deployed at IIS. Since it's a work in progress, we are using the built-in development server from VS 2008. Another casue of concern is that the code tries to update the Web.config, at leat once, during startup. Don't know if this is the way to go about it!
This is a very simple sample with two pages, the first page has a button when clicked directs to second page. I am trying to have log file implemented on daily basis and the Rolling Flat File that comes with EntLib does not fit the requirement as it will not create a file on daily basis with the required date for that day.
Regards.
after searching for a long time. This is what I came up with. The idea is to use a FlatFile Trace listner instead of the in-build Rolling Flat File.
Disclaimer:
One of my colleagues had this code with him, he does not remember from where he got it, so if you are the owner or have written code similar to this, then thanks to you.
Please don't vote for this answer as I am not the owner of it. Nevertheless it's here to help anyone looking for similar implementation
This uses EntLib 4, but can be used with EntLib 5 as well.
Here is the logging part from my Web.config:
<loggingConfiguration name="Logging Application Block" tracingEnabled="true"
defaultCategory="User" logWarningsWhenNoCategoriesMatch="true">
<listeners>
<add fileName="trace.log" header="----------------------------------------"
footer="----------------------------------------" formatter=""
listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
traceOutputOptions="None" filter="All" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="FlatFile TraceListener" />
<add fileName="MyLoggingSystem.log" header="" footer="" formatter="Text Formatter"
listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
traceOutputOptions="None" filter="All" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="MyLoggingApp FlatFile TraceListener " />
<add listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.WmiTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
traceOutputOptions="None" filter="All" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.WmiTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="WMI TraceListener" />
</listeners>
<formatters>
<add template="[{timestamp}] [{category}] {message}" type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="Text Formatter" />
</formatters>
<categorySources>
<add switchValue="All" name="Developer">
<listeners>
<add name="FlatFile TraceListener" />
</listeners>
</add>
<add switchValue="All" name="General" />
<add switchValue="All" name="Instrumentation">
<listeners>
<add name="WMI TraceListener" />
</listeners>
</add>
<add switchValue="All" name="EskoLoggingApp">
<listeners>
<add name="MyLogging FlatFile TraceListener " />
</listeners>
</add>
<add switchValue="All" name="User">
<listeners>
<add name="FlatFile TraceListener" />
</listeners>
</add>
</categorySources>
<specialSources>
<allEvents switchValue="All" name="All Events" />
<notProcessed switchValue="All" name="Unprocessed Category" />
<errors switchValue="All" name="Logging Errors & Warnings">
<listeners>
<add name="FlatFile TraceListener" />
</listeners>
</errors>
</specialSources>
</loggingConfiguration>
I have two more sections, file name and folder to save the file:
<appSettings>
<add key="LogFolder" value="./Logs" />
<add key="LogFileName" value="MyLoginSystem" />
</appSettings>
Create a class like so:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using System.Diagnostics;
using System.Globalization;
using Microsoft.Practices.EnterpriseLibrary.Logging.Formatters;
using Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners;
using Microsoft.Practices.EnterpriseLibrary.Logging.Filters;
/// <summary>
/// Summary description for Utility
/// </summary>
public static class Utility {
/// <summary>
/// Instance for log writer
/// </summary>
private static LogWriter writer;
/// <summary>
/// Instance for log writer
/// </summary>
private static LogWriter wmiWriter;
/// <summary>
/// Instance for log writer
/// </summary>
private static LogWriter eskoLoggingWriter;
/// <summary>
/// Intialize the Trace listners without using app.config file
/// </summary>
/// <param name="fileName">log file name</param>
public static void Initialize(string fileName) {
CreateLogWriterFromCode(fileName);
}
/// <summary>
/// Log User Messages
/// </summary>
/// <param name="message">Message text</param>
/// <param name="prior">Logger Priority</param>
/// <param name="traceType">Trave event type</param>
public static void LogUserMessage(string message, int prior, System.Diagnostics.TraceEventType traceType) {
LogEntry(message, "User", prior, traceType);
}
/// <summary>
/// Any type of Log Entry
/// </summary>
/// <param name="message">Message text</param>
/// <param name="category">Logger category</param>
/// <param name="prior">Priory logger </param>
/// <param name="traceType">Trace event type</param>
public static void LogEntry(string message, string category, int prior, System.Diagnostics.TraceEventType traceType) {
try {
LogEntry log = null;
log = new LogEntry();
log.Message = message;
log.Categories.Add(category);
log.Severity = traceType;
log.Priority = prior;
log.TimeStamp = DateTime.Now;
if (writer != null) {
writer.Write(log);
} else {
eskoLoggingWriter.Write(log);
}
// wmiWriter.Write(log);
} catch (LoggingException ex) {
LogEntry(ex.Message, "Developer", prior, traceType);
}
}
/// <summary>
/// Log Developer Messages
/// </summary>
/// <param name="message">Message text</param>
/// <param name="prior">Logger priority</param>
/// <param name="traceType">Trace event type</param>
public static void LogDeveloperMessage(string message, int prior, System.Diagnostics.TraceEventType traceType) {
LogEntry(message, "Developer", prior, traceType);
}
/// <summary>
/// Close splash screen
/// </summary>
public static void ExitSplash() {
Logger.Reset();
}
/// <summary>
/// Disposing log write instance
/// </summary>
public static void Dispose() {
if (writer != null) {
writer = null;
}
}
/// <summary>
/// Creating log writer programatically
/// </summary>
/// <param name="fileName">Full path of log file</param>
static private void CreateLogWriterFromCode(string fileName) {
if (writer != null) {
writer = null;
}
//// The formatter is responsible for the look of the message. Notice the tokens: {timestamp}, {newline}, {message}, {category}
TextFormatter formatter = new TextFormatter
("[{timestamp}]" + "[{category}]" + "{message}{newline}");
//// Log messages to a log file. Use the formatter mentioned above specified.
FlatFileTraceListener logFileListener = new FlatFileTraceListener(fileName, "", "", formatter);
//// My collection of TraceListeners.
LogSource mainLogSource =
new LogSource("FlatFile TraceListener", SourceLevels.All);
mainLogSource.Listeners.Add(logFileListener);
//// Assigning a non-existant LogSource for Logging Application Block
//// Specials Sources I don't care about.Used to say "don't log".
LogSource nonExistantLogSource = new LogSource("Empty");
//// I want all messages with a category of "User" or "Developer" to get distributed
//// to all TraceListeners in my mainLogSource.
IDictionary<string, LogSource> traceSources =
new Dictionary<string, LogSource>();
traceSources.Add("User", mainLogSource);
traceSources.Add("Developer", mainLogSource);
// Let's glue it all together.
// No filters at this time.
// I won't log a couple of the Special
// Sources: All Events and Events not
// using "Error" or "Debug" categories.
writer = new LogWriter(new ILogFilter[0],
traceSources,
nonExistantLogSource,
nonExistantLogSource,
mainLogSource,
"ALL",
false,
true);
}
/// <summary>
/// Creating log writer programatically
/// </summary>
static public void CreateLogWriterFromCode(string folder, string fileName) {
if (eskoLoggingWriter == null) {
//// The formatter is responsible for the look of the message. Notice the tokens: {timestamp}, {newline}, {message}, {category}
TextFormatter formatter = new TextFormatter
("[{timestamp}]" + "[{category}]" + "{message}{newline}");
//// Log messages to a log file. Use the formatter mentioned above specified.
string date = String.Format("{0:yyyyMMdd}", DateTime.Now);
FlatFileTraceListener logFileListener = new FlatFileTraceListener(folder + "/" + fileName + "_" + date + ".log", "", "", formatter);
WmiTraceListener wmiListener = new WmiTraceListener();
//// My collection of TraceListeners.
LogSource mainLogSource =
new LogSource("FlatFile TraceListener", SourceLevels.All);
LogSource wmiMainLogSource = new LogSource("WmiTraceListener", SourceLevels.All);
mainLogSource.Listeners.Add(logFileListener);
wmiMainLogSource.Listeners.Add(wmiListener);
//// Assigning a non-existant LogSource for Logging Application Block
//// Specials Sources I don't care about.Used to say "don't log".
LogSource nonExistantLogSource = new LogSource("Empty");
//// I want all messages with a category of "User" or "Developer" to get distributed
//// to all TraceListeners in my mainLogSource.
IDictionary<string, LogSource> traceSources =
new Dictionary<string, LogSource>();
traceSources.Add("User", mainLogSource);
traceSources.Add("Developer", mainLogSource);
IDictionary<string, LogSource> wmiTraceSources =
new Dictionary<string, LogSource>();
wmiTraceSources.Add("Instrumentation", wmiMainLogSource);
// Let's glue it all together.
// No filters at this time.
// I won't log a couple of the Special
// Sources: All Events and Events not
// using "Error" or "Debug" categories.
eskoLoggingWriter = new LogWriter(new ILogFilter[0],
traceSources,
nonExistantLogSource,
nonExistantLogSource,
mainLogSource,
"ALL",
false,
true);
wmiWriter = new LogWriter(new ILogFilter[0],
wmiTraceSources,
nonExistantLogSource,
nonExistantLogSource,
wmiMainLogSource,
"All",
true,
true);
}
}
}
In Global.asax, add these line in Application_Start
void Application_Start(object sender, EventArgs e) {
// Code that runs on application startup
Utility.CreateLogWriterFromCode(ConfigurationSettings.AppSettings["LogFolder"].Trim(), ConfigurationSettings.AppSettings["LogFileName"].Trim());
Utility.LogUserMessage("******** Application_Start Event My Login application started ******", 1, System.Diagnostics.TraceEventType.Information);
}
Now wherver you want to log a message, use
Utility.LogUserMessage
You might have to make minor changes to the Utility class if EntLib 5 is used. That should be trivial.
So there you have, a log file on daily basis with correct data for that day.
Again thank you to the anonymus person who wrote the Utility class in the first place.
Hope this helps.
Regards.

MVC3 Helper Not Working, Not Found

I created the following helper in my main directory under /Helpers:
HtmlHelpers.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;
namespace Website.Helpers
{
public static class HtmlHelpers
{
public static MvcHtmlString ActiveActionLinkHelper(this HtmlHelper Html, string text, string action, string controller, string activeClass = "active", bool actionCheck = false)
{
if (Html.ViewContext.RouteData.GetRequiredString("controller") == controller)
{
if (actionCheck)
{
if (Html.ViewContext.RouteData.GetRequiredString("action") == action)
return Html.ActionLink(text, action, controller, new { Class = activeClass });
}
else
{
return Html.ActionLink(text, action, controller, new { Class = activeClass });
}
}
return Html.ActionLink(text, action, controller);
}
}
}
I added the namespace to the Views web.config in my Publishers Areas folder:
<system.web.webPages.razor>
<host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
<add namespace="System.Web.Mvc" />
<add namespace="System.Web.Mvc.Ajax" />
<add namespace="System.Web.Mvc.Html" />
<add namespace="System.Web.Routing" />
<add namespace="Website.Helpers" />
</namespaces>
</pages>
</system.web.webPages.razor>
I keep getting this message:
Compiler Error Message: CS1061: 'System.Web.Mvc.HtmlHelper' does not contain a definition for 'ActiveActionLink' and no extension method 'ActiveActionLink' accepting a first argument of type 'System.Web.Mvc.HtmlHelper' could be found (are you missing a using directive or an assembly reference?)
Core: #Html.ActiveActionLink("Dashboard", "Index", "Dashboard")
Does anyone know what I am doing wrong? There are hardly any tutorials on how or where to store an HTML helper. Can someone please advise me?
Core: #Html.ActiveActionLink("Dashboard", "Index", "Dashboard") // here it is the problem
as your method is ActiveActionLinkHelper, your calling different method.
#Html.ActiveActionLinkHelper("Dashboard", "Index", "Dashboard") // try like this.
The compiler is right. You're method is named ActiveActionLinkHelper. Change it to ActiveActionLink and all should be well

i want to return List<DictionaryClass<string,string>> from web service but getting error for IDictionary

[WebMethod]
public List<DictionaryClass<string,string>> GetDataByModuleDictionary(string ModuleName)
{
return BAL_GeneralService.GetDataByModuleDictionary(ModuleName);
}
here i m getting the following error...
The type DictionaryClass`2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]] is not supported because it implements IDictionary.
XMLSerializer cannot serialize a class that implements IDictionary. To work around this you need to implement System.Xml.Serialization.IXmlSerializable in your DictionaryClass. See here for further info.

Resources