Audit.Mvc.Core
25.0.6
See the version list below for details.
dotnet add package Audit.Mvc.Core --version 25.0.6
NuGet\Install-Package Audit.Mvc.Core -Version 25.0.6
<PackageReference Include="Audit.Mvc.Core" Version="25.0.6" />
paket add Audit.Mvc.Core --version 25.0.6
#r "nuget: Audit.Mvc.Core, 25.0.6"
// Install Audit.Mvc.Core as a Cake Addin #addin nuget:?package=Audit.Mvc.Core&version=25.0.6 // Install Audit.Mvc.Core as a Cake Tool #tool nuget:?package=Audit.Mvc.Core&version=25.0.6
Audit.Mvc
MVC Actions Audit Extension for Audit.NET library. (An extensible framework to audit executing operations in .NET).
Generate Audit Trails for MVC actions. Supporting Asp NET Core Mvc.
Audit.Mvc / Audit.Mvc.Core provides the infrastructure to log interactions with MVC applications. It can record action methods calls to controllers and razor pages.
Install
NuGet Packages
To install the ASP.NET package run the following command on the Package Manager Console:
PM> Install-Package Audit.Mvc
To install the Asp Net Core package:
PM> Install-Package Audit.Mvc.Core
IMPORTANT NOTE
Previously, it was possible to employ the Audit.Mvc
package for ASP.NET Core MVC or vice versa.
However, starting from version 23, the Audit.Mvc
package is now exclusively designed for ASP.NET Framework MVC,
whereas the Audit.Mvc.Core
package is exclusively tailored for ASP.NET Core MVC.
Please upgrade your references accordingly.
Usage
MVC Controllers
Decorate the MVC Actions or Controllers you want to audit with [Audit]
action filter.
For example:
public class HomeController : Controller
{
[Audit]
public ActionResult Index(int id, string name)
{
//...
return View(new SomeViewModel() { Id = id, Name = name });
}
[Audit(EventType = "InsertOrderAction", IncludeHeaders = true, IncludeModel = true)]
[HttpPost]
public ActionResult TestPost(SomeViewModel model)
{
//...
}
}
The
[Audit]
attribute cannot be used on razor pages, because action filters are not supported on razor pages.
Razor pages
To audit razor pages, include the AuditPageFilter
on the filters collection on your startup code, for example:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages()
.AddMvcOptions(options =>
{
options.Filters.Add(new AuditPageFilter()
{
IncludeHeaders = true
});
});
}
Or you can apply the filter only to certain pages, for example for pages under /Movies
path:
public void ConfigureServices(IServiceCollection services)
{
services.AddRazorPages(options =>
{
options.Conventions.AddFolderApplicationModelConvention("/Movies", model => model.Filters.Add(new AuditPageFilter()
{
IncludeResponseBody = true
}));
});
}
Alternatively, if you want to setup the audit on a particular page and/or don't want to add the filter as a global filter,
you can override the OnPageHandlerExecutionAsync
on your page model and manually call the same method
on an AuditPageFilter
instance:
public class YourPageModel : PageModel
{
private readonly AuditPageFilter _pageFilter = new AuditPageFilter() { IncludeHeaders = true };
public override async Task OnPageHandlerExecutionAsync(PageHandlerExecutingContext context, PageHandlerExecutionDelegate next)
{
await _pageFilter.OnPageHandlerExecutionAsync(context, next);
}
// ...
}
Configuration
Output
The MVC audit events are stored using a Data Provider. You can use one of the available data providers or implement your own. Please refer to the data providers section on Audit.NET documentation.
Settings
The AuditAttribute
can be configured with the following properties:
- EventType: A string that identifies the event type. Can contain the following placeholders:
- {controller}: replaced with the controller name (only for MVC).
- {action}: replaced with the action method name (or the display name for razor pages).
- {verb}: replaced with the HTTP verb used (GET, POST, etc).
- {area}: replaced with the area name (only for razor pages).
- {path}: replaced with the view path (only for razor pages).
- IncludeHeaders: Boolean to indicate whether to include the Http Request Headers or not.
- IncludeModel: Boolean to indicate whether to include the View Model or not.
- IncludeRequestBody: Boolean to indicate whether to include or exclude the request body from the logs. Default is false. (Check following note)
- IncludeResponseBody: Boolean to indicate whether to include response body or not. Default is false.
- SerializeActionParameters: Boolean to indicate whether the action arguments should be pre-serialized to the audit event. Default is false.
To configure the output persistence mechanism please see Event Output Configuration.
NOTE
When IncludeRequestBody is set to true you may need to enable rewind on the request body stream, otherwise the controller won't be able to read the request body more than once (by default it's a forwand-only stream that can be read only once). You can enable rewind on your startup logic with the following startup code:
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
app.Use(async (context, next) => {
context.Request.EnableBuffering();
await next();
});
}
Audit Ignore attribute
To selectively exclude certain controllers, action methods, action parameters or return values, you can decorate them with AuditIgnore
attribute.
For example:
[Audit(IncludeHeaders = true, IncludeModel = true)]
public class AccountController : Controller
{
[HttpGet]
[AuditIgnore]
public IEnumerable<string> GetAccounts()
{
// this action will not be audited
}
[HttpPost]
public IEnumerable<string> PostAccount(string user, [AuditIgnore]string password)
{
// password argument will not be audited
}
[HttpGet]
[return:AuditIgnore]
public IEnumerable<string> GetSecrets(string user)
{
// the response body of this action will not be audited
}
}
You can also decorate the razor pages classes, methods or arguments to be ignored on the audits:
public class IndexModel : PageModel
{
[return:AuditIgnore]
public IActionResult OnGet(string user)
{
// the response of this action will not be audited
}
[AuditIgnore]
public void OnDelete(string user)
{
// this action will not be audited
}
public async Task<IActionResult> OnPostAsync([AuditIgnore]string password)
{
// password argument will not be audited
}
}
Output details
The following table describes the Audit.Mvc output fields:
Field Name | Type | Description |
---|---|---|
TraceId | string | A unique identifier per request |
HttpMethod | string | HTTP method (GET, POST, etc) |
ControllerName | string | The controller name (or the area name for razor pages) |
ActionName | string | The action name (or the display name for razor pages) |
ViewName | string | The view name (if any) |
ViewPath | string | View physical path (if any) |
FormVariables | Object | Form-data input variables passed to the action |
ActionParameters | Object | The action parameters passed |
RequestBody | BodyContent | The request body (optional) |
ResponseBody | BodyContent | The response body (optional) |
UserName | string | Username on the HttpContext Identity |
RequestUrl | string | URL of the request |
IpAddress | string | Client IP address |
ResponseStatusCode | integer | HTTP response status code |
ResponseStatus | string | Response status description |
Headers | Object | HTTP Headers (optional) |
Model | Object | The model object returned by the controller (if any) (optional) |
ModelStateValid | boolean | Boolean to indicate if the model is valid |
ModelStateErrors | string | Error description when the model is invalid |
RedirectLocation | string | The redirect location (if any) |
Exception | string | The exception thrown details (if any) |
BodyContent
Field Name | Type | Description |
---|---|---|
Type | string | The body type reported |
Length | long? | The length of the body if reported |
Value | Object | The body content |
Customization
You can access the Audit Scope from the controller action by calling the Controller extension method GetCurrentAuditScope()
.
For example:
public class HomeController : Controller
{
[Audit]
public ActionResult Index(int id, string name)
{
//...
var auditScope = this.GetCurrentAuditScope();
auditScope.Comment("New comment from controller");
auditScope.SetCustomField("TestField", Guid.NewGuid());
//...
}
}
See Audit.NET documentation about Custom Field and Comments for more information.
Output Sample for Get operation
HomeController.Index
(GET) with params: id=1234567&name=test
{
"EventType": "Home/Index (GET)",
"Environment": {
...
},
"StartDate": "2016-08-22T18:31:14.6550924-05:00",
"EndDate": "2016-08-22T18:31:23.1834012-05:00",
"Duration": 8529,
"Action": {
"TraceId": "0HLFLQP4HGFAG_00000001",
"HttpMethod": "GET",
"ControllerName": "Home",
"ActionName": "Index",
"ViewName": "Index",
"ViewPath": "~/Views/Home/Index.cshtml",
"FormVariables": {},
"ActionParameters": {
"id": 1234567,
"name": "test",
},
"UserName": "federico@mycompany.com",
"RequestUrl": "/",
"IpAddress": "127.0.0.1",
"ResponseStatus": "200 OK",
"ResponseStatusCode": 200,
"ModelStateValid": true,
"RedirectLocation": null
}
}
Output Sample for Post operation
HomeController.TestPost
(POST) with body: id=1234567&name=test
{
"EventType": "InsertOrderAction",
"Environment": {
...
},
"StartDate": "2016-08-22T18:31:00.0020036-05:00",
"EndDate": "2016-08-22T18:31:15.1705128-05:00",
"Duration": 15000,
"Action": {
"TraceId": "0HLFLQP4HGFAG_00000002",
"HttpMethod": "POST",
"ControllerName": "Home",
"ActionName": "TestPost",
"FormVariables": {
"id": "1234567",
"name": "test"
},
"ActionParameters": {
"model": {
"id": 1234567,
"name": "test"
}
},
"UserName": "federico@mycompany.com",
"RequestUrl": "/Home/TestPost",
"IpAddress": "::1",
"ResponseStatus": "200 OK",
"ResponseStatusCode": 200,
"Headers": {
"Cache-Control": "max-age=0",
"Connection": "keep-alive",
"Content-Length": "24",
"Content-Type": "application/x-www-form-urlencoded",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "es-419,es;q=0.8",
"Host": "localhost:37341",
"Referer": "http://localhost:37341/",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743",
"Origin": "http://localhost:37341",
"Upgrade-Insecure-Requests": "1"
},
"ModelStateValid": false,
"ModelStateErrors": {
"Id": "The field Id must be between 0 and 9999."
},
"RedirectLocation": null
}
}
MVC template (dotnet new)
If you are creating an ASP.NET Core MVC project from scratch, you can use the dotnet new template provided on the library Audit.Mvc.Template. This allows to quickly generate an audit-enabled MVC project that can be used as a starting point for your project or as a working example.
To install the template on your system, just type:
dotnet new -i Audit.Mvc.Template
Once you install the template, you should see it on the dotnet new templates list with the name mvcaudit
as follows:
You can now create a new project on the current folder by running:
dotnet new mvcaudit
This will create a new Asp.NET Core 2.1 project.
To get help about the options:
dotnet new mvcaudit -h
Contribute
If you like this project please contribute in any of the following ways:
- Star this project on GitHub.
- Request a new feature or expose any bug you found by creating a new issue.
- Ask any questions about the library on StackOverflow.
- Subscribe to and use the Gitter Audit.NET channel.
- Support the project by becoming a Backer:
- Spread the word by blogging about it, or sharing it on social networks: <p class="share-buttons"> <a href="https://www.facebook.com/sharer/sharer.php?u=https://nuget.org/packages/Audit.NET/&t=Check+out+Audit.NET" target="_blank"> <img width="24" height="24" alt="Share this package on Facebook" src="https://nuget.org/Content/gallery/img/facebook.svg" / > </a> <a href="https://twitter.com/intent/tweet?url=https://nuget.org/packages/Audit.NET/&text=Check+out+Audit.NET" target="_blank"> <img width="24" height="24" alt="Tweet this package" src="https://nuget.org/Content/gallery/img/twitter.svg" /> </a> </p>
- Buy me a coffee via ko-fi:
<br/>
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
.NET Framework | net461 was computed. net462 is compatible. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETFramework 4.6.2
- Audit.NET (>= 25.0.6)
- Microsoft.AspNetCore.Mvc.Core (>= 2.2.0)
- Microsoft.AspNetCore.Mvc.RazorPages (>= 2.2.0)
- Microsoft.AspNetCore.Mvc.ViewFeatures (>= 2.2.0)
- System.Text.Json (>= 6.0.9)
-
.NETStandard 2.0
- Audit.NET (>= 25.0.6)
- Microsoft.AspNetCore.Mvc (>= 2.2.0)
- System.Text.Json (>= 6.0.9)
-
.NETStandard 2.1
- Audit.NET (>= 25.0.6)
- Microsoft.AspNetCore.Mvc (>= 2.2.0)
- System.Text.Json (>= 6.0.9)
-
net6.0
- Audit.NET (>= 25.0.6)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories (1)
Showing the top 1 popular GitHub repositories that depend on Audit.Mvc.Core:
Repository | Stars |
---|---|
thepirat000/Audit.NET
An extensible framework to audit executing operations in .NET and .NET Core.
|
Version | Downloads | Last updated |
---|---|---|
27.0.1 | 66 | 9/4/2024 |
27.0.0 | 110 | 9/3/2024 |
26.0.1 | 273 | 8/22/2024 |
26.0.0 | 8,181 | 7/19/2024 |
25.0.7 | 517 | 7/4/2024 |
25.0.6 | 186 | 6/24/2024 |
25.0.5 | 155 | 6/18/2024 |
25.0.4 | 13,490 | 3/24/2024 |
25.0.3 | 501 | 3/13/2024 |
25.0.2 | 124 | 3/12/2024 |
25.0.1 | 464 | 2/28/2024 |
25.0.0 | 5,418 | 2/16/2024 |
24.0.1 | 188 | 2/12/2024 |
24.0.0 | 101 | 2/12/2024 |
23.0.0 | 4,593 | 12/14/2023 |
22.1.0 | 141 | 12/9/2023 |
22.0.2 | 323 | 12/1/2023 |
22.0.1 | 5,265 | 11/16/2023 |
22.0.0 | 1,964 | 11/14/2023 |
21.1.0 | 1,299 | 10/9/2023 |
21.0.4 | 215 | 9/15/2023 |
21.0.3 | 1,562 | 7/9/2023 |
21.0.2 | 214 | 7/6/2023 |
21.0.1 | 2,184 | 5/27/2023 |
21.0.0 | 1,043 | 4/15/2023 |
20.2.4 | 2,131 | 3/27/2023 |
20.2.3 | 299 | 3/17/2023 |
20.2.2 | 257 | 3/14/2023 |
20.2.1 | 347 | 3/11/2023 |
20.2.0 | 297 | 3/7/2023 |
20.1.6 | 2,003 | 2/23/2023 |
20.1.5 | 811 | 2/9/2023 |
20.1.4 | 2,619 | 1/28/2023 |
20.1.3 | 1,616 | 12/21/2022 |
20.1.2 | 4,737 | 12/14/2022 |
20.1.1 | 396 | 12/12/2022 |
20.1.0 | 438 | 12/4/2022 |
20.0.4 | 1,322 | 11/30/2022 |
20.0.3 | 4,387 | 10/28/2022 |
20.0.2 | 2,332 | 10/26/2022 |
20.0.1 | 677 | 10/21/2022 |
20.0.0 | 1,315 | 10/1/2022 |
19.4.1 | 2,224 | 9/10/2022 |
19.4.0 | 645 | 9/2/2022 |
19.3.0 | 7,589 | 8/23/2022 |
19.2.2 | 1,403 | 8/11/2022 |
19.2.1 | 903 | 8/6/2022 |
19.2.0 | 2,388 | 7/24/2022 |
19.1.4 | 3,070 | 5/23/2022 |
19.1.3 | 626 | 5/22/2022 |
19.1.2 | 1,524 | 5/18/2022 |
19.1.1 | 4,113 | 4/28/2022 |
19.1.0 | 3,298 | 4/10/2022 |
19.0.7 | 2,298 | 3/13/2022 |
19.0.6 | 886 | 3/7/2022 |
19.0.5 | 4,500 | 1/28/2022 |
19.0.4 | 1,490 | 1/23/2022 |
19.0.3 | 1,545 | 12/14/2021 |
19.0.2 | 449 | 12/11/2021 |
19.0.1 | 2,178 | 11/20/2021 |
19.0.0 | 833 | 11/11/2021 |
19.0.0-rc.net60.2 | 883 | 9/26/2021 |
19.0.0-rc.net60.1 | 216 | 9/16/2021 |
18.1.6 | 9,008 | 9/26/2021 |
18.1.5 | 1,567 | 9/7/2021 |
18.1.4 | 550 | 9/6/2021 |
18.1.3 | 676 | 8/19/2021 |
18.1.2 | 777 | 8/8/2021 |
18.1.1 | 606 | 8/5/2021 |
18.1.0 | 1,200 | 8/1/2021 |
18.0.1 | 617 | 7/30/2021 |
18.0.0 | 702 | 7/26/2021 |
17.0.8 | 2,186 | 7/7/2021 |
17.0.7 | 855 | 6/16/2021 |
17.0.6 | 635 | 6/5/2021 |
17.0.5 | 660 | 5/28/2021 |
17.0.4 | 753 | 5/4/2021 |
17.0.3 | 749 | 5/1/2021 |
17.0.2 | 775 | 4/22/2021 |
17.0.1 | 621 | 4/18/2021 |
17.0.0 | 3,557 | 3/26/2021 |
16.5.6 | 798 | 3/25/2021 |
16.5.5 | 624 | 3/23/2021 |
16.5.4 | 2,366 | 3/9/2021 |
16.5.3 | 573 | 2/26/2021 |
16.5.2 | 621 | 2/23/2021 |
16.5.1 | 646 | 2/21/2021 |
16.5.0 | 977 | 2/17/2021 |
16.4.5 | 684 | 2/15/2021 |
16.4.4 | 1,133 | 2/5/2021 |
16.4.3 | 866 | 1/27/2021 |
16.4.2 | 705 | 1/22/2021 |
16.4.1 | 648 | 1/21/2021 |
16.4.0 | 718 | 1/11/2021 |
16.3.3 | 725 | 1/8/2021 |
16.3.2 | 686 | 1/3/2021 |
16.3.1 | 580 | 12/31/2020 |
16.3.0 | 600 | 12/30/2020 |
16.2.1 | 2,134 | 12/27/2020 |
16.2.0 | 8,868 | 10/13/2020 |
16.1.5 | 742 | 10/4/2020 |
16.1.4 | 2,351 | 9/17/2020 |
16.1.3 | 1,377 | 9/13/2020 |
16.1.2 | 701 | 9/9/2020 |
16.1.1 | 1,116 | 9/3/2020 |
16.1.0 | 860 | 8/19/2020 |
16.0.3 | 723 | 8/15/2020 |
16.0.2 | 923 | 8/9/2020 |
16.0.1 | 704 | 8/8/2020 |
16.0.0 | 653 | 8/7/2020 |
15.3.0 | 1,851 | 7/23/2020 |
15.2.3 | 2,941 | 7/14/2020 |
15.2.2 | 7,688 | 5/19/2020 |
15.2.1 | 1,053 | 5/12/2020 |
15.2.0 | 716 | 5/9/2020 |
15.1.1 | 700 | 5/4/2020 |
15.1.0 | 1,266 | 4/13/2020 |
15.0.5 | 5,697 | 3/18/2020 |
15.0.4 | 942 | 2/28/2020 |
15.0.3 | 687 | 2/26/2020 |
15.0.2 | 3,218 | 1/20/2020 |
15.0.1 | 818 | 1/10/2020 |
15.0.0 | 1,062 | 12/17/2019 |
14.9.1 | 2,765 | 11/30/2019 |
14.9.0 | 718 | 11/29/2019 |
14.8.1 | 756 | 11/26/2019 |
14.8.0 | 1,064 | 11/20/2019 |
14.7.0 | 2,137 | 10/9/2019 |
14.6.6 | 730 | 10/8/2019 |
14.6.5 | 1,235 | 9/27/2019 |
14.6.4 | 843 | 9/21/2019 |
14.6.3 | 5,231 | 8/12/2019 |
14.6.2 | 797 | 8/3/2019 |
14.6.1 | 824 | 8/3/2019 |
14.6.0 | 786 | 7/26/2019 |
14.5.7 | 1,196 | 7/18/2019 |
14.5.6 | 29,355 | 7/10/2019 |
14.5.5 | 6,961 | 7/1/2019 |
14.5.4 | 896 | 6/17/2019 |
14.5.3 | 865 | 6/5/2019 |
14.5.2 | 773 | 5/30/2019 |
14.5.1 | 1,213 | 5/28/2019 |
14.5.0 | 2,451 | 5/24/2019 |
14.4.0 | 1,621 | 5/22/2019 |
14.3.4 | 850 | 5/14/2019 |
14.3.3 | 830 | 5/9/2019 |
14.3.2 | 881 | 4/30/2019 |
14.3.1 | 893 | 4/27/2019 |
14.3.0 | 876 | 4/24/2019 |
14.2.3 | 3,139 | 4/17/2019 |
14.2.2 | 861 | 4/10/2019 |
14.2.1 | 5,965 | 4/5/2019 |
14.2.0 | 897 | 3/16/2019 |
14.1.1 | 972 | 3/8/2019 |
14.1.0 | 2,429 | 2/11/2019 |
14.0.4 | 997 | 1/31/2019 |
14.0.3 | 996 | 1/22/2019 |
14.0.2 | 1,367 | 12/15/2018 |
14.0.1 | 1,176 | 11/29/2018 |
14.0.0 | 1,033 | 11/19/2018 |
13.3.0 | 1,686 | 11/16/2018 |
13.2.2 | 1,027 | 11/15/2018 |
13.2.1 | 1,019 | 11/13/2018 |
13.2.0 | 1,071 | 10/31/2018 |
13.1.5 | 1,063 | 10/31/2018 |
13.1.4 | 1,028 | 10/25/2018 |
13.1.3 | 1,263 | 10/18/2018 |
13.1.2 | 1,347 | 9/12/2018 |
13.1.1 | 2,413 | 9/11/2018 |
13.1.0 | 1,047 | 9/11/2018 |
13.0.0 | 7,774 | 8/29/2018 |
12.3.6 | 1,118 | 8/29/2018 |
12.3.5 | 2,401 | 8/22/2018 |
12.3.4 | 1,104 | 8/21/2018 |
12.3.3 | 25,886 | 8/21/2018 |
12.3.2 | 1,156 | 8/20/2018 |
12.3.1 | 1,120 | 8/20/2018 |
12.3.0 | 1,070 | 8/20/2018 |
12.2.2 | 2,952 | 8/15/2018 |
12.2.1 | 1,258 | 8/9/2018 |
12.2.0 | 1,126 | 8/8/2018 |
12.1.11 | 3,710 | 7/30/2018 |
12.1.10 | 1,214 | 7/20/2018 |
12.1.9 | 1,288 | 7/10/2018 |
12.1.8 | 1,111 | 7/2/2018 |
12.1.7 | 1,142 | 6/7/2018 |
12.1.6 | 1,218 | 6/4/2018 |
12.1.5 | 1,196 | 6/2/2018 |
12.1.4 | 1,233 | 5/25/2018 |
12.1.3 | 2,581 | 5/16/2018 |
12.1.2 | 1,238 | 5/15/2018 |
12.1.1 | 1,361 | 5/14/2018 |
12.1.0 | 1,284 | 5/9/2018 |
12.0.7 | 1,219 | 5/5/2018 |
12.0.6 | 1,335 | 5/4/2018 |
12.0.5 | 1,170 | 5/3/2018 |
12.0.4 | 1,386 | 4/30/2018 |
12.0.3 | 1,336 | 4/30/2018 |
12.0.2 | 1,186 | 4/27/2018 |
12.0.1 | 1,250 | 4/25/2018 |
12.0.0 | 1,176 | 4/22/2018 |
11.2.0 | 1,158 | 4/11/2018 |
11.1.0 | 1,339 | 4/8/2018 |
11.0.8 | 1,381 | 3/26/2018 |
11.0.7 | 1,301 | 3/20/2018 |
11.0.6 | 1,981 | 3/7/2018 |
11.0.5 | 1,233 | 2/22/2018 |
11.0.4 | 1,347 | 2/14/2018 |
11.0.3 | 1,249 | 2/12/2018 |
11.0.2 | 1,238 | 2/9/2018 |
11.0.1 | 1,277 | 1/29/2018 |
11.0.0 | 1,259 | 1/15/2018 |
10.0.3 | 1,304 | 12/29/2017 |
10.0.2 | 1,219 | 12/26/2017 |
10.0.1 | 1,273 | 12/18/2017 |
10.0.0 | 1,269 | 12/18/2017 |