thepirat000 / audit.net Goto Github PK
View Code? Open in Web Editor NEWAn extensible framework to audit executing operations in .NET and .NET Core.
License: MIT License
An extensible framework to audit executing operations in .NET and .NET Core.
License: MIT License
Hi Frederico,
While playing around with Audit.NET I would love to see direct integration of EntityFramework.
I mean a possibility to save EventEntry and other data (POCO objects) directly to existing DbContexts via DbSets.
Currently I'm trying to implement my own CustomDataProvider to achieve this goal. I will try to fetch all EntityFrameworkEvents and use their data for saving.
The reason for this: I need a possibility to show the end user changes made by other users on an entity. That way I need the data in plain format to show in data grids - not json.
Regards
Sven
Hi,
I'm find your library very promising for my project, but I have couple of q's:
Can this library provide nested audit scopes? How I can do that?
I need to track all things in http request boundary and I interested in writing single event to store,
this event should hold data entries smth like:
(Request) -> (Application scope) -> (Business scope) -> (EF scope)
where Request and EF holding data which already implemented in your extensions(Mvc,Sql),
Application and Business holding custom audit data
How to make custom DB schema for storing event not in json?
Thanks in advance!
P.S: You making good stuff ๐
I am trying to use this in one of my MVC 4.5 application and my DB context is defined as below:
public class MyDBContext : AuditIdentityDbContext<User>
{
public MyDBContext()
: base("MyDBContext", throwIfV1Schema: false)
{
}
//Additional DbSets here...
}
While compiling the application it throws error in Constructor for - base("MyDBContext", throwIfV1Schema: false). I identified that the below constructor is missing in AuditIdentityDbContext and AuditDBContext class:
/// <summary>
/// Constructor which takes the connection string to use
/// </summary>
/// <param name="nameOrConnectionString"></param>
/// <param name="throwIfV1Schema">Will throw an exception if the schema matches that of Identity 1.0.0</param>
public AuditIdentityDbContext(string nameOrConnectionString, bool throwIfV1Schema)
: base(nameOrConnectionString)
{
if (throwIfV1Schema)
{
_helper.SetConfig(this);
}
}
I added this constructor in Audit.EntityFramework Source in both the classes and added a reference of that source in Project and it started working fine.
Would you suggest to add this in this package?
Please let me know in case you need any additional details.
Thanks,
Dhaval Limbad
I have a database with several schemas in it. I am currently using the API audit package and I want the event table to be stored in a certain schema. How can I configure the Audit.NET to work with a specific schema? Or is this something that will need to be coded into the application.
Hi,
When I tried to install Audit.MVC
Installing Audit.NET 6.0.0.
Adding package 'Audit.NET.6.0.0' to folder 'c:\testaud\packages'
Added package 'Audit.NET.6.0.0' to folder 'c:\testaud\packages'
Install failed. Rolling back...
Package 'Audit.NET.6.0.0 : Newtonsoft.Json [9.0.1, )' does not exist in project 'TestAud'
Removing package 'Audit.NET.6.0.0 : Newtonsoft.Json [9.0.1, )' from folder 'c:\testaud\packages'
Removed package 'Audit.NET.6.0.0 : Newtonsoft.Json [9.0.1, )' from folder 'c:\testaud\packages'
Install-Package : Failed to add reference to 'Audit.NET'.
At line:1 char:1
+ Install-Package Audit.MVC
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Install-Package], Exception
+ FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand
Hi I'm Using Audit.EntityFramework with Custom Storage provider for Sql Server,How Can I Audit Image or Long Length String?
Hi, the following is the response , and found that the potential Null Reference Exception.
{
"Message": "An error has occurred."
"ExceptionMessage": "Object reference not set to an instance of an object."
"ExceptionType": "System.NullReferenceException"
"StackTrace": " at Audit.WebApi.AuditApiAttribute.OnActionExecuted(HttpActionExecutedContext actionExecutedContext) at System.Web.Http.Filters.ActionFilterAttribute.OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken) --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter.GetResult() at System.Web.Http.Filters.ActionFilterAttribute.d__5.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter1.GetResult() at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__0.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter
1.GetResult() at System.Web.Http.Controllers.ActionFilterResult.d__2.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() at System.Web.Http.Dispatcher.HttpControllerDispatcher.d__1.MoveNext()"
}
AuditApiAttribute class
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
actionExecutedContext.Response <--- may null if the exception throw.
Following is my modified code AuditApiAttribute.
public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext)
{
var httpContext = GetHttpContext(actionExecutedContext.Request);
var auditAction = httpContext.Items[AuditApiActionKey] as AuditApiAction;
var auditScope = httpContext.Items[AuditApiScopeKey] as AuditScope;
if (auditAction != null && auditScope != null)
{
auditAction.Exception = actionExecutedContext.Exception.GetExceptionInfo();
auditAction.ModelStateErrors = IncludeModelState ? GetModelStateErrors(actionExecutedContext.ActionContext.ModelState) : null;
auditAction.ModelStateValid = IncludeModelState ? (bool?)actionExecutedContext.ActionContext.ModelState.IsValid : null;
auditAction.ResponseBodyType = actionExecutedContext.Response == null ? "" : actionExecutedContext.Response.Content.GetType().Name;
if (actionExecutedContext.Response != null)
{
auditAction.ResponseStatus = actionExecutedContext.Response.ReasonPhrase;
auditAction.ResponseStatusCode = (int)actionExecutedContext.Response.StatusCode;
if (IncludeResponseBody)
{
var objContent = actionExecutedContext.Response.Content as ObjectContent;
auditAction.ResponseBody = objContent != null
? new { Type = objContent.ObjectType.Name, Value = objContent.Value }
: (object)actionExecutedContext.Response.Content.ReadAsStringAsync().Result;
}
}
else
{
auditAction.ResponseStatusCode = 500 ;
auditAction.ResponseStatus = "Internal Server Error";
}
// Replace the Action field and save
auditScope.SetCustomField("Action", auditAction);
auditScope.Save();
}
}
Hello,
We have 4 apps which are already in production but for auditing we have to write a lot of code so we were looking for some robust mechanism with same functionality but with less code.
I am loving it to use AUDIT.NET believe me it only takes one day to attach to all apps.
Thanks.
Well i am looking for two things
Thanks
Would it be possible to mark the Audit.NET assembly CLS compliant by adding the ClsCompliantAttribute to the assembly.info file?
[assembly: CLSCompliant(true)]
Thanks for considering.
Hi @thepirat000
I got an error when the request form data has html code, the Audit.Mvc.AuditAttribute class method private static IDictionary<string, string> ToDictionary(NameValueCollection col) occur an exception "System.Web.HttpRequestValidationException: 'A potentially dangerous Request.Form value was detected from the client (Html="
").'" , would you help to check this issue?
Below image for your reference.
@thepirat000 Because System.Web.Http.Filters.ActionFilterAttribute.OnActionExecuted method HttpActionExecutedContext.Response.Content will be a unsekable stream when using owin, auditAction.ResponseBody will always be empty.
To fix it ,I added a Middleware to use bufferred stream to replace networkInputStream, then I can get the HttpActionExecutedContext.Response.Content and read it as string.
I posted here angularsen/AspNetHttpLogger#3.
I think you`d better add a Notice on README or somewhere, or fix it in you way, that will helpful.
Hi,
This great library has saved us ages in getting good auditing set up, so many thanks indeed!!
We have one small problem with it. We are using a dotnet 452 mvc app and in the Startup.startup method we are configuring a SQLProvider as follows
public Startup(IHostingEnvironment env)
{
//Load application config as the first step in the startup
var builder = new ConfigurationBuilder()
.SetBasePath(env.ContentRootPath)
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true);
builder.AddEnvironmentVariables();
Configuration = builder.Build();
//Set up a storage provider for the audit infrastructure that we are using
//See https://github.com/thepirat000/Audit.NET
var sqlProvider = new Audit.SqlServer.Providers.SqlDataProvider();
sqlProvider.ConnectionString = Configuration.GetConnectionString("Link.Core.Db");
sqlProvider.Schema = "audit";
sqlProvider.LastUpdatedDateColumnName = "LastUpdateTime";
Audit.Core.Configuration.Setup().UseCustomProvider(sqlProvider);
}
We then instantiate our AuditDbContext object in the ConfigureServices method as per:
public void ConfigureServices(IServiceCollection services) {
//Other service setup omitted for brevity
services.AddScoped(_ => new LinkContext(Configuration.GetConnectionString("Link.Core.Db")));
}
The first time we hit the API service we are getting the following error raised:
System.NullReferenceException was unhandled by user code
Message=Object reference not set to an instance of an object
StackTrace:
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at Audit.EntityFramework.DbContextHelper.SetConfig(IAuditDbContext context)
at Audit.EntityFramework.AuditDbContext..ctor(String nameOrConnectionString)
at Link.Data.LinkContext..ctor(String connString)
at Link.Api.Startup.<ConfigureServices>b__4_2(ISeachProvider _)
........ Remaining stack trace omitted for brevity
It appears to work subsequent to this so wondering if we are starting up something in the wrong order?
Thanks in advance
Iain
I've come across an issue whereby the WebAPI extension appears to be ignoring the EventCreation Policy.
I've set the policy in two ways, both in the fluent style as follows:
Audit.Core.Configuration.CreationPolicy = EventCreationPolicy.InsertOnStartReplaceOnEnd;
var connectionString = ConfigurationManager.ConnectionStrings[contextName].ConnectionString;
Audit.Core.Configuration
.Setup()
.UseSqlServer(config => config.ConnectionString(connectionString)
.Schema("dbo")
.TableName("events")
.IdColumnName("id")
.JsonColumnName("data")
.LastUpdatedColumnName("lastUpdatedDate")
)
.WithCreationPolicy(EventCreationPolicy.InsertOnStartReplaceOnEnd);
however all my events are only being written to the log at the end of the request, and none of the events have a populated 'lastUpdatedField'
Hi,
I encountered a issue when using AuditScope in my MVC application like below.
AuditScope.CreateAndSave("LoginSuccess", new { username = user.username });
AuditScope.CreateAndSave("LoginFailed", new { username = user.username });
I have several controller action calls the log , however it doesn't always error out. Sometime it throws exception, and some time it works well.
the exception message is as the title:
Collection was modified; enumeration operation may not execute.
the stack trace logged as follows:
System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
at System.Collections.Generic.List1.Enumerator.MoveNextRare() at Audit.Core.Configuration.InvokeScopeCustomActions(ActionType type, AuditScope auditScope) at Audit.Core.AuditScope.SaveEvent(Boolean forceInsert) at Audit.Core.AuditScope..ctor(String eventType, Func
1 target, Object extraFields, AuditDataProvider dataProvider, Nullable`1 creationPolicy, Boolean isCreateAndSave)
at Audit.Core.AuditScope.CreateAndSave(String eventType, Object extraFields, AuditDataProvider dataProvider)
So my when i looked up the source code, in the class Audit.Core.Configuration , you have
internal static void InvokeScopeCustomActions(ActionType type, AuditScope auditScope)
{
foreach (var action in AuditScopeActions[type])
{
action.Invoke(auditScope);
}
}
the above function loop through the AuditScopeActions Dictionary defined as
internal static Dictionary<ActionType, List<Action<AuditScope>>> AuditScopeActions { get; private set; }
Could that be because the Dictionary isn't thread safe, so when multiple thread from my MVC web application reads and writes it concurrently, it throws the error?
let me know if i am mistaken. thank you.
Hey, I've been trying today to get a combination of Audit.NET SqlServer and EF tracking changes to my database. I'm getting events to fire, but I'm not able to get any changes to be tracked? Instead I seem to get an empty list in my DB.
Is there anything in particular I need to know?
I'm configured with OptOut, and AnyContext - and my DbContext is an extension of AuditContext. I get the new state of the object perfectly fine, but no information on changes that have been made.
Hi,
Would it be possible to strongly sign your release version that you package in your Nuget Package. This way the nuget can also be used in projects that require all assemblies to be signed. Make sure you make a wise decision on your key because if you change it in future versions other issues come up for backwards compatibility.
Kind regards,
Bjorn
Hi and thanks for the awesome Audit package you created :)
We are creating a lot of audit logs in azure and we need to remove them when they reach a certain age.
Deleting the files one by one takes to long time. If there were a ContainerNameBuilder, I could create a new container per month, and delete this container after a certain time and all the files will be deleted with it :)
Another question: Whats the performance cost for auditing to azure blobs? Are you batching the updates? Runing the update async or on another thread?
Regards
//Per
Love the tool, and wondering if you have plans to implement for IdentityDbContext? I've been working my way through a [messy] implementation, and you can see the issue I've run into here: http://stackoverflow.com/questions/42168013/third-party-implementation-of-dbcontext-how-to-also-implement-identitydbcontext
Thank you!
Hi,
I'm testing your library for the auditing in my application that uses EF6.
I configured SQL provider in Application_Start.
With first of the AuditScope use I got this exception:
The default DbConfiguration instance was used by the Entity Framework before the 'DbConfig' type was discovered. An instance of 'DbConfig' must be set at application start before using any Entity Framework features or must be registered in the application's config file. See http://go.microsoft.com/fwlink/?LinkId=260883 for more information.
Can you explain how to use it in MVC app with EF6 in use and the same database as target ?
Hi,
I'm trying to integrate the Audit.NET library with my existing code. All of my entities inherit from an abstract base class. The code is not working and an error is thrown at the step "Get the entity type from the model that maps to the CLR type" in EntityKeyHelper.cs. The code is trying to find a CLR type for my base class, which cannot work properly because it doesn't exist in objectItemCollection. I'm not sure if it is correct to get the base entity type (GetBaseEntityType) for the given entity.
Regards
Sven
I'm not sure how to change the default Directory. It always save to IIS express when I run in local. Do you have example code for this?
Please assists. Thanks.
public class CustomAuditDataProvider : Audit.Core.Providers.FileDataProvider
{
public override object InsertEvent(AuditEvent auditEvent)
{
//FileDataProvider fileDataProvider = new FileDataProvider();
DirectoryPath = "C://Users//XXXX";
// AuditEvent provides a ToJson() method
string json = auditEvent.ToJson();
// Write the json representation of the event to a randomly named file
var fileName = "Log" + Guid.NewGuid().ToString() + ".json";
File.WriteAllText(fileName, json);
return fileName;
}
}
I have tried Audit.Mvc with FileDataProvider and made a performance test as shown below:
Audit.Core.Configuration.Setup()
.UseFileLogProvider(config => config
.DirectoryBuilder(_ => $@"C:\Logs\{DateTime.Now:yyyy-MM-dd}")
.FilenamePrefix("Event_"));
[Audit]
public IActionResult Index()
result:
Speed=34177 pages/min
//[Audit]
public IActionResult Index()
result:
Speed=137437 pages/min
I think that wrote audit data immediately, or into independent files will cause performance issue. Is there any way to write all audit data into one file or make a batch writing?
Is there a way I only track Update and Delete actions of my models?
And its also capture DBUpdate Exceptions, where changes were not successful. How can I exclude these as well?
"Valid":true,"ValidationResults":[]}],"Result":0,"Success":false,"ErrorMessage":"(DbUpdateException) An error occurred while updating the entries. See the inner exception for details.
Hi!
Is there a way to set the connection string to the azure storage per request?
Our customers have there own azure storage accounts and we want to be able to store there own audit logs in there own azure storage. (They are using our SAAS webapi)
Regards
Per
Firstly, Thanks a lot for creating this Awesome Library. I love using it.
I am new to package and have came across below issue while using this in one my application.
I added reference of Audit.net 6.2.0 in my MVC application built on .Net Framework 4.0.
In Global.asax Start_Application event when i use below configuration, it gives me System.Object error:
Audit.Core.Configuration.DataProvider = new Audit.SqlServer.Providers.SqlDataProvider()
{
ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["AuditDBConnection"].ConnectionString,
Schema = "odb",
TableName = "LOG_JSON",
IdColumnName = "LOG_JSON_ID",
JsonColumnName = "JSON_STRING",
LastUpdatedDateColumnName = "CREATED_DATE" ,
};
Error i get while using "Audit.Core.Configuration" in first line :
The type 'System.Object' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Runtime, Version=4.0.20.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a'.
Hello,
I'm not sure if missed anything in the docs.
I'm trying to track EF 6 entity changes.
For simple properties it works, but for complex properties (foreign key) the change is simply ignored.
Any suggestion?
Thanks,
Sandor
Include the raw request body as an optional field
I have some sensitive information that comes across in form fields and action parameters that I would like to either remove from the log or encrypt.
I see no way of doing this without a custom policy creation.
I was hoping (for example the MVC extension) I could hook into it and remove different fields I did not want to log at all?
Is this possible?
When using some extensions which implement attributes(currently at least Audit.Mvc and Audit.WebApi) and an action is audited, the record that is created contains something like this
"AssemblyName": "Audit.Mvc, Version=4.10.0.0, Culture=neutral, PublicKeyToken=null",
"CallingMethodName": "Audit.Mvc.AuditAttribute.OnActionExecuting()"
If you explicitly create the auditScope, it works as expected(meaning it references my assembly and calling method)
Guessing it's breaking because AuditScope.cs is hardcoded to 2, when, if coming from an attribute in this case, the stack would be one level deeper.
var callingMethod = new StackFrame(2).GetMethod();
This is super low priority however, I'm getting beautiful audits and they currently include the correct Controller and Action. Having the assembly and method would simply be sugar on top.
Thanks again for an awesome product.
I'm running Audit.NET on an API deployed in IIS. The environment data for each call that gets audited is always the same and pretty much of no value, as follows:
"Environment": {
"UserName": "DotNet Core",
"MachineName": "HOFFELL",
"DomainName": "IIS APPPOOL",
"CallingMethodName": "SomeController.Get()",
"AssemblyName": "Api, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null",
"Culture": "is-IS"
},
Is it possible to pass in more useful information, and how to achieve it, related to the user that is calling the api?
@thepirat000 Because System.Web.Http.Filters.ActionFilterAttribute.OnActionExecuted method HttpActionExecutedContext.Response.Content will be a unsekable stream when using owin, auditAction.ResponseBody will always be empty.
To fix it ,I added a Middleware to use bufferred stream to replace networkInputStream, then I can get the HttpActionExecutedContext.Response.Content and read it as string.
I posted here angularsen/AspNetHttpLogger#3.
I think you`d better add a Notice on README or somewhere, or fix it in you way, that will helpful.
Audit.WebApi can`t work in selfhost webapi , because use System.Web.dll as a reference.
It will fire a ArguementNullException, because HttpContext.Current is null.
I think using owinContext as a "WebContext" environment will make it more extensional.
New Feature Request: Support for Azure Blob Storage and Azure Table Storage for event storage
Hi, and let me start by saying thanks for the awesome project.
I recently integrated Audit.EntityFramework into an existing project that uses an EDMX file. It worked perfectly, except for one entity that is mapped to modification functions. After some digging, I discovered that the designer had created two EntityTypeMapping
elements for the entity, one containing the MappingFragment
, and the other containing the ModificationFunctionMapping
. This appears to be perfectly valid inside the various EF components, but results in an InvalidOperationException
("Sequence contains more than one element.") on line 161 of EntityKeyHelper.cs
.
I've managed to get around the error by merging the two EntityTypeMapping
elements in the EDMX, but since the designer has a mind of it's own, I wouldn't be surprised if it puts things back to the way they were the next time the file is updated from the database.
I noticed that, at runtime, EF had merged the function mapping metadata into the EntityTypeMapping
instance that contained the fragment, however the opposite was not true, so it might be possible to prevent the error by filtering out EntityTypeMapping
instances that don't contain any fragments. i.e. Line 161 could be updated to:
.EntityTypeMappings.Single(m => m.Fragments.Count != 0)
Regards
Rory
Hi,
I was looking at your help for the APS MVC 4 / 5, the picture really helped.
Is there default configuration on startup to just audit all actions/or atleast by controller, rather than putting on each action(by roles)? to profile things like number of times a password was failed/ reset etc
thanks
entityType.SqlServer() method is not found when trying to get entity name
System.MissingMethodException: Method not found: 'Microsoft.EntityFrameworkCore.Metadata.IRelationalEntityTypeAnnotations Microsoft.EntityFrameworkCore.SqlServerMetadataExtensions.SqlServer(Microsoft.EntityFrameworkCore.Metadata.IEntityType)'. at Audit.EntityFramework.AuditDbContext.GetEntityName(IEntityType entityType) at Audit.EntityFramework.AuditDbContext.CreateAuditEvent(Boolean includeEntities, AuditOptionMode mode) at Audit.EntityFramework.AuditDbContext.SaveChanges()
Setting CreationPolicy to InsertOnEnd is behaving the same as setting it to InsertOnStartInsertOnEnd. Specifically it appears to be firing the Insert event for OnActionExecuted and OnResultExecuted. It is my understanding that InsertOnEnd should cause it to only fire the insert event when the scope is disposed, which happens in OnResultExecuted.
This is what I'm attempting to use:
Configuration.Setup()
.UseDynamicProvider(config => config.OnInsert(auditEvent =>
//Do something
))
.WithCreationPolicy(EventCreationPolicy.InsertOnEnd);
The result of this is that I'm getting nearly duplicate log entries.
Thoughts?
We have plugged in the Audit.WebApi via a global filter. but the authentication call to \Token is not being recorded.
I assume this is because it is not a ApiController call.
any idea how i could get this to work
Does Audit.EntityFramework
not work with in-memory database? I need it for testing. I am using EF Core with xUnit.
I have a context factory like so:
public class DatabaseContextFactory
{
public DatabaseContext Create()
{
var serviceProvider = new ServiceCollection()
.AddEntityFrameworkInMemoryDatabase()
.BuildServiceProvider();
var builder = new DbContextOptionsBuilder<DatabaseContext>();
builder.UseInMemoryDatabase()
.UseInternalServiceProvider(serviceProvider);
return new DatabaseContext(builder.Options);
}
}
Where my DatabaseContext
inherits from AuditDbContext
:
public sealed class DatabaseContext : AuditDbContext
{
public DatabaseContext(DbContextOptions options)
: base(options)
{
}
}
I get this error when running tests:
System.IndexOutOfRangeException : Index was outside the bounds of the array.
Stack Trace:
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at Audit.EntityFramework.DbContextHelper.EnsureEntitiesIncludeIgnoreAttrCache(Type type)
at Audit.EntityFramework.DbContextHelper.IncludeEntity(IAuditDbContext context, EntityEntry entry, AuditOptionMode mode)
at Audit.EntityFramework.DbContextHelper.<>c__DisplayClass19_0.<GetModifiedEntries>b__0(EntityEntry x)
at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Audit.EntityFramework.DbContextHelper.GetModifiedEntries(IAuditDbContext context)
at Audit.EntityFramework.DbContextHelper.CreateAuditEvent(IAuditDbContext context)
at Audit.EntityFramework.DbContextHelper.SaveChanges(IAuditDbContext context, Func`1 baseSaveChanges)
at Audit.EntityFramework.AuditDbContext.SaveChanges()
Excellent library!
Are there any plans to support .NET Core 1.1?
Amazing library. :)
I am trying to query single audit event by ObjectId (593feb7c2d63d072b061d966) of AuditEvent(_id) to get the difference in a Old and New document.
here is my query
mongoDataProvider.QueryEvents()
.FirstOrDefault(ev => ev.CustomFields.Any(kvp => kvp.Key = "_id" (string)kvp.Value == auditId));
Its throwing Exception "The expression tree is not supported".
Here is sample document
{
"_id" : ObjectId("593feb7c2d63d072b061d966"),
"Environment" : {
"UserName" : "Patel, Anand",
"MachineName" : "APATEL-W10LT",
"DomainName" : null,
"CallingMethodName" : null,
"AssemblyName" : null,
"Exception" : null,
"Culture" : "en-US"
},
"EventType" : "593aaedc8f0dd20019fbdd40",
"Target" : {
"Type" : "Template",
"Old" : {
"_t" : "MongoDB.Bson.BsonDocument, MongoDB.Bson",
"_v" : {
"_t" : "Template",
"_id" : ObjectId("593aaedc8f0dd20019fbdd40"),
"name" : "Import Test - 12",
"type" : "Web",
"activeIndicator" : true,
"parentId" : "5925d50336ed6f0019b6a660",
"parentIndicator" : false,
"createdAtUtc" : ISODate("2017-06-09T14:21:16.736+0000"),
"updatedAtUtc" : ISODate("0001-01-01T00:00:00.000+0000")
}
},
"New" : {
"_t" : "MongoDB.Bson.BsonDocument, MongoDB.Bson",
"_v" : {
"_t" : "Template",
"_id" : ObjectId("593aaedc8f0dd20019fbdd40"),
"name" : "Import Test - 1222",
"type" : "Web",
"activeIndicator" : true,
"parentId" : "5925d50336ed6f0019b6a660",
"parentIndicator" : false,
"createdAtUtc" : ISODate("2017-06-09T14:21:16.736+0000"),
"updatedAtUtc" : ISODate("0001-01-01T00:00:00.000+0000")
}
}
},
"Comments" : [
"Template imported."
],
"StartDate" : ISODate("2017-06-13T13:41:16.193+0000"),
"EndDate" : ISODate("2017-06-13T13:41:16.268+0000"),
"Duration" : NumberInt(75)
}
Hi,
Me again.... Apologies for another intrusion.
To recap we are using .net core web api with .net 45 and EF 6.1.3
I am doing an update of an entity and am getting the error below every time I post a changed entity. All unit tests work however although those are written in a traditional c# test project. Any ideas why this would happen in the .Net Core api only?
{ "message": "Invalid column name 'Id'.", "detail": " at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose) at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady) at System.Data.SqlClient.SqlDataReader.TryConsumeMetaData() at System.Data.SqlClient.SqlDataReader.get_MetaData() at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString, Boolean isInternal, Boolean forDescribeParameterEncryption) at System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async, Int32 timeout, Task& task, Boolean asyncWrite, Boolean inRetry, SqlDataReader ds, Boolean describeParameterEncryptionRequest) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, TaskCompletionSource`1 completion, Int32 timeout, Task& task, Boolean& usedCache, Boolean asyncWrite, Boolean inRetry) at System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method) at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior behavior, String method) at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed) at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext) at System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreQueryInternal[TElement](String commandText, String entitySetName, ExecutionOptions executionOptions, Object[] parameters) at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass65`1.<ExecuteStoreQueryReliably>b__64() at System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction[T](Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess) at System.Data.Entity.Core.Objects.ObjectContext.<>c__DisplayClass65`1.<ExecuteStoreQueryReliably>b__63() at System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute[TResult](Func`1 operation) at System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreQueryReliably[TElement](String commandText, String entitySetName, ExecutionOptions executionOptions, Object[] parameters) at System.Data.Entity.Core.Objects.ObjectContext.ExecuteStoreQuery[TElement](String commandText, ExecutionOptions executionOptions, Object[] parameters) at System.Data.Entity.Internal.LazyEnumerator`1.MoveNext() at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source) at Audit.SqlServer.Providers.SqlDataProvider.InsertEvent(AuditEvent auditEvent) at Audit.Core.AuditScope.SaveEvent(Boolean forceInsert) at Audit.Core.AuditScope.Save() at Audit.EntityFramework.DbContextHelper.SaveScope(IAuditDbContext context, AuditScope scope, EntityFrameworkEvent event) at Audit.EntityFramework.DbContextHelper.SaveChanges(IAuditDbContext context, Func`1 baseSaveChanges) at Audit.EntityFramework.AuditDbContext.SaveChanges() at Link.Data.Services.SupplierRegistrationService.Upsert(SupplierRegistration entity) in C:\\Users\\Admin\\Source\\Repos\\LINK\\LINK\\Link.Data\\Services\\SupplierRegistrationService.cs:line 74 at Link.Api.Controllers.SupplierRegistrationsController.Put(SupplierRegistration entity) in C:\\Users\\Admin\\Source\\Repos\\LINK\\LINK\\Link.Api\\Controllers\\SupplierRegistrationsController.cs:line 40 at lambda_method(Closure , Object , Object[] ) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__27.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextActionFilterAsync>d__25.MoveNext() --- End of stack trace from previous location where exception was thrown --- at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextExceptionFilterAsync>d__24.MoveNext()" }
Hi I'm currently using Audit.NET for WebApi. I've im using the attribute based approach for auditing specific api calls. This works great.
However, now I want to include whatever changes that API calls have made to the underlying EF6 scope.
My question is; can I include both webapi and ef6 audit information in the same audit record?
Also, how do I ensure that all the other EF6 are not audited?
Any ideas or thoughts?
Hi guys! Great work @thepirat000! I would like to ask if you have plans to implement some rest api endpoint or middleware to log audit events for any consumer platform. This can be very hepfull! Thanks!
Thanks,
Paul Alves
Hi!
Iยดm using Audit.EntityFramework and on log output the old and new values for changed entity are always the same!
My config on statup.cs:
Audit.Core.Configuration.Setup().UseSqlServer(c => {
c.ConnectionString(Configuration.GetConnectionString("audit.db"));
c.Schema("dbo");
c.TableName("Event");
c.IdColumnName("EventId");
c.JsonColumnName("Data");
c.LastUpdatedColumnName("LastUpdatedDate");
});
Audit.EntityFramework.Configuration.Setup()
.ForAnyContext(x => x.IncludeEntityObjects(true)
.AuditEventType("{context}:{database}"))
.UseOptOut();
Thankyou for the library and support!
I tried to create a trigger on the Event table. Whenever I wanted to add an event log in the database (with the Audit.NET.SqlServer provider) I have an issue due to the way the log is inserted in the database.
I searched in the code of the provider (SqlDataProvider.cs) and found out that it use this query to insert a line in the table :
INSERT INTO {0} ([{1}]) OUTPUT CONVERT(NVARCHAR(MAX), INSERTED.[{2}]) AS [Id] VALUES (@json)
But the trigger will always fail if the statement contains an OUTPUT.
Here is the exception :
An exception of type 'System.Data.SqlClient.SqlException' occurred in EntityFramework.SqlServer.dll but was not handled in user code
Additional information: The target table 'dbo.Event' of the DML statement cannot have any enabled triggers if the statement contains an OUTPUT clause without INTO clause.
I did work around this issue by replacing the INSERT statement by INSERT INTO {0} ([{1}]) VALUES (@json)
in the SqlDataProvider.cs (I downloaded the source of the project) file and it works just fine for me.
Hi,
I want to exclude some properties which are not required for an Audit.
Hi Daniel,
the audit.net runs on my project since over two months, but I updated all packages yesterday, now I lose Authentication. I deactivated audit configuration then works well fine. I using following code in my asp.net core startup. I wanna ask you have you any idee ? Thank you very much
app.Use(async (context, next) =>
{
Audit.Core.Configuration.AddCustomAction(ActionType.OnEventSaving, scope =>
{
if (scope.Event.Environment.Exception != null)
{
scope.SetCustomField("Fehler", true);
}
if (context.User.Identity.Name != null)
{
try
{
scope.Event.Environment.UserName = context.User.Identity.Name.ToString();
scope.Event.Environment.MachineName = context.Connection.RemoteIpAddress.ToString();
}
catch (Exception)
{
scope.Event.Environment.UserName = "Fehler";
scope.Event.Environment.MachineName = "Fehler";
}
}
});
if (context.Request.IsHttps)
{
await next();
}
else
{
var withHttps = "https://" + context.Request.Host + context.Request.Path;
context.Response.Redirect(withHttps);
}
});
Hello,
I used this code for disable audit for some tables:
Audit.EntityFramework.Configuration.Setup()
.ForContext<MyContext>(config => config
.IncludeEntityObjects(false)
.AuditEventType("{context}:{database}"))
.UseOptOut()
.IgnoreAny(x => x.Name == "LogCmdClient" || x.Name == "BlackListBatch" || x.Name == "BlackListSQL" || x.Name == "ReleaseFiles");
But I noticed that when I delete something generates an occurrence in my audit log.
Is it possible to have multiple data providers, one to capture all the Web API activities and another to capture the Entity Framework (data layer) activities, on separate tables?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.