├── src ├── NetCoreWebApp │ ├── .bowerrc │ ├── wwwroot │ │ ├── js │ │ │ ├── site.js │ │ │ └── site.min.js │ │ ├── favicon.ico │ │ ├── lib │ │ │ ├── bootstrap │ │ │ │ ├── dist │ │ │ │ │ ├── fonts │ │ │ │ │ │ ├── glyphicons-halflings-regular.eot │ │ │ │ │ │ ├── glyphicons-halflings-regular.ttf │ │ │ │ │ │ ├── glyphicons-halflings-regular.woff │ │ │ │ │ │ └── glyphicons-halflings-regular.woff2 │ │ │ │ │ ├── js │ │ │ │ │ │ └── npm.js │ │ │ │ │ └── css │ │ │ │ │ │ └── bootstrap-theme.min.css.map │ │ │ │ ├── .bower.json │ │ │ │ └── LICENSE │ │ │ ├── jquery │ │ │ │ ├── .bower.json │ │ │ │ └── LICENSE.txt │ │ │ ├── jquery-validation │ │ │ │ ├── .bower.json │ │ │ │ ├── LICENSE.md │ │ │ │ └── dist │ │ │ │ │ ├── additional-methods.min.js │ │ │ │ │ └── jquery.validate.min.js │ │ │ └── jquery-validation-unobtrusive │ │ │ │ ├── .bower.json │ │ │ │ ├── jquery.validate.unobtrusive.min.js │ │ │ │ └── jquery.validate.unobtrusive.js │ │ ├── css │ │ │ ├── site.min.css │ │ │ └── site.css │ │ ├── _references.js │ │ └── images │ │ │ ├── banner2.svg │ │ │ ├── banner1.svg │ │ │ ├── banner3.svg │ │ │ └── banner4.svg │ ├── Views │ │ ├── _ViewStart.cshtml │ │ ├── Home │ │ │ ├── About.cshtml │ │ │ ├── Contact.cshtml │ │ │ └── Index.cshtml │ │ ├── _ViewImports.cshtml │ │ └── Shared │ │ │ ├── Error.cshtml │ │ │ └── _Layout.cshtml │ ├── bower.json │ ├── Models │ │ └── IndexSetting.cs │ ├── web.config │ ├── bundleconfig.json │ ├── Properties │ │ ├── launchSettings.json │ │ └── PublishProfiles │ │ │ ├── publish-publish.ps1 │ │ │ └── publish.pubxml │ ├── Program.cs │ ├── NetCoreWebApp.xproj │ ├── appsettings.json │ ├── project.json │ ├── Controllers │ │ └── HomeController.cs │ ├── Startup.cs │ └── Project_Readme.html ├── MQ │ ├── EventBusExtensions.cs │ ├── ObjectExtensions.cs │ ├── mqsettings.json │ ├── SubscribeOptions.cs │ ├── project.json │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── MQ.xproj │ ├── Internal │ │ ├── EventBusSettings.cs │ │ ├── AutofacServiceLocator.cs │ │ └── CacheManager.cs │ └── EventBus.cs ├── NetCoreApp.Logger.File │ ├── project.json │ ├── FileLoggerExtensions.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── NetCoreApp.Logger.File.xproj │ ├── FileLoggerSettings.cs │ ├── FileLogger.cs │ └── FileLoggerProvider.cs ├── MSServer │ ├── project.json │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── MSServer.xproj │ └── Program.cs └── MQClient │ ├── mqsettings.json │ ├── Properties │ └── AssemblyInfo.cs │ ├── appsettings.json │ ├── MQClient.xproj │ ├── project.json │ └── Program.cs ├── global.json ├── README.md ├── .vscode ├── tasks.json └── launch.json ├── .gitattributes ├── NetCoreWebApp.sln └── .gitignore /src/NetCoreWebApp/.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "wwwroot/lib" 3 | } 4 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/wwwroot/js/site.js: -------------------------------------------------------------------------------- 1 | // Write your Javascript code. 2 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/wwwroot/js/site.min.js: -------------------------------------------------------------------------------- 1 | // Write your Javascript code. -------------------------------------------------------------------------------- /src/NetCoreWebApp/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /global.json: -------------------------------------------------------------------------------- 1 | { 2 | "projects": [ "src", "test" ], 3 | "sdk": { 4 | "version": "1.0.0-preview2-003131" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czd890/NetCoreWebApp/HEAD/src/NetCoreWebApp/wwwroot/favicon.ico -------------------------------------------------------------------------------- /src/MQ/EventBusExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MQ 7 | { 8 | } 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NetCoreWebApp 2 | 学习asp.net core demo 所码之 3 | 4 | 1.通过参数启动项目,指定需要绑定的hosts 5 | 2.替换系统ioc框架为autofac 6 | 3.ioc注入appsettings自定义配置 7 | 4.ioc注入controller的三种方式 8 | 5.自定义日志写本地文件组件,参考系统自带的console实现方式。支持多文件写入。 9 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/Views/Home/About.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "About"; 3 | } 4 |

@ViewData["Title"].

5 |

@ViewData["Message"]

6 | 7 |

Use this area to provide additional information.

8 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czd890/NetCoreWebApp/HEAD/src/NetCoreWebApp/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /src/NetCoreWebApp/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czd890/NetCoreWebApp/HEAD/src/NetCoreWebApp/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /src/NetCoreWebApp/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using NetCoreWebApp 2 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 3 | @inject Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration TelemetryConfiguration 4 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czd890/NetCoreWebApp/HEAD/src/NetCoreWebApp/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /src/NetCoreWebApp/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/czd890/NetCoreWebApp/HEAD/src/NetCoreWebApp/wwwroot/lib/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /src/NetCoreWebApp/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "asp.net", 3 | "private": true, 4 | "dependencies": { 5 | "bootstrap": "3.3.6", 6 | "jquery": "2.2.0", 7 | "jquery-validation": "1.14.0", 8 | "jquery-validation-unobtrusive": "3.2.6" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/wwwroot/css/site.min.css: -------------------------------------------------------------------------------- 1 | body{padding-top:50px;padding-bottom:20px}.body-content{padding-left:15px;padding-right:15px}input,select,textarea{max-width:280px}.carousel-caption p{font-size:20px;line-height:1.4}.carousel-inner .item img[src$=".svg"]{width:100%}@media screen and (max-width:767px){.carousel-caption{display:none}} -------------------------------------------------------------------------------- /src/NetCoreWebApp/Models/IndexSetting.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace NetCoreWebApp.Models 7 | { 8 | public class IndexSetting 9 | { 10 | public string Title { get; set; } 11 | public string Desc { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/wwwroot/_references.js: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | /// 4 | /// 5 | /// 6 | /// 7 | -------------------------------------------------------------------------------- /src/NetCoreApp.Logger.File/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0-*", 3 | 4 | "dependencies": { 5 | "Microsoft.Extensions.Configuration.Abstractions": "1.1.0", 6 | "Microsoft.Extensions.Logging": "1.1.0", 7 | "NETStandard.Library": "1.6.1", 8 | "System.Threading.Thread": "4.3.0" 9 | }, 10 | 11 | "frameworks": { 12 | "netstandard1.6": { 13 | "imports": "dnxcore50" 14 | } 15 | } 16 | } 17 | 18 | -------------------------------------------------------------------------------- /src/MQ/ObjectExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Newtonsoft.Json; 6 | 7 | namespace System 8 | { 9 | public static class ObjectExtensions 10 | { 11 | public static string ToJson(this T obj, JsonSerializerSettings setting = null) 12 | { 13 | return Newtonsoft.Json.JsonConvert.SerializeObject(obj, typeof(T), setting); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/MSServer/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0-*", 3 | "buildOptions": { 4 | "emitEntryPoint": true 5 | }, 6 | 7 | "dependencies": { 8 | "Microsoft.NETCore.App": { 9 | "type": "platform", 10 | "version": "1.1.0" 11 | }, 12 | "MQ": "1.0.0-*", 13 | "RabbitMQ.Client": "4.1.1", 14 | "System.Text.Encoding": "4.3.0" 15 | }, 16 | 17 | "frameworks": { 18 | "netcoreapp1.0": { 19 | "imports": "dnxcore50" 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "0.1.0", 5 | "command": "dotnet", 6 | "isShellCommand": true, 7 | "args": [], 8 | "tasks": [ 9 | { 10 | "taskName": "build", 11 | "args": [ ], 12 | "isBuildCommand": true, 13 | "showOutput": "silent", 14 | "problemMatcher": "$msCompile" 15 | } 16 | ] 17 | } -------------------------------------------------------------------------------- /src/MQ/mqsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Hosts": [ 3 | { 4 | "Name": "default", 5 | "UserName": "user", 6 | "UserPassword": "user", 7 | "Address": "192.168.50.2", 8 | "Port": 5672, 9 | "VHost": "/", 10 | "Heartbeat": 60, 11 | "AutoRecovery": true 12 | } 13 | ], 14 | "Products": [ 15 | { 16 | "Id": "produt", 17 | "Host": "default" 18 | }, 19 | { 20 | "Id": "produtid", 21 | "Host": "default" 22 | }, 23 | { 24 | "Id": "productid" 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /src/MQClient/mqsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Hosts": [ 3 | { 4 | "Name": "default", 5 | "UserName": "user", 6 | "UserPassword": "user", 7 | "Address": "192.168.50.2", 8 | "Port": 5672, 9 | "VHost": "/", 10 | "Heartbeat": 60, 11 | "AutoRecovery": true 12 | } 13 | ], 14 | "Products": [ 15 | { 16 | "Id": "produt", 17 | "Host": "default" 18 | }, 19 | { 20 | "Id": "produtid", 21 | "Host": "default" 22 | }, 23 | { 24 | "Id": "productid" 25 | } 26 | ] 27 | } 28 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/Views/Home/Contact.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Contact"; 3 | } 4 |

@ViewData["Title"].

5 |

@ViewData["Message"]

6 | 7 |
8 | One Microsoft Way
9 | Redmond, WA 98052-6399
10 | P: 11 | 425.555.0100 12 |
13 | 14 |
15 | Support: Support@example.com
16 | Marketing: Marketing@example.com 17 |
18 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/wwwroot/lib/bootstrap/dist/js/npm.js: -------------------------------------------------------------------------------- 1 | // This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment. 2 | require('../../js/transition.js') 3 | require('../../js/alert.js') 4 | require('../../js/button.js') 5 | require('../../js/carousel.js') 6 | require('../../js/collapse.js') 7 | require('../../js/dropdown.js') 8 | require('../../js/modal.js') 9 | require('../../js/tooltip.js') 10 | require('../../js/popover.js') 11 | require('../../js/scrollspy.js') 12 | require('../../js/tab.js') 13 | require('../../js/affix.js') -------------------------------------------------------------------------------- /src/NetCoreWebApp/web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/wwwroot/lib/jquery/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery", 3 | "main": "dist/jquery.js", 4 | "license": "MIT", 5 | "ignore": [ 6 | "package.json" 7 | ], 8 | "keywords": [ 9 | "jquery", 10 | "javascript", 11 | "browser", 12 | "library" 13 | ], 14 | "homepage": "https://github.com/jquery/jquery-dist", 15 | "version": "2.2.0", 16 | "_release": "2.2.0", 17 | "_resolution": { 18 | "type": "version", 19 | "tag": "2.2.0", 20 | "commit": "6fc01e29bdad0964f62ef56d01297039cdcadbe5" 21 | }, 22 | "_source": "git://github.com/jquery/jquery-dist.git", 23 | "_target": "2.2.0", 24 | "_originalSource": "jquery" 25 | } -------------------------------------------------------------------------------- /src/NetCoreWebApp/bundleconfig.json: -------------------------------------------------------------------------------- 1 | // Configure bundling and minification for the project. 2 | // More info at https://go.microsoft.com/fwlink/?LinkId=808241 3 | [ 4 | { 5 | "outputFileName": "wwwroot/css/site.min.css", 6 | // An array of relative input file paths. Globbing patterns supported 7 | "inputFiles": [ 8 | "wwwroot/css/site.css" 9 | ] 10 | }, 11 | { 12 | "outputFileName": "wwwroot/js/site.min.js", 13 | "inputFiles": [ 14 | "wwwroot/js/site.js" 15 | ], 16 | // Optionally specify minification options 17 | "minify": { 18 | "enabled": true, 19 | "renameLocals": true 20 | }, 21 | // Optinally generate .map file 22 | "sourceMap": false 23 | } 24 | ] 25 | -------------------------------------------------------------------------------- /src/MQ/SubscribeOptions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MQ 7 | { 8 | public class SubscribeOptions 9 | { 10 | public MessageModel Model { get; set; } 11 | 12 | public static SubscribeOptions Default { get; } = new SubscribeOptions() 13 | { 14 | Model = MessageModel.Clustering 15 | }; 16 | } 17 | /// 18 | /// 消息消费方式 19 | /// 20 | public enum MessageModel 21 | { 22 | /// 23 | /// 广播消费 24 | /// 25 | Broadcasting = 1, 26 | /// 27 | /// 集群消费,默认方式 28 | /// 29 | Clustering = 2 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/MQ/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0-*", 3 | 4 | "dependencies": { 5 | "NETStandard.Library": "1.6.0", 6 | "Newtonsoft.Json": "7.0.1", 7 | "RabbitMQ.Client": "4.1.1", 8 | "System.Text.Encoding": "4.3.0", 9 | "System.Threading": "4.3.0", 10 | "System.Runtime.Serialization.Primitives": "4.1.1", 11 | "System.ComponentModel": "4.3.0", 12 | "Microsoft.Extensions.Configuration.Abstractions": "1.1.0", 13 | "Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.0", 14 | "CoreCompat.Microsoft.Practices.ServiceLocation": "1.3.0-r2", 15 | "Autofac": "4.2.1", 16 | "Microsoft.Extensions.Logging.Abstractions": "1.1.0" 17 | }, 18 | 19 | "frameworks": { 20 | "netstandard1.6": { 21 | "imports": "dnxcore50" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Error"; 3 | } 4 | 5 |

Error.

6 |

An error occurred while processing your request.

7 | 8 |

Development Mode

9 |

10 | Swapping to Development environment will display more detailed information about the error that occurred. 11 |

12 |

13 | Development environment should not be enabled in deployed applications, as it can result in sensitive information from exceptions being displayed to end users. For local debugging, development environment can be enabled by setting the ASPNETCORE_ENVIRONMENT environment variable to Development, and restarting the application. 14 |

15 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:17408/", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "Linux": "Linux", 16 | "ASPNETCORE_ENVIRONMENT": "Development" 17 | } 18 | }, 19 | "NetCoreWebApp": { 20 | "commandName": "Project", 21 | "launchBrowser": true, 22 | "launchUrl": "http://localhost:5000", 23 | "environmentVariables": { 24 | "ASPNETCORE_ENVIRONMENT": "Development" 25 | } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/NetCoreWebApp/Properties/PublishProfiles/publish-publish.ps1: -------------------------------------------------------------------------------- 1 | [cmdletbinding(SupportsShouldProcess=$true)] 2 | param($publishProperties=@{}, $packOutput, $pubProfilePath) 3 | 4 | # to learn more about this file visit https://go.microsoft.com/fwlink/?LinkId=524327 5 | 6 | try{ 7 | if ($publishProperties['ProjectGuid'] -eq $null){ 8 | $publishProperties['ProjectGuid'] = '61604e42-0cdb-4b8a-82e1-32a8c87db979' 9 | } 10 | 11 | $publishModulePath = Join-Path (Split-Path $MyInvocation.MyCommand.Path) 'publish-module.psm1' 12 | Import-Module $publishModulePath -DisableNameChecking -Force 13 | 14 | # call Publish-AspNet to perform the publish operation 15 | Publish-AspNet -publishProperties $publishProperties -packOutput $packOutput -pubProfilePath $pubProfilePath 16 | } 17 | catch{ 18 | "An error occurred during publish.`n{0}" -f $_.Exception.Message | Write-Error 19 | } -------------------------------------------------------------------------------- /src/NetCoreWebApp/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | padding-bottom: 20px; 4 | } 5 | 6 | /* Wrapping element */ 7 | /* Set some basic padding to keep content from hitting the edges */ 8 | .body-content { 9 | padding-left: 15px; 10 | padding-right: 15px; 11 | } 12 | 13 | /* Set widths on the form inputs since otherwise they're 100% wide */ 14 | input, 15 | select, 16 | textarea { 17 | max-width: 280px; 18 | } 19 | 20 | /* Carousel */ 21 | .carousel-caption p { 22 | font-size: 20px; 23 | line-height: 1.4; 24 | } 25 | 26 | /* Make .svg files in the carousel display properly in older browsers */ 27 | .carousel-inner .item img[src$=".svg"] 28 | { 29 | width: 100%; 30 | } 31 | 32 | /* Hide/rearrange for smaller screens */ 33 | @media screen and (max-width: 767px) { 34 | /* Hide captions */ 35 | .carousel-caption { 36 | display: none 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/MQ/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("MQ")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("e666614b-728c-48bf-a535-4b519a9a3459")] 20 | -------------------------------------------------------------------------------- /src/MQClient/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("MQClient")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("c6425af8-d448-4731-8f9e-c876bddfbc39")] 20 | -------------------------------------------------------------------------------- /src/MSServer/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("MSServer")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("b6730ac2-8bda-4d01-b5ce-0b3222cd615d")] 20 | -------------------------------------------------------------------------------- /src/NetCoreApp.Logger.File/FileLoggerExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.IO; 6 | using Microsoft.Extensions.Configuration; 7 | using NetCoreApp.Logger.File; 8 | 9 | namespace Microsoft.Extensions.Logging 10 | { 11 | public static class FileLoggerExtensions 12 | { 13 | //add 日志文件创建规则,分割规则,格式化规则,过滤规则 to appsettings.json 14 | public static ILoggerFactory AddFile(this ILoggerFactory factory, IConfiguration configuration) 15 | { 16 | return AddFile(factory, new FileLoggerSettings(configuration)); 17 | } 18 | public static ILoggerFactory AddFile(this ILoggerFactory factory, FileLoggerSettings fileLoggerSettings) 19 | { 20 | factory.AddProvider(new FileLoggerProvider(fileLoggerSettings)); 21 | return factory; 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/NetCoreWebApp/Properties/PublishProfiles/publish.pubxml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | FileSystem 9 | Release 10 | Any CPU 11 | 12 | True 13 | False 14 | netcoreapp1.0 15 | True 16 | .\bin\PublishOutput 17 | False 18 | 19 | -------------------------------------------------------------------------------- /src/NetCoreApp.Logger.File/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyConfiguration("")] 9 | [assembly: AssemblyCompany("")] 10 | [assembly: AssemblyProduct("NetCoreApp.Logger.File")] 11 | [assembly: AssemblyTrademark("")] 12 | 13 | // Setting ComVisible to false makes the types in this assembly not visible 14 | // to COM components. If you need to access a type in this assembly from 15 | // COM, set the ComVisible attribute to true on that type. 16 | [assembly: ComVisible(false)] 17 | 18 | // The following GUID is for the ID of the typelib if this project is exposed to COM 19 | [assembly: Guid("03616715-5482-4f5c-921b-a4dda9793ddc")] 20 | -------------------------------------------------------------------------------- /src/MQClient/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | //写本地log文件 3 | //已创建logger的categoryName区分配置。可配置多规则多文件写入 4 | "FileLogging": { 5 | // 相对路径:log:current path+'\log' 6 | // 绝对路径:C://log 7 | // linux 绝对路径:/var/log/netcorewebapp 8 | //多环境部署,可以使用环境变量配置文件方式。 9 | "DefaultPath": "log", //默认文件地址 10 | "DefaultMaxMB": 500, //默认最大文件大小 11 | "DefaultFileName": "yyyyMMdd", //默认文件名字 12 | "DefaultRollingType": "Day", //默认文件新建方式 13 | //过滤器,以.分割,逐层匹配 14 | "LogLevel": { 15 | "Default": "Debug", 16 | "System": "Information", 17 | "Microsoft": "Information", 18 | "NetCoreWebApp": "Debug", 19 | "Test.NewFile": "Debug" 20 | }, 21 | //log需要写入的文件。 22 | "Path": { 23 | "Test.NewFile": "log/secfile" 24 | }, 25 | //log名字 26 | "FileName": { 27 | "Test.NewFile": "yyyyMMddHH" 28 | }, 29 | //文件新建方式,未实现 30 | "RollingType": { 31 | "Test.NewFile": "Minute" 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Hosting; 7 | using Microsoft.Extensions.Configuration; 8 | using Microsoft.Extensions.Logging; 9 | 10 | namespace NetCoreWebApp 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | 17 | //args 18 | //dotnet NetCoreWebApp.dll --server.urls="http://localhost:5000/;http://localhost:5001/" 19 | var config = new ConfigurationBuilder() 20 | .AddCommandLine(args) 21 | .Build(); 22 | 23 | var host = new WebHostBuilder() 24 | .UseConfiguration(config) 25 | .UseKestrel() 26 | .UseContentRoot(Directory.GetCurrentDirectory()) 27 | .UseIISIntegration() 28 | .UseStartup() 29 | .Build(); 30 | 31 | host.Run(); 32 | 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/wwwroot/lib/jquery-validation/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-validation", 3 | "homepage": "http://jqueryvalidation.org/", 4 | "repository": { 5 | "type": "git", 6 | "url": "git://github.com/jzaefferer/jquery-validation.git" 7 | }, 8 | "authors": [ 9 | "Jörn Zaefferer " 10 | ], 11 | "description": "Form validation made easy", 12 | "main": "dist/jquery.validate.js", 13 | "keywords": [ 14 | "forms", 15 | "validation", 16 | "validate" 17 | ], 18 | "license": "MIT", 19 | "ignore": [ 20 | "**/.*", 21 | "node_modules", 22 | "bower_components", 23 | "test", 24 | "demo", 25 | "lib" 26 | ], 27 | "dependencies": { 28 | "jquery": ">= 1.7.2" 29 | }, 30 | "version": "1.14.0", 31 | "_release": "1.14.0", 32 | "_resolution": { 33 | "type": "version", 34 | "tag": "1.14.0", 35 | "commit": "c1343fb9823392aa9acbe1c3ffd337b8c92fed48" 36 | }, 37 | "_source": "git://github.com/jzaefferer/jquery-validation.git", 38 | "_target": ">=1.8", 39 | "_originalSource": "jquery-validation" 40 | } -------------------------------------------------------------------------------- /src/NetCoreWebApp/wwwroot/lib/bootstrap/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bootstrap", 3 | "description": "The most popular front-end framework for developing responsive, mobile first projects on the web.", 4 | "keywords": [ 5 | "css", 6 | "js", 7 | "less", 8 | "mobile-first", 9 | "responsive", 10 | "front-end", 11 | "framework", 12 | "web" 13 | ], 14 | "homepage": "http://getbootstrap.com", 15 | "license": "MIT", 16 | "moduleType": "globals", 17 | "main": [ 18 | "less/bootstrap.less", 19 | "dist/js/bootstrap.js" 20 | ], 21 | "ignore": [ 22 | "/.*", 23 | "_config.yml", 24 | "CNAME", 25 | "composer.json", 26 | "CONTRIBUTING.md", 27 | "docs", 28 | "js/tests", 29 | "test-infra" 30 | ], 31 | "dependencies": { 32 | "jquery": "1.9.1 - 2" 33 | }, 34 | "version": "3.3.6", 35 | "_release": "3.3.6", 36 | "_resolution": { 37 | "type": "version", 38 | "tag": "v3.3.6", 39 | "commit": "81df608a40bf0629a1dc08e584849bb1e43e0b7a" 40 | }, 41 | "_source": "git://github.com/twbs/bootstrap.git", 42 | "_target": "3.3.6", 43 | "_originalSource": "bootstrap" 44 | } -------------------------------------------------------------------------------- /src/NetCoreWebApp/wwwroot/lib/bootstrap/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2015 Twitter, Inc 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/MQ/MQ.xproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14.0 5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 6 | 7 | 8 | 9 | 10 | e666614b-728c-48bf-a535-4b519a9a3459 11 | MQ 12 | .\obj 13 | .\bin\ 14 | v4.6.1 15 | 16 | 17 | 18 | 2.0 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/wwwroot/lib/jquery-validation/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright Jörn Zaefferer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /src/MQClient/MQClient.xproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14.0 5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 6 | 7 | 8 | 9 | 10 | c6425af8-d448-4731-8f9e-c876bddfbc39 11 | MQClient 12 | .\obj 13 | .\bin\ 14 | v4.6.1 15 | 16 | 17 | 18 | 2.0 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/MSServer/MSServer.xproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14.0 5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 6 | 7 | 8 | 9 | 10 | b6730ac2-8bda-4d01-b5ce-0b3222cd615d 11 | MSServer 12 | .\obj 13 | .\bin\ 14 | v4.6.1 15 | 16 | 17 | 18 | 2.0 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/NetCoreApp.Logger.File/NetCoreApp.Logger.File.xproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14.0 5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 6 | 7 | 8 | 9 | 10 | 03616715-5482-4f5c-921b-a4dda9793ddc 11 | NetCoreApp.Logger.File 12 | .\obj 13 | .\bin\ 14 | v4.6.1 15 | 16 | 17 | 18 | 2.0 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/MQClient/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1.0.0-*", 3 | "buildOptions": { 4 | "emitEntryPoint": true, 5 | "copyToOutput": [ "mqsettings.json", "appsettings.json" ] 6 | }, 7 | "publishOptions": { 8 | "include": [ "mqsettings.json", "appsettings.json" ] 9 | }, 10 | "dependencies": { 11 | "Autofac": "4.2.1", 12 | "CoreCompat.Microsoft.Practices.ServiceLocation": "1.3.0-r2", 13 | "Microsoft.EntityFrameworkCore": "1.1.0", 14 | "Microsoft.EntityFrameworkCore.SqlServer": "1.1.0", 15 | "Microsoft.Extensions.Configuration": "1.1.0", 16 | "Microsoft.Extensions.Configuration.FileExtensions": "1.1.0", 17 | "Microsoft.Extensions.Configuration.Json": "1.1.0", 18 | "Microsoft.Extensions.DependencyInjection": "1.1.0", 19 | "Microsoft.Extensions.Logging": "1.1.0", 20 | "Microsoft.Extensions.Logging.Console": "1.1.0", 21 | "Microsoft.Extensions.Logging.Debug": "1.1.0", 22 | "Microsoft.NETCore.App": { 23 | "type": "platform", 24 | "version": "1.1.0" 25 | }, 26 | "MQ": "1.0.0-*", 27 | "NetCoreApp.Logger.File": "1.0.0-*", 28 | "RabbitMQ.Client": "4.1.1", 29 | "System.Text.Encoding": "4.3.0", 30 | "System.Text.Encoding.CodePages": "4.3.0" 31 | }, 32 | "frameworks": { 33 | "netcoreapp1.0": { 34 | "imports": "dnxcore50" 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/wwwroot/lib/jquery-validation-unobtrusive/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-validation-unobtrusive", 3 | "version": "3.2.6", 4 | "homepage": "https://github.com/aspnet/jquery-validation-unobtrusive", 5 | "description": "Add-on to jQuery Validation to enable unobtrusive validation options in data-* attributes.", 6 | "main": [ 7 | "jquery.validate.unobtrusive.js" 8 | ], 9 | "ignore": [ 10 | "**/.*", 11 | "*.json", 12 | "*.md", 13 | "*.txt", 14 | "gulpfile.js" 15 | ], 16 | "keywords": [ 17 | "jquery", 18 | "asp.net", 19 | "mvc", 20 | "validation", 21 | "unobtrusive" 22 | ], 23 | "authors": [ 24 | "Microsoft" 25 | ], 26 | "license": "http://www.microsoft.com/web/webpi/eula/net_library_eula_enu.htm", 27 | "repository": { 28 | "type": "git", 29 | "url": "git://github.com/aspnet/jquery-validation-unobtrusive.git" 30 | }, 31 | "dependencies": { 32 | "jquery-validation": ">=1.8", 33 | "jquery": ">=1.8" 34 | }, 35 | "_release": "3.2.6", 36 | "_resolution": { 37 | "type": "version", 38 | "tag": "v3.2.6", 39 | "commit": "13386cd1b5947d8a5d23a12b531ce3960be1eba7" 40 | }, 41 | "_source": "git://github.com/aspnet/jquery-validation-unobtrusive.git", 42 | "_target": "3.2.6", 43 | "_originalSource": "jquery-validation-unobtrusive" 44 | } -------------------------------------------------------------------------------- /src/NetCoreWebApp/NetCoreWebApp.xproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14.0 5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 6 | 7 | 8 | 9 | 61604e42-0cdb-4b8a-82e1-32a8c87db979 10 | NetCoreWebApp 11 | .\obj 12 | .\bin\ 13 | v4.6.1 14 | 15 | 16 | 2.0 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ApplicationInsights": { 3 | "InstrumentationKey": "" 4 | }, 5 | "ConnectionStrings": { 6 | "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-NetCoreWebApp-166558c2-5cd2-4df4-a8cb-b9e4d17c55b1;Trusted_Connection=True;MultipleActiveResultSets=true" 7 | }, 8 | //测试ioc注入自定义配置 9 | "IndexSetting": { 10 | "Title": "Title...........", 11 | "Desc": "Desc............" 12 | }, 13 | "Logging": { 14 | "IncludeScopes": true, 15 | "LogLevel": { 16 | "Default": "Debug", 17 | "System": "Information", 18 | "Microsoft": "Information" 19 | } 20 | }, 21 | //写本地log文件 22 | //已创建logger的categoryName区分配置。可配置多规则多文件写入 23 | "FileLogging": { 24 | // 相对路径:log:current path+'\log' 25 | // 绝对路径:C://log 26 | // linux 绝对路径:/var/log/netcorewebapp 27 | //多环境部署,可以使用环境变量配置文件方式。 28 | "DefaultPath": "log", //默认文件地址 29 | "DefaultMaxMB": 500, //默认最大文件大小 30 | "DefaultFileName": "yyyyMMdd", //默认文件名字 31 | "DefaultRollingType": "Day", //默认文件新建方式 32 | //过滤器,以.分割,逐层匹配 33 | "LogLevel": { 34 | "Default": "Debug", 35 | "System": "Information", 36 | "Microsoft": "Information", 37 | "NetCoreWebApp": "Debug", 38 | "Test.NewFile": "Debug" 39 | }, 40 | //log需要写入的文件。 41 | "Path": { 42 | "Test.NewFile": "log/secfile" 43 | }, 44 | //log名字 45 | "FileName": { 46 | "Test.NewFile": "yyyyMMddHH" 47 | }, 48 | //文件新建方式,未实现 49 | "RollingType": { 50 | "Test.NewFile": "Minute" 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": ".NET Core Launch (console)", 6 | "type": "coreclr", 7 | "request": "launch", 8 | "preLaunchTask": "build", 9 | "program": "${workspaceRoot}/bin/Debug//", 10 | "args": [], 11 | "cwd": "${workspaceRoot}", 12 | "stopAtEntry": false, 13 | "externalConsole": false 14 | }, 15 | { 16 | "name": ".NET Core Launch (web)", 17 | "type": "coreclr", 18 | "request": "launch", 19 | "preLaunchTask": "build", 20 | "program": "${workspaceRoot}/bin/Debug//", 21 | "args": [], 22 | "cwd": "${workspaceRoot}", 23 | "stopAtEntry": false, 24 | "launchBrowser": { 25 | "enabled": true, 26 | "args": "${auto-detect-url}", 27 | "windows": { 28 | "command": "cmd.exe", 29 | "args": "/C start ${auto-detect-url}" 30 | }, 31 | "osx": { 32 | "command": "open" 33 | }, 34 | "linux": { 35 | "command": "xdg-open" 36 | } 37 | }, 38 | "env": { 39 | "ASPNETCORE_ENVIRONMENT": "Development" 40 | } 41 | }, 42 | { 43 | "name": ".NET Core Attach", 44 | "type": "coreclr", 45 | "request": "attach", 46 | "processId": 0 47 | } 48 | ] 49 | } -------------------------------------------------------------------------------- /src/NetCoreWebApp/wwwroot/lib/jquery/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright jQuery Foundation and other contributors, https://jquery.org/ 2 | 3 | This software consists of voluntary contributions made by many 4 | individuals. For exact contribution history, see the revision history 5 | available at https://github.com/jquery/jquery 6 | 7 | The following license applies to all parts of this software except as 8 | documented below: 9 | 10 | ==== 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining 13 | a copy of this software and associated documentation files (the 14 | "Software"), to deal in the Software without restriction, including 15 | without limitation the rights to use, copy, modify, merge, publish, 16 | distribute, sublicense, and/or sell copies of the Software, and to 17 | permit persons to whom the Software is furnished to do so, subject to 18 | the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be 21 | included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | ==== 32 | 33 | All files located in the node_modules and external directories are 34 | externally maintained libraries used by this software which have their 35 | own licenses; we recommend you read them, as their terms may differ from 36 | the terms above. 37 | -------------------------------------------------------------------------------- /src/MSServer/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using MQ; 7 | 8 | namespace MSServer 9 | { 10 | public class Program 11 | { 12 | public static void Main(string[] args) 13 | { 14 | //var factory = new RabbitMQ.Client.ConnectionFactory(); 15 | //factory.HostName = "192.168.50.2"; 16 | //factory.UserName = "user"; 17 | //factory.Password = "user"; 18 | //factory.VirtualHost = "/"; 19 | 20 | //using (var connection = factory.CreateConnection()) 21 | //{ 22 | // using (var channel = connection.CreateModel()) 23 | // { 24 | // //channel.ExchangeDeclare("ext1", "direct", true, false, null); 25 | // //channel.QueueDeclare("queue_1", true, false, false, null); 26 | // //channel.QueueBind("queue_1", "ext1", "route", null); 27 | 28 | // var prop = channel.CreateBasicProperties(); 29 | // prop.DeliveryMode = 2; 30 | // prop.Headers = new Dictionary(); 31 | // prop.Headers["msgid"] = Guid.NewGuid().ToString("N"); 32 | // var t = true; 33 | // int i = 0; 34 | // while (true) 35 | // { 36 | // i++; 37 | // channel.BasicPublish("amq.topic", ((t = !t) ? "route" : "route.a"), 38 | // true, prop, Encoding.UTF8.GetBytes(DateTime.Now.ToString())); 39 | // } 40 | // } 41 | //} 42 | 43 | for (int i = 0; i < 100; i++) 44 | { 45 | //EventBus.Publish("amq.topic", "PPP", "", DateTime.Now); 46 | EventBus.Publish("productid","guangbo", "", "", DateTime.Now); 47 | } 48 | 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/project.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "Microsoft.AspNetCore.Razor.Tools": { 4 | "version": "1.0.0-preview2-final", 5 | "type": "build" 6 | }, 7 | "NetCoreApp.Logger.File": "1.0.0-*", 8 | "Autofac.Extensions.DependencyInjection": "4.0.0", 9 | "BundlerMinifier.Core": "2.2.306", 10 | "Microsoft.ApplicationInsights.AspNetCore": "1.0.2", 11 | "Microsoft.AspNetCore.Diagnostics": "1.1.0", 12 | "Microsoft.AspNetCore.Mvc": "1.1.0", 13 | "Microsoft.AspNetCore.Server.IISIntegration": "1.1.0", 14 | "Microsoft.AspNetCore.Server.Kestrel": "1.1.0", 15 | "Microsoft.AspNetCore.StaticFiles": "1.1.0", 16 | "Microsoft.Extensions.Configuration.CommandLine": "1.1.0", 17 | "Microsoft.Extensions.Configuration.EnvironmentVariables": "1.1.0", 18 | "Microsoft.Extensions.Configuration.Json": "1.1.0", 19 | "Microsoft.Extensions.Logging": "1.1.0", 20 | "Microsoft.Extensions.Logging.Console": "1.1.0", 21 | "Microsoft.Extensions.Logging.Debug": "1.1.0", 22 | "Microsoft.Extensions.Options.ConfigurationExtensions": "1.1.0", 23 | "Microsoft.NETCore.App": { 24 | "type": "platform", 25 | "version": "1.1.0" 26 | }, 27 | "Microsoft.VisualStudio.Web.BrowserLink.Loader": "14.1.0", 28 | "System.Text.Encoding.CodePages": "4.3.0" 29 | }, 30 | 31 | "tools": { 32 | "Microsoft.AspNetCore.Razor.Tools": "1.0.0-preview2-final", 33 | "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final" 34 | }, 35 | 36 | "frameworks": { 37 | "netcoreapp1.0": { 38 | "imports": [ 39 | "dotnet5.6", 40 | "portable-net45+win8" 41 | ] 42 | } 43 | }, 44 | 45 | "buildOptions": { 46 | "emitEntryPoint": true, 47 | "preserveCompilationContext": true 48 | }, 49 | 50 | "runtimeOptions": { 51 | "configProperties": { 52 | "System.GC.Server": true 53 | } 54 | }, 55 | 56 | "publishOptions": { 57 | "include": [ 58 | "wwwroot", 59 | "Views", 60 | "Areas/**/Views", 61 | "appsettings.json", 62 | "web.config" 63 | ] 64 | }, 65 | 66 | "scripts": { 67 | "prepublish": [ "bower install", "dotnet bundle" ], 68 | "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ] 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/MQ/Internal/EventBusSettings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.Extensions.Configuration; 6 | using Microsoft.Extensions.Logging; 7 | using Microsoft.Extensions.Options; 8 | using Microsoft.Extensions.Primitives; 9 | 10 | namespace MQ.Internal 11 | { 12 | public class EventBusSettings 13 | { 14 | IConfiguration _configuration; 15 | public IChangeToken ChangeToken { get; private set; } 16 | ILogger _logger; 17 | public EventBusSettings(IConfiguration configuration, ILogger logger) 18 | { 19 | _configuration = configuration; 20 | this.ChangeToken = _configuration.GetReloadToken(); 21 | _logger = logger; 22 | 23 | 24 | List hostsOptions = new List(); 25 | ConfigurationBinder.Bind(_configuration.GetSection("Hosts"), hostsOptions); 26 | this.Hosts = hostsOptions.ToDictionary(p => p.Name, p => p); 27 | 28 | List productOptions = new List(); 29 | ConfigurationBinder.Bind(_configuration.GetSection("Products"), productOptions); 30 | this.Products = productOptions.ToDictionary(p => p.Id, p => p); 31 | 32 | _logger.LogInformation("init EventBus.Hosts:" + this.Hosts.ToJson()); 33 | _logger.LogInformation("init EventBus.Products:" + this.Products.ToJson()); 34 | } 35 | 36 | 37 | public Dictionary Hosts { get; set; } 38 | public Dictionary Products { get; set; } 39 | 40 | } 41 | 42 | public class EventBusHostOptions 43 | { 44 | public string Name { get; set; } = "default"; 45 | public string Address { get; set; } 46 | public string UserName { get; set; } = "guest"; 47 | public string UserPassword { get; set; } = "guest"; 48 | public string Port { get; set; } = "5672"; 49 | public string VHost { get; set; } = "/"; 50 | public int Heartbeat { get; set; } = 60; 51 | public bool AutoRecovery { get; set; } = true; 52 | } 53 | 54 | public class ProductOptions 55 | { 56 | public string Id { get; set; } 57 | public string Host { get; set; } = "default"; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /src/MQClient/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Microsoft.EntityFrameworkCore; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.DependencyInjection; 10 | using Microsoft.Extensions.Logging; 11 | using Microsoft.Practices.ServiceLocation; 12 | using MQ; 13 | using MQ.Internal; 14 | using RabbitMQ.Client; 15 | using RabbitMQ.Client.Content; 16 | using RabbitMQ.Client.Events; 17 | 18 | namespace MQClient 19 | { 20 | public class Program 21 | { 22 | static IServiceProvider sp; 23 | 24 | public static void Main(string[] args) 25 | { 26 | Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); 27 | 28 | var appsettings = new ConfigurationBuilder() 29 | .SetBasePath(System.IO.Directory.GetCurrentDirectory()) 30 | .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true).Build(); 31 | 32 | var mqsettings = new ConfigurationBuilder() 33 | .SetBasePath(System.IO.Directory.GetCurrentDirectory()) 34 | .AddJsonFile("mqsettings.json", optional: true, reloadOnChange: true).Build(); 35 | 36 | //---------------------------------------------------------------------------------------- 37 | 38 | 39 | ServiceCollection sc = new ServiceCollection(); 40 | sc.AddLogging(); 41 | 42 | sc.AddDbContext(ServiceLifetime.Transient); 43 | 44 | sp = sc.BuildServiceProvider(); 45 | //---------------------------------------------------------------------------------------- 46 | 47 | sp.GetService() 48 | .AddConsole() 49 | .AddDebug() 50 | .AddFile(appsettings.GetSection("FileLogging")); 51 | 52 | EventBus.Configure(mqsettings, sp); 53 | 54 | //主题发布订阅 55 | EventBus.Subscribe("produtid", "queue_3", time => 56 | { 57 | //Console.WriteLine(time); 58 | return true; 59 | }); 60 | 61 | 62 | //广播方式 63 | EventBus.Subscribe("produt", "guangbo", message => 64 | { 65 | Console.WriteLine(message); 66 | return true; 67 | }, new SubscribeOptions() { Model = MessageModel.Broadcasting }); 68 | 69 | EventBus.Subscribe("produt", "queue_1", message => 70 | { 71 | return true; 72 | }); 73 | 74 | 75 | Console.WriteLine("开始监听"); 76 | Console.ReadLine(); 77 | EventBus.Exit(); 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Mvc; 6 | using Microsoft.Extensions.DependencyInjection; 7 | using Microsoft.Extensions.Logging; 8 | using Microsoft.Extensions.Options; 9 | using NetCoreWebApp.Models; 10 | 11 | namespace NetCoreWebApp.Controllers 12 | { 13 | public class HomeController : Controller 14 | { 15 | 16 | //1.构造函数注入 17 | IOptions _ser; 18 | public HomeController(IOptions ser) 19 | { 20 | this._ser = ser; 21 | } 22 | public IActionResult Index2([FromServices]IOptions ser/*2.FromServices方式注入*/) 23 | { 24 | //2.这种方式比较适合,service不是在整个controller里面使用的情况下。只有某个单独的action需要。可以考虑使用这种方式 25 | _ser = ser; 26 | 27 | //3.IServiceProvider。ioc容器直接获取。 28 | //3.官方并不推荐使用,官方原话 29 | //Generally, you shouldn’t use these properties directly, 30 | //preferring instead to request the types your classes you require via your class’s constructor, 31 | //and letting the framework inject these dependencies. 32 | //This yields classes that are easier to test (see Testing) and are more loosely coupled. 33 | //大意是不应该使用这种方式,而应该使用构造函数的方式注入。因为能够方便测试并且设计上更加解耦。 34 | _ser = this.HttpContext.RequestServices.GetService>(); 35 | _ser.Value.Desc = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; 36 | return View(ser.Value); 37 | } 38 | 39 | public IActionResult Index([FromServices]ILogger logger, [FromServices]ILoggerFactory factory) 40 | { 41 | logger.LogInformation("begin"); 42 | using (logger.BeginScope("{0},{1}", "你是i", "SB!!")) 43 | { 44 | logger.LogError("error......................"); 45 | logger.LogInformation("LogInformation......................"); 46 | } 47 | logger.LogInformation("end"); 48 | 49 | 50 | factory.CreateLogger("Test.NewFile").LogError("!!!!!!!!!!!!!!!!!!!!!!!!!"); 51 | 52 | return this.Content(System.IO.Directory.GetCurrentDirectory()); 53 | } 54 | 55 | public IActionResult About() 56 | { 57 | ViewData["Message"] = "Your application description page."; 58 | 59 | return View(); 60 | } 61 | 62 | public IActionResult Contact() 63 | { 64 | ViewData["Message"] = "Your contact page."; 65 | 66 | return View(); 67 | } 68 | 69 | public IActionResult Error() 70 | { 71 | return View(); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/NetCoreApp.Logger.File/FileLoggerSettings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.Extensions.Configuration; 6 | using Microsoft.Extensions.Logging; 7 | using Microsoft.Extensions.Primitives; 8 | 9 | namespace NetCoreApp.Logger.File 10 | { 11 | public class FileLoggerSettings 12 | { 13 | IConfiguration _configuration; 14 | public IChangeToken ChangeToken { get; private set; } 15 | public FileLoggerSettings(IConfiguration configuration) 16 | { 17 | _configuration = configuration; 18 | this.ChangeToken = _configuration.GetReloadToken(); 19 | } 20 | 21 | public string DefaultPath 22 | { 23 | get 24 | { 25 | return this._configuration["DefaultPath"]; 26 | } 27 | } 28 | 29 | public int DefaultMaxMB 30 | { 31 | get 32 | { 33 | return int.Parse(this._configuration["DefaultMaxMB"]); 34 | } 35 | } 36 | public string DefaultFileName 37 | { 38 | get { return this._configuration["DefaultFileName"]; } 39 | } 40 | 41 | public void Reload() 42 | { 43 | //update cache settings 44 | } 45 | 46 | public Tuple GetSwitch(string name) 47 | { 48 | var section = this._configuration.GetSection("LogLevel"); 49 | if (section != null) 50 | { 51 | LogLevel level; 52 | if (Enum.TryParse(section[name], true, out level)) 53 | return new Tuple(true, level); 54 | } 55 | return new Tuple(false, LogLevel.None); 56 | } 57 | public Tuple GetDiretoryPath(string name) 58 | { 59 | var section = this._configuration.GetSection("Path"); 60 | if (section!=null) 61 | { 62 | var path = section[name]; 63 | if (!String.IsNullOrEmpty(path)) 64 | { 65 | return new Tuple(true, path); 66 | } 67 | } 68 | return new Tuple(false, this.DefaultPath); 69 | } 70 | public Tuple GetFileName(string name) 71 | { 72 | var section = this._configuration.GetSection("FileName"); 73 | if (section != null) 74 | { 75 | var path = section[name]; 76 | if (!String.IsNullOrEmpty(path)) 77 | { 78 | return new Tuple(true, path); 79 | } 80 | } 81 | return new Tuple(false, this.DefaultFileName); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | @ViewData["Title"] - NetCoreWebApp 7 | 8 | 9 | 10 | 11 | 12 | 13 | 16 | 17 | 18 | @Html.ApplicationInsightsJavaScript(TelemetryConfiguration) 19 | 20 | 21 | 41 |
42 | @RenderBody() 43 |
44 |
45 |

© 2016 - NetCoreWebApp

46 |
47 |
48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 59 | 63 | 64 | 65 | 66 | @RenderSection("scripts", required: false) 67 | 68 | 69 | -------------------------------------------------------------------------------- /src/MQ/Internal/AutofacServiceLocator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Autofac; 7 | using Microsoft.Practices.ServiceLocation; 8 | 9 | namespace MQ.Internal 10 | { 11 | public class AutofacServiceLocator : ServiceLocatorImplBase 12 | { 13 | /// 14 | /// The from which services 15 | /// should be located. 16 | /// 17 | private readonly IComponentContext _container; 18 | 19 | /// 20 | /// Initializes a new instance of the class. 21 | /// 22 | /// 23 | /// The from which services 24 | /// should be located. 25 | /// 26 | /// 27 | /// Thrown if is . 28 | /// 29 | public AutofacServiceLocator(IComponentContext container) 30 | { 31 | if (container == null) 32 | { 33 | throw new ArgumentNullException("container"); 34 | } 35 | this._container = container; 36 | } 37 | 38 | /// 39 | /// Resolves the requested service instance. 40 | /// 41 | /// Type of instance requested. 42 | /// Name of registered service you want. May be . 43 | /// The requested service instance. 44 | /// 45 | /// Thrown if is . 46 | /// 47 | protected override object DoGetInstance(Type serviceType, string key) 48 | { 49 | if (serviceType == null) 50 | { 51 | throw new ArgumentNullException("serviceType"); 52 | } 53 | if (key == null) 54 | { 55 | return ResolutionExtensions.Resolve(this._container, serviceType); 56 | } 57 | return ResolutionExtensions.ResolveNamed(this._container, key, serviceType); 58 | } 59 | 60 | /// 61 | /// Resolves all requested service instances. 62 | /// 63 | /// Type of instance requested. 64 | /// Sequence of service instance objects. 65 | /// 66 | /// Thrown if is . 67 | /// 68 | protected override IEnumerable DoGetAllInstances(Type serviceType) 69 | { 70 | if (serviceType == null) 71 | { 72 | throw new ArgumentNullException("serviceType"); 73 | } 74 | Type type = typeof(IEnumerable).MakeGenericType(new Type[] 75 | { 76 | serviceType 77 | }); 78 | return Enumerable.Cast((IEnumerable)ResolutionExtensions.Resolve(this._container, type)); 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/Startup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Autofac; 7 | using Autofac.Extensions.DependencyInjection; 8 | using Microsoft.AspNetCore.Builder; 9 | using Microsoft.AspNetCore.Hosting; 10 | using Microsoft.Extensions.Configuration; 11 | using Microsoft.Extensions.DependencyInjection; 12 | using Microsoft.Extensions.Logging; 13 | using NetCoreWebApp.Models; 14 | 15 | namespace NetCoreWebApp 16 | { 17 | public class Startup 18 | { 19 | public Startup(IHostingEnvironment env) 20 | { 21 | var builder = new ConfigurationBuilder() 22 | .SetBasePath(env.ContentRootPath) 23 | .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) 24 | .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) 25 | .AddEnvironmentVariables(); 26 | //env.IsEnvironment("xxx") 27 | if (env.IsDevelopment()) 28 | { 29 | // This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately. 30 | builder.AddApplicationInsightsSettings(developerMode: true); 31 | } 32 | Configuration = builder.Build(); 33 | } 34 | 35 | public IConfigurationRoot Configuration { get; } 36 | 37 | // This method gets called by the runtime. Use this method to add services to the container. 38 | public IServiceProvider ConfigureServices(IServiceCollection services) 39 | { 40 | // Add framework services. 41 | services.AddApplicationInsightsTelemetry(Configuration); 42 | 43 | services.AddMvc(); 44 | 45 | 46 | services.AddOptions(); 47 | //增加poco的配置服务 48 | services.Configure(this.Configuration.GetSection("IndexSetting")); 49 | 50 | //add autofac 51 | var containerBuilder = new ContainerBuilder(); 52 | containerBuilder.Populate(services); 53 | //Register for assembly,modules,config file 54 | //............. 55 | var container = containerBuilder.Build(); 56 | return container.Resolve(); 57 | 58 | } 59 | // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 60 | public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 61 | { 62 | loggerFactory.AddConsole(Configuration.GetSection("Logging")); 63 | loggerFactory.AddDebug(); 64 | loggerFactory.AddFile(this.Configuration.GetSection("FileLogging")); 65 | 66 | Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); 67 | 68 | app.UseApplicationInsightsRequestTelemetry(); 69 | 70 | if (env.IsDevelopment()) 71 | { 72 | app.UseDeveloperExceptionPage(); 73 | app.UseBrowserLink(); 74 | } 75 | else 76 | { 77 | app.UseExceptionHandler("/Home/Error"); 78 | } 79 | 80 | app.UseApplicationInsightsExceptionTelemetry(); 81 | 82 | app.UseStaticFiles(); 83 | 84 | app.UseMvc(routes => 85 | { 86 | routes.MapRoute( 87 | name: "default", 88 | template: "{controller=Home}/{action=Index}/{id?}"); 89 | }); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /NetCoreWebApp.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{27FD4CA6-58E6-4A77-A4A4-235584780305}" 7 | EndProject 8 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A8EEA05C-1F7E-459C-A925-5B23C240D7B0}" 9 | ProjectSection(SolutionItems) = preProject 10 | global.json = global.json 11 | EndProjectSection 12 | EndProject 13 | Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "NetCoreWebApp", "src\NetCoreWebApp\NetCoreWebApp.xproj", "{61604E42-0CDB-4B8A-82E1-32A8C87DB979}" 14 | EndProject 15 | Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "NetCoreApp.Logger.File", "src\NetCoreApp.Logger.File\NetCoreApp.Logger.File.xproj", "{03616715-5482-4F5C-921B-A4DDA9793DDC}" 16 | EndProject 17 | Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "MQ", "src\MQ\MQ.xproj", "{E666614B-728C-48BF-A535-4B519A9A3459}" 18 | EndProject 19 | Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "MQClient", "src\MQClient\MQClient.xproj", "{C6425AF8-D448-4731-8F9E-C876BDDFBC39}" 20 | EndProject 21 | Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "MSServer", "src\MSServer\MSServer.xproj", "{B6730AC2-8BDA-4D01-B5CE-0B3222CD615D}" 22 | EndProject 23 | Global 24 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 25 | Debug|Any CPU = Debug|Any CPU 26 | Release|Any CPU = Release|Any CPU 27 | EndGlobalSection 28 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 29 | {61604E42-0CDB-4B8A-82E1-32A8C87DB979}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 30 | {61604E42-0CDB-4B8A-82E1-32A8C87DB979}.Debug|Any CPU.Build.0 = Debug|Any CPU 31 | {61604E42-0CDB-4B8A-82E1-32A8C87DB979}.Release|Any CPU.ActiveCfg = Release|Any CPU 32 | {61604E42-0CDB-4B8A-82E1-32A8C87DB979}.Release|Any CPU.Build.0 = Release|Any CPU 33 | {03616715-5482-4F5C-921B-A4DDA9793DDC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 34 | {03616715-5482-4F5C-921B-A4DDA9793DDC}.Debug|Any CPU.Build.0 = Debug|Any CPU 35 | {03616715-5482-4F5C-921B-A4DDA9793DDC}.Release|Any CPU.ActiveCfg = Release|Any CPU 36 | {03616715-5482-4F5C-921B-A4DDA9793DDC}.Release|Any CPU.Build.0 = Release|Any CPU 37 | {E666614B-728C-48BF-A535-4B519A9A3459}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 38 | {E666614B-728C-48BF-A535-4B519A9A3459}.Debug|Any CPU.Build.0 = Debug|Any CPU 39 | {E666614B-728C-48BF-A535-4B519A9A3459}.Release|Any CPU.ActiveCfg = Release|Any CPU 40 | {E666614B-728C-48BF-A535-4B519A9A3459}.Release|Any CPU.Build.0 = Release|Any CPU 41 | {C6425AF8-D448-4731-8F9E-C876BDDFBC39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 42 | {C6425AF8-D448-4731-8F9E-C876BDDFBC39}.Debug|Any CPU.Build.0 = Debug|Any CPU 43 | {C6425AF8-D448-4731-8F9E-C876BDDFBC39}.Release|Any CPU.ActiveCfg = Release|Any CPU 44 | {C6425AF8-D448-4731-8F9E-C876BDDFBC39}.Release|Any CPU.Build.0 = Release|Any CPU 45 | {B6730AC2-8BDA-4D01-B5CE-0B3222CD615D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 46 | {B6730AC2-8BDA-4D01-B5CE-0B3222CD615D}.Debug|Any CPU.Build.0 = Debug|Any CPU 47 | {B6730AC2-8BDA-4D01-B5CE-0B3222CD615D}.Release|Any CPU.ActiveCfg = Release|Any CPU 48 | {B6730AC2-8BDA-4D01-B5CE-0B3222CD615D}.Release|Any CPU.Build.0 = Release|Any CPU 49 | EndGlobalSection 50 | GlobalSection(SolutionProperties) = preSolution 51 | HideSolutionNode = FALSE 52 | EndGlobalSection 53 | GlobalSection(NestedProjects) = preSolution 54 | {61604E42-0CDB-4B8A-82E1-32A8C87DB979} = {27FD4CA6-58E6-4A77-A4A4-235584780305} 55 | {03616715-5482-4F5C-921B-A4DDA9793DDC} = {27FD4CA6-58E6-4A77-A4A4-235584780305} 56 | {E666614B-728C-48BF-A535-4B519A9A3459} = {27FD4CA6-58E6-4A77-A4A4-235584780305} 57 | {C6425AF8-D448-4731-8F9E-C876BDDFBC39} = {27FD4CA6-58E6-4A77-A4A4-235584780305} 58 | {B6730AC2-8BDA-4D01-B5CE-0B3222CD615D} = {27FD4CA6-58E6-4A77-A4A4-235584780305} 59 | EndGlobalSection 60 | EndGlobal 61 | -------------------------------------------------------------------------------- /src/NetCoreApp.Logger.File/FileLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.Extensions.Logging; 6 | using System.IO; 7 | using System.Text; 8 | using System.Threading; 9 | 10 | namespace NetCoreApp.Logger.File 11 | { 12 | public class FileLogger : ILogger 13 | { 14 | static protected string delimiter = new string(new char[] { (char)1 }); 15 | public FileLogger(string categoryName) 16 | { 17 | this.Name = categoryName; 18 | } 19 | class Disposable : IDisposable 20 | { 21 | public void Dispose() 22 | { 23 | } 24 | } 25 | Disposable _DisposableInstance = new Disposable(); 26 | public IDisposable BeginScope(TState state) 27 | { 28 | return _DisposableInstance; 29 | } 30 | public bool IsEnabled(LogLevel logLevel) 31 | { 32 | return this.MinLevel <= logLevel; 33 | } 34 | public void Reload() 35 | { 36 | _Expires = true; 37 | } 38 | 39 | public string Name { get; private set; } 40 | 41 | public LogLevel MinLevel { get; set; } 42 | public string FileDiretoryPath { get; set; } 43 | public string FileNameTemplate { get; set; } 44 | public void Log(LogLevel logLevel, EventId eventId, TState state, Exception exception, Func formatter) 45 | { 46 | if (!this.IsEnabled(logLevel)) 47 | return; 48 | var msg = formatter(state, exception); 49 | this.Write(logLevel, eventId, msg, exception); 50 | } 51 | void Write(LogLevel logLevel, EventId eventId, string message, Exception ex) 52 | { 53 | EnsureInitFile(); 54 | 55 | //TODO 提高效率 队列写!!! 56 | var log = String.Concat(DateTime.Now.ToString("HH:mm:ss"), '[', logLevel.ToString(), ']', '[', 57 | Thread.CurrentThread.ManagedThreadId.ToString(), ',', eventId.Id.ToString(), ',', eventId.Name, ']', 58 | delimiter, message, delimiter, ex?.ToString()); 59 | lock (this) 60 | { 61 | this._sw.WriteLine(log); 62 | } 63 | } 64 | 65 | bool _Expires = true; 66 | string _FileName; 67 | protected StreamWriter _sw; 68 | void EnsureInitFile() 69 | { 70 | if (CheckNeedCreateNewFile()) 71 | { 72 | lock (this) 73 | { 74 | if (CheckNeedCreateNewFile()) 75 | { 76 | InitFile(); 77 | _Expires = false; 78 | } 79 | } 80 | } 81 | } 82 | bool CheckNeedCreateNewFile() 83 | { 84 | if (_Expires) 85 | { 86 | return true; 87 | } 88 | //TODO 使用 RollingType判断是否需要创建文件。提高效率!!! 89 | if (_FileName != DateTime.Now.ToString(this.FileNameTemplate)) 90 | { 91 | return true; 92 | } 93 | return false; 94 | } 95 | void InitFile() 96 | { 97 | if (!Directory.Exists(this.FileDiretoryPath)) 98 | { 99 | Directory.CreateDirectory(this.FileDiretoryPath); 100 | } 101 | var path = ""; 102 | int i = 0; 103 | do 104 | { 105 | _FileName = DateTime.Now.ToString(this.FileNameTemplate); 106 | path = Path.Combine(this.FileDiretoryPath, _FileName + "_" + i + ".log"); 107 | i++; 108 | } while (System.IO.File.Exists(path)); 109 | var oldsw = _sw; 110 | _sw = new StreamWriter(new FileStream(path, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.Read), Encoding.UTF8); 111 | _sw.AutoFlush = true; 112 | if (oldsw != null) 113 | { 114 | try 115 | { 116 | _sw.Flush(); 117 | _sw.Dispose(); 118 | } 119 | catch 120 | { 121 | } 122 | } 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/MQ/Internal/CacheManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using RabbitMQ.Client; 6 | 7 | namespace MQ.Internal 8 | { 9 | internal class CacheManager : IDisposable 10 | { 11 | 12 | Dictionary rabittmqConn = new Dictionary(); 13 | Dictionary rabittmqChannel = new Dictionary(); 14 | EventBusSettings _settings; 15 | 16 | public IConnection GetConnection(string productId) 17 | { 18 | if (!rabittmqConn.ContainsKey(productId)) 19 | { 20 | if (!_settings.Products.ContainsKey(productId)) 21 | { 22 | throw new Exception(productId + " product setting not found"); 23 | } 24 | var hKey = _settings.Products[productId].Host; 25 | if (!_settings.Hosts.ContainsKey(hKey)) 26 | { 27 | throw new Exception(hKey + " host setting not found"); 28 | } 29 | var option = _settings.Hosts[hKey]; 30 | var factory = new RabbitMQ.Client.ConnectionFactory(); 31 | factory.HostName = option.Address; 32 | factory.UserName = option.UserName; 33 | factory.Password = option.UserPassword; 34 | factory.VirtualHost = option.VHost; 35 | factory.RequestedHeartbeat = (ushort)option.Heartbeat; 36 | factory.AutomaticRecoveryEnabled = option.AutoRecovery; 37 | 38 | rabittmqConn[productId] = factory.CreateConnection(); 39 | } 40 | 41 | 42 | return rabittmqConn[productId]; 43 | } 44 | 45 | public IModel GetChannel(string productId) 46 | { 47 | 48 | //return GetConnection(productId).CreateModel(); 49 | 50 | if (!rabittmqChannel.ContainsKey(productId)) 51 | { 52 | var conn = GetConnection(productId); 53 | rabittmqChannel[productId] = conn.CreateModel(); 54 | } 55 | return rabittmqChannel[productId]; 56 | } 57 | 58 | public void Configure(EventBusSettings settings) 59 | { 60 | _settings = settings; 61 | } 62 | 63 | #region IDisposable Support 64 | private bool disposedValue = false; // 要检测冗余调用 65 | 66 | protected virtual void Dispose(bool disposing) 67 | { 68 | if (!disposedValue) 69 | { 70 | if (disposing) 71 | { 72 | // TODO: 释放托管状态(托管对象)。 73 | 74 | 75 | try 76 | { 77 | foreach (var item in rabittmqChannel) 78 | { 79 | try 80 | { 81 | item.Value.Close(); 82 | item.Value.Dispose(); 83 | } 84 | catch (Exception) 85 | { 86 | 87 | throw; 88 | } 89 | } 90 | foreach (var item in rabittmqConn) 91 | { 92 | try 93 | { 94 | item.Value.Close(); 95 | item.Value.Dispose(); 96 | } 97 | catch (Exception) 98 | { 99 | 100 | throw; 101 | } 102 | } 103 | } 104 | catch (Exception) 105 | { 106 | 107 | throw; 108 | } 109 | } 110 | 111 | // TODO: 释放未托管的资源(未托管的对象)并在以下内容中替代终结器。 112 | // TODO: 将大型字段设置为 null。 113 | 114 | disposedValue = true; 115 | } 116 | } 117 | 118 | // TODO: 仅当以上 Dispose(bool disposing) 拥有用于释放未托管资源的代码时才替代终结器。 119 | // ~CacheManager() { 120 | // // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。 121 | // Dispose(false); 122 | // } 123 | 124 | // 添加此代码以正确实现可处置模式。 125 | void IDisposable.Dispose() 126 | { 127 | // 请勿更改此代码。将清理代码放入以上 Dispose(bool disposing) 中。 128 | Dispose(true); 129 | // TODO: 如果在以上内容中替代了终结器,则取消注释以下行。 130 | // GC.SuppressFinalize(this); 131 | } 132 | #endregion 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | [Xx]64/ 19 | [Xx]86/ 20 | [Bb]uild/ 21 | bld/ 22 | [Bb]in/ 23 | [Oo]bj/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | artifacts/ 46 | 47 | *_i.c 48 | *_p.c 49 | *_i.h 50 | *.ilk 51 | *.meta 52 | *.obj 53 | *.pch 54 | *.pdb 55 | *.pgc 56 | *.pgd 57 | *.rsp 58 | *.sbr 59 | *.tlb 60 | *.tli 61 | *.tlh 62 | *.tmp 63 | *.tmp_proj 64 | *.log 65 | *.vspscc 66 | *.vssscc 67 | .builds 68 | *.pidb 69 | *.svclog 70 | *.scc 71 | 72 | # Chutzpah Test files 73 | _Chutzpah* 74 | 75 | # Visual C++ cache files 76 | ipch/ 77 | *.aps 78 | *.ncb 79 | *.opendb 80 | *.opensdf 81 | *.sdf 82 | *.cachefile 83 | *.VC.db 84 | 85 | # Visual Studio profiler 86 | *.psess 87 | *.vsp 88 | *.vspx 89 | *.sap 90 | 91 | # TFS 2012 Local Workspace 92 | $tf/ 93 | 94 | # Guidance Automation Toolkit 95 | *.gpState 96 | 97 | # ReSharper is a .NET coding add-in 98 | _ReSharper*/ 99 | *.[Rr]e[Ss]harper 100 | *.DotSettings.user 101 | 102 | # JustCode is a .NET coding add-in 103 | .JustCode 104 | 105 | # TeamCity is a build add-in 106 | _TeamCity* 107 | 108 | # DotCover is a Code Coverage Tool 109 | *.dotCover 110 | 111 | # NCrunch 112 | _NCrunch_* 113 | .*crunch*.local.xml 114 | nCrunchTemp_* 115 | 116 | # MightyMoose 117 | *.mm.* 118 | AutoTest.Net/ 119 | 120 | # Web workbench (sass) 121 | .sass-cache/ 122 | 123 | # Installshield output folder 124 | [Ee]xpress/ 125 | 126 | # DocProject is a documentation generator add-in 127 | DocProject/buildhelp/ 128 | DocProject/Help/*.HxT 129 | DocProject/Help/*.HxC 130 | DocProject/Help/*.hhc 131 | DocProject/Help/*.hhk 132 | DocProject/Help/*.hhp 133 | DocProject/Help/Html2 134 | DocProject/Help/html 135 | 136 | # Click-Once directory 137 | publish/ 138 | 139 | # Publish Web Output 140 | *.[Pp]ublish.xml 141 | *.azurePubxml 142 | 143 | # TODO: Un-comment the next line if you do not want to checkin 144 | # your web deploy settings because they may include unencrypted 145 | # passwords 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # NuGet Packages 150 | *.nupkg 151 | # The packages folder can be ignored because of Package Restore 152 | **/packages/* 153 | # except build/, which is used as an MSBuild target. 154 | !**/packages/build/ 155 | # Uncomment if necessary however generally it will be regenerated when needed 156 | #!**/packages/repositories.config 157 | # NuGet v3's project.json files produces more ignoreable files 158 | *.nuget.props 159 | *.nuget.targets 160 | 161 | # Microsoft Azure Build Output 162 | csx/ 163 | *.build.csdef 164 | 165 | # Microsoft Azure Emulator 166 | ecf/ 167 | rcf/ 168 | 169 | # Microsoft Azure ApplicationInsights config file 170 | ApplicationInsights.config 171 | 172 | # Windows Store app package directory 173 | AppPackages/ 174 | BundleArtifacts/ 175 | 176 | # Visual Studio cache files 177 | # files ending in .cache can be ignored 178 | *.[Cc]ache 179 | # but keep track of directories ending in .cache 180 | !*.[Cc]ache/ 181 | 182 | # Others 183 | ClientBin/ 184 | [Ss]tyle[Cc]op.* 185 | ~$* 186 | *~ 187 | *.dbmdl 188 | *.dbproj.schemaview 189 | *.pfx 190 | *.publishsettings 191 | node_modules/ 192 | orleans.codegen.cs 193 | 194 | # RIA/Silverlight projects 195 | Generated_Code/ 196 | 197 | # Backup & report files from converting an old project file 198 | # to a newer Visual Studio version. Backup files are not needed, 199 | # because we have git ;-) 200 | _UpgradeReport_Files/ 201 | Backup*/ 202 | UpgradeLog*.XML 203 | UpgradeLog*.htm 204 | 205 | # SQL Server files 206 | *.mdf 207 | *.ldf 208 | 209 | # Business Intelligence projects 210 | *.rdl.data 211 | *.bim.layout 212 | *.bim_*.settings 213 | 214 | # Microsoft Fakes 215 | FakesAssemblies/ 216 | 217 | # GhostDoc plugin setting file 218 | *.GhostDoc.xml 219 | 220 | # Node.js Tools for Visual Studio 221 | .ntvs_analysis.dat 222 | 223 | # Visual Studio 6 build log 224 | *.plg 225 | 226 | # Visual Studio 6 workspace options file 227 | *.opt 228 | 229 | # Visual Studio LightSwitch build output 230 | **/*.HTMLClient/GeneratedArtifacts 231 | **/*.DesktopClient/GeneratedArtifacts 232 | **/*.DesktopClient/ModelManifest.xml 233 | **/*.Server/GeneratedArtifacts 234 | **/*.Server/ModelManifest.xml 235 | _Pvt_Extensions 236 | 237 | # LightSwitch generated files 238 | GeneratedArtifacts/ 239 | ModelManifest.xml 240 | 241 | # Paket dependency manager 242 | .paket/paket.exe 243 | 244 | # FAKE - F# Make 245 | .fake/ -------------------------------------------------------------------------------- /src/NetCoreWebApp/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | ** Unobtrusive validation support library for jQuery and jQuery Validate 3 | ** Copyright (C) Microsoft Corporation. All rights reserved. 4 | */ 5 | !function(a){function e(a,e,n){a.rules[e]=n,a.message&&(a.messages[e]=a.message)}function n(a){return a.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}function t(a){return a.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function r(a){return a.substr(0,a.lastIndexOf(".")+1)}function i(a,e){return 0===a.indexOf("*.")&&(a=a.replace("*.",e)),a}function o(e,n){var r=a(this).find("[data-valmsg-for='"+t(n[0].name)+"']"),i=r.attr("data-valmsg-replace"),o=i?a.parseJSON(i)!==!1:null;r.removeClass("field-validation-valid").addClass("field-validation-error"),e.data("unobtrusiveContainer",r),o?(r.empty(),e.removeClass("input-validation-error").appendTo(r)):e.hide()}function d(e,n){var t=a(this).find("[data-valmsg-summary=true]"),r=t.find("ul");r&&r.length&&n.errorList.length&&(r.empty(),t.addClass("validation-summary-errors").removeClass("validation-summary-valid"),a.each(n.errorList,function(){a("
  • ").html(this.message).appendTo(r)}))}function s(e){var n=e.data("unobtrusiveContainer");if(n){var t=n.attr("data-valmsg-replace"),r=t?a.parseJSON(t):null;n.addClass("field-validation-valid").removeClass("field-validation-error"),e.removeData("unobtrusiveContainer"),r&&n.empty()}}function l(e){var n=a(this),t="__jquery_unobtrusive_validation_form_reset";if(!n.data(t)){n.data(t,!0);try{n.data("validator").resetForm()}finally{n.removeData(t)}n.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors"),n.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}}function m(e){var n=a(e),t=n.data(v),r=a.proxy(l,e),i=p.unobtrusive.options||{},m=function(n,t){var r=i[n];r&&a.isFunction(r)&&r.apply(e,t)};return t||(t={options:{errorClass:i.errorClass||"input-validation-error",errorElement:i.errorElement||"span",errorPlacement:function(){o.apply(e,arguments),m("errorPlacement",arguments)},invalidHandler:function(){d.apply(e,arguments),m("invalidHandler",arguments)},messages:{},rules:{},success:function(){s.apply(e,arguments),m("success",arguments)}},attachValidation:function(){n.off("reset."+v,r).on("reset."+v,r).validate(this.options)},validate:function(){return n.validate(),n.valid()}},n.data(v,t)),t}var u,p=a.validator,v="unobtrusiveValidation";p.unobtrusive={adapters:[],parseElement:function(e,n){var t,r,i,o=a(e),d=o.parents("form")[0];d&&(t=m(d),t.options.rules[e.name]=r={},t.options.messages[e.name]=i={},a.each(this.adapters,function(){var n="data-val-"+this.name,t=o.attr(n),s={};void 0!==t&&(n+="-",a.each(this.params,function(){s[this]=o.attr(n+this)}),this.adapt({element:e,form:d,message:t,params:s,rules:r,messages:i}))}),a.extend(r,{__dummy__:!0}),n||t.attachValidation())},parse:function(e){var n=a(e),t=n.parents().addBack().filter("form").add(n.find("form")).has("[data-val=true]");n.find("[data-val=true]").each(function(){p.unobtrusive.parseElement(this,!0)}),t.each(function(){var a=m(this);a&&a.attachValidation()})}},u=p.unobtrusive.adapters,u.add=function(a,e,n){return n||(n=e,e=[]),this.push({name:a,params:e,adapt:n}),this},u.addBool=function(a,n){return this.add(a,function(t){e(t,n||a,!0)})},u.addMinMax=function(a,n,t,r,i,o){return this.add(a,[i||"min",o||"max"],function(a){var i=a.params.min,o=a.params.max;i&&o?e(a,r,[i,o]):i?e(a,n,i):o&&e(a,t,o)})},u.addSingleVal=function(a,n,t){return this.add(a,[n||"val"],function(r){e(r,t||a,r.params[n])})},p.addMethod("__dummy__",function(a,e,n){return!0}),p.addMethod("regex",function(a,e,n){var t;return this.optional(e)?!0:(t=new RegExp(n).exec(a),t&&0===t.index&&t[0].length===a.length)}),p.addMethod("nonalphamin",function(a,e,n){var t;return n&&(t=a.match(/\W/g),t=t&&t.length>=n),t}),p.methods.extension?(u.addSingleVal("accept","mimtype"),u.addSingleVal("extension","extension")):u.addSingleVal("extension","extension","accept"),u.addSingleVal("regex","pattern"),u.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"),u.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range"),u.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength"),u.add("equalto",["other"],function(n){var o=r(n.element.name),d=n.params.other,s=i(d,o),l=a(n.form).find(":input").filter("[name='"+t(s)+"']")[0];e(n,"equalTo",l)}),u.add("required",function(a){("INPUT"!==a.element.tagName.toUpperCase()||"CHECKBOX"!==a.element.type.toUpperCase())&&e(a,"required",!0)}),u.add("remote",["url","type","additionalfields"],function(o){var d={url:o.params.url,type:o.params.type||"GET",data:{}},s=r(o.element.name);a.each(n(o.params.additionalfields||o.element.name),function(e,n){var r=i(n,s);d.data[r]=function(){var e=a(o.form).find(":input").filter("[name='"+t(r)+"']");return e.is(":checkbox")?e.filter(":checked").val()||e.filter(":hidden").val()||"":e.is(":radio")?e.filter(":checked").val()||"":e.val()}}),e(o,"remote",d)}),u.add("password",["min","nonalphamin","regex"],function(a){a.params.min&&e(a,"minlength",a.params.min),a.params.nonalphamin&&e(a,"nonalphamin",a.params.nonalphamin),a.params.regex&&e(a,"regex",a.params.regex)}),a(function(){p.unobtrusive.parse(document)})}(jQuery); -------------------------------------------------------------------------------- /src/NetCoreWebApp/wwwroot/lib/bootstrap/dist/css/bootstrap-theme.min.css.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["less/theme.less","less/mixins/vendor-prefixes.less","less/mixins/gradients.less","less/mixins/reset-filter.less"],"names":[],"mappings":";;;;AAmBA,YAAA,aAAA,UAAA,aAAA,aAAA,aAME,YAAA,EAAA,KAAA,EAAA,eC2CA,mBAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,iBDvCR,mBAAA,mBAAA,oBAAA,oBAAA,iBAAA,iBAAA,oBAAA,oBAAA,oBAAA,oBAAA,oBAAA,oBCsCA,mBAAA,MAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,iBDlCR,qBAAA,sBAAA,sBAAA,uBAAA,mBAAA,oBAAA,sBAAA,uBAAA,sBAAA,uBAAA,sBAAA,uBAAA,+BAAA,gCAAA,6BAAA,gCAAA,gCAAA,gCCiCA,mBAAA,KACQ,WAAA,KDlDV,mBAAA,oBAAA,iBAAA,oBAAA,oBAAA,oBAuBI,YAAA,KAyCF,YAAA,YAEE,iBAAA,KAKJ,aErEI,YAAA,EAAA,IAAA,EAAA,KACA,iBAAA,iDACA,iBAAA,4CAAA,iBAAA,qEAEA,iBAAA,+CCnBF,OAAA,+GH4CA,OAAA,0DACA,kBAAA,SAuC2C,aAAA,QAA2B,aAAA,KArCtE,mBAAA,mBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,oBAAA,oBAEE,iBAAA,QACA,aAAA,QAMA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,uBAAA,8BAAA,6BAAA,8BAAA,6BAAA,6BAAA,gCAAA,uCAAA,sCAAA,uCAAA,sCAAA,sCAME,iBAAA,QACA,iBAAA,KAgBN,aEtEI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,mBAAA,mBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,oBAAA,oBAEE,iBAAA,QACA,aAAA,QAMA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,uBAAA,8BAAA,6BAAA,8BAAA,6BAAA,6BAAA,gCAAA,uCAAA,sCAAA,uCAAA,sCAAA,sCAME,iBAAA,QACA,iBAAA,KAiBN,aEvEI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,mBAAA,mBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,oBAAA,oBAEE,iBAAA,QACA,aAAA,QAMA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,uBAAA,8BAAA,6BAAA,8BAAA,6BAAA,6BAAA,gCAAA,uCAAA,sCAAA,uCAAA,sCAAA,sCAME,iBAAA,QACA,iBAAA,KAkBN,UExEI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,gBAAA,gBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,iBAAA,iBAEE,iBAAA,QACA,aAAA,QAMA,mBAAA,0BAAA,yBAAA,0BAAA,yBAAA,yBAAA,oBAAA,2BAAA,0BAAA,2BAAA,0BAAA,0BAAA,6BAAA,oCAAA,mCAAA,oCAAA,mCAAA,mCAME,iBAAA,QACA,iBAAA,KAmBN,aEzEI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,mBAAA,mBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,oBAAA,oBAEE,iBAAA,QACA,aAAA,QAMA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,uBAAA,8BAAA,6BAAA,8BAAA,6BAAA,6BAAA,gCAAA,uCAAA,sCAAA,uCAAA,sCAAA,sCAME,iBAAA,QACA,iBAAA,KAoBN,YE1EI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDAEA,OAAA,+GCnBF,OAAA,0DH4CA,kBAAA,SACA,aAAA,QAEA,kBAAA,kBAEE,iBAAA,QACA,oBAAA,EAAA,MAGF,mBAAA,mBAEE,iBAAA,QACA,aAAA,QAMA,qBAAA,4BAAA,2BAAA,4BAAA,2BAAA,2BAAA,sBAAA,6BAAA,4BAAA,6BAAA,4BAAA,4BAAA,+BAAA,sCAAA,qCAAA,sCAAA,qCAAA,qCAME,iBAAA,QACA,iBAAA,KA2BN,eAAA,WClCE,mBAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,EAAA,IAAA,IAAA,iBD2CV,0BAAA,0BE3FI,iBAAA,QACA,iBAAA,oDACA,iBAAA,+CAAA,iBAAA,wEACA,iBAAA,kDACA,OAAA,+GF0FF,kBAAA,SAEF,yBAAA,+BAAA,+BEhGI,iBAAA,QACA,iBAAA,oDACA,iBAAA,+CAAA,iBAAA,wEACA,iBAAA,kDACA,OAAA,+GFgGF,kBAAA,SASF,gBE7GI,iBAAA,iDACA,iBAAA,4CACA,iBAAA,qEAAA,iBAAA,+CACA,OAAA,+GACA,OAAA,0DCnBF,kBAAA,SH+HA,cAAA,ICjEA,mBAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,iBD6DV,sCAAA,oCE7GI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SD2CF,mBAAA,MAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,iBD0EV,cAAA,iBAEE,YAAA,EAAA,IAAA,EAAA,sBAIF,gBEhII,iBAAA,iDACA,iBAAA,4CACA,iBAAA,qEAAA,iBAAA,+CACA,OAAA,+GACA,OAAA,0DCnBF,kBAAA,SHkJA,cAAA,IAHF,sCAAA,oCEhII,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SD2CF,mBAAA,MAAA,EAAA,IAAA,IAAA,gBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,gBDgFV,8BAAA,iCAYI,YAAA,EAAA,KAAA,EAAA,gBAKJ,qBAAA,kBAAA,mBAGE,cAAA,EAqBF,yBAfI,mDAAA,yDAAA,yDAGE,MAAA,KE7JF,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,UFqKJ,OACE,YAAA,EAAA,IAAA,EAAA,qBC3HA,mBAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,gBACQ,WAAA,MAAA,EAAA,IAAA,EAAA,sBAAA,EAAA,IAAA,IAAA,gBDsIV,eEtLI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF8KF,aAAA,QAKF,YEvLI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF8KF,aAAA,QAMF,eExLI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF8KF,aAAA,QAOF,cEzLI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF8KF,aAAA,QAeF,UEjMI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFuMJ,cE3MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFwMJ,sBE5MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFyMJ,mBE7MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF0MJ,sBE9MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF2MJ,qBE/MI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF+MJ,sBElLI,iBAAA,yKACA,iBAAA,oKACA,iBAAA,iKFyLJ,YACE,cAAA,IC9KA,mBAAA,EAAA,IAAA,IAAA,iBACQ,WAAA,EAAA,IAAA,IAAA,iBDgLV,wBAAA,8BAAA,8BAGE,YAAA,EAAA,KAAA,EAAA,QEnOE,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFiOF,aAAA,QALF,+BAAA,qCAAA,qCAQI,YAAA,KAUJ,OCnME,mBAAA,EAAA,IAAA,IAAA,gBACQ,WAAA,EAAA,IAAA,IAAA,gBD4MV,8BE5PI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFyPJ,8BE7PI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF0PJ,8BE9PI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF2PJ,2BE/PI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF4PJ,8BEhQI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SF6PJ,6BEjQI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFoQJ,MExQI,iBAAA,oDACA,iBAAA,+CACA,iBAAA,wEAAA,iBAAA,kDACA,OAAA,+GACA,kBAAA,SFsQF,aAAA,QC3NA,mBAAA,MAAA,EAAA,IAAA,IAAA,gBAAA,EAAA,IAAA,EAAA,qBACQ,WAAA,MAAA,EAAA,IAAA,IAAA,gBAAA,EAAA,IAAA,EAAA"} -------------------------------------------------------------------------------- /src/NetCoreApp.Logger.File/FileLoggerProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.Extensions.Configuration; 7 | using Microsoft.Extensions.Logging; 8 | 9 | namespace NetCoreApp.Logger.File 10 | { 11 | public class FileLoggerProvider : ILoggerProvider, IDisposable 12 | { 13 | FileLoggerSettings _configuration; 14 | readonly ConcurrentDictionary _loggerKeys = new ConcurrentDictionary(); 15 | readonly ConcurrentDictionary _loggers = new ConcurrentDictionary(); 16 | 17 | public FileLoggerProvider(FileLoggerSettings configuration) 18 | { 19 | _configuration = configuration; 20 | _configuration.ChangeToken.RegisterChangeCallback(p => 21 | { 22 | //appsettings.json changed. reload settings. 23 | _configuration.Reload(); 24 | 25 | //update loggers settings form new settings 26 | foreach (var item in this._loggers.Values) 27 | { 28 | InitLoggerModel model = new InitLoggerModel(); 29 | InitLoggerSettings(item.Name, model); 30 | InitLogger(model, item); 31 | } 32 | 33 | }, null); 34 | } 35 | public ILogger CreateLogger(string categoryName) 36 | { 37 | var loggerKey = this._loggerKeys.GetOrAdd(categoryName, p => 38 | { 39 | InitLoggerModel model = new InitLoggerModel(); 40 | InitLoggerSettings(categoryName, model); 41 | return model; 42 | }); 43 | var key = loggerKey.FileDiretoryPath + loggerKey.FileNameTemplate; 44 | return this._loggers.GetOrAdd(key, p => 45 | { 46 | var logger = new FileLogger(categoryName); 47 | InitLogger(loggerKey, logger); 48 | return logger; 49 | }); 50 | } 51 | 52 | private static void InitLogger(InitLoggerModel model, FileLogger logger) 53 | { 54 | logger.FileNameTemplate = model.FileNameTemplate; 55 | logger.FileDiretoryPath = model.FileDiretoryPath; 56 | logger.MinLevel = model.MinLevel; 57 | } 58 | 59 | class InitLoggerModel 60 | { 61 | public LogLevel MinLevel { get; set; } 62 | public string FileDiretoryPath { get; set; } 63 | public string FileNameTemplate { get; set; } 64 | 65 | public override int GetHashCode() 66 | { 67 | return this.MinLevel.GetHashCode() + this.FileDiretoryPath.GetHashCode() + this.FileNameTemplate.GetHashCode(); 68 | } 69 | public override bool Equals(object obj) 70 | { 71 | var b = obj as InitLoggerModel; 72 | if (b == null) 73 | return false; 74 | return this.MinLevel == b.MinLevel && this.FileDiretoryPath == b.FileDiretoryPath && this.FileNameTemplate == b.FileNameTemplate; 75 | } 76 | 77 | } 78 | private void InitLoggerSettings(string categoryName, InitLoggerModel model) 79 | { 80 | model.MinLevel = LogLevel.Debug; 81 | var keys = this.GetKeys(categoryName); 82 | foreach (var item in keys) 83 | { 84 | var switchV = _configuration.GetSwitch(item); 85 | if (switchV.Item1) 86 | { 87 | model.MinLevel = switchV.Item2; 88 | break; 89 | } 90 | } 91 | model.FileDiretoryPath = this._configuration.DefaultPath; 92 | foreach (var item in keys) 93 | { 94 | var switchV = _configuration.GetDiretoryPath(item); 95 | if (switchV.Item1) 96 | { 97 | model.FileDiretoryPath = switchV.Item2; 98 | break; 99 | } 100 | } 101 | model.FileNameTemplate = this._configuration.DefaultFileName; 102 | foreach (var item in keys) 103 | { 104 | var switchV = _configuration.GetFileName(item); 105 | if (switchV.Item1) 106 | { 107 | model.FileNameTemplate = switchV.Item2; 108 | break; 109 | } 110 | } 111 | } 112 | 113 | IEnumerable GetKeys(string categoryName) 114 | { 115 | while (!String.IsNullOrEmpty(categoryName)) 116 | { 117 | // a.b.c 118 | //--result 119 | // a.b.c,a.b,a,Default 120 | yield return categoryName; 121 | var last = categoryName.LastIndexOf('.'); 122 | if (last <= 0) 123 | { 124 | yield return "Default"; 125 | yield break; 126 | } 127 | System.Diagnostics.Debug.WriteLine(categoryName + "--" + last); 128 | categoryName = categoryName.Substring(0, last); 129 | } 130 | yield break; 131 | 132 | } 133 | public void Dispose() 134 | { 135 | } 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /src/MQ/EventBus.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Net.Http; 5 | using System.Text; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.Logging; 10 | using MQ.Internal; 11 | using Newtonsoft.Json; 12 | using RabbitMQ.Client; 13 | using RabbitMQ.Client.Events; 14 | using Microsoft.Extensions.DependencyInjection; 15 | namespace MQ 16 | { 17 | public class EventBus 18 | { 19 | static SpinLock sl = new SpinLock(); 20 | static JsonSerializerSettings setting = new Newtonsoft.Json.JsonSerializerSettings(); 21 | static EventBusSettings settings; 22 | static ILogger _logger; 23 | static CacheManager _CacheManager; 24 | static EventBus() 25 | { 26 | setting.DateFormatString = "yyyy/MM/dd HH:mm:ss.fff"; 27 | } 28 | /// 29 | /// 30 | /// 31 | /// 32 | /// 33 | /// exchange 34 | /// routingKey 35 | /// 36 | /// 37 | public static ulong Publish(string productId, string topic, string tag, string id, T message) 38 | { 39 | var t = typeof(T); 40 | string msgStr; 41 | if (t == typeof(string)) 42 | msgStr = message.ToString(); 43 | else 44 | msgStr = Newtonsoft.Json.JsonConvert.SerializeObject(message, t, setting); 45 | 46 | var msg = Encoding.UTF8.GetBytes(msgStr); 47 | bool reflock = false; 48 | sl.Enter(ref reflock); 49 | try 50 | { 51 | var channel = _CacheManager.GetChannel(productId); 52 | var pubNo = channel.NextPublishSeqNo; 53 | channel.BasicPublish(topic, tag, false, null, msg); 54 | return pubNo; 55 | } 56 | catch (Exception ex) 57 | { 58 | } 59 | finally 60 | { 61 | if (reflock) 62 | sl.Exit(); 63 | } 64 | return 0; 65 | } 66 | /// 67 | /// 68 | /// 69 | /// 70 | /// 71 | /// 集群消费:queuename;广播消费:exchange 72 | /// 73 | /// 74 | public static async void Subscribe(string productId, string topic, Func action, SubscribeOptions options = null) 75 | { 76 | options = options ?? SubscribeOptions.Default; 77 | var queueName = topic; 78 | var channel = _CacheManager.GetChannel(productId); 79 | 80 | if (options.Model == MessageModel.Broadcasting) 81 | { 82 | var hostName = System.Net.Dns.GetHostName(); 83 | var ipaddress = await System.Net.Dns.GetHostEntryAsync(hostName).ConfigureAwait(false); 84 | var ip = ipaddress.AddressList.FirstOrDefault(p => p.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)?.ToString() ?? hostName; 85 | var fanoutQueueName = ip + "." + productId + "." + topic + "." + DateTime.UtcNow.Ticks; 86 | channel.QueueDeclare(queue: fanoutQueueName); 87 | channel.QueueBind(fanoutQueueName, topic, "", null); 88 | queueName = fanoutQueueName; 89 | } 90 | 91 | var consumer = new EventingBasicConsumer(channel); 92 | consumer.Shutdown += (obj, ea) => 93 | { 94 | _logger.LogError("eventbus.consumer.shutdown:" + ea.ToJson()); 95 | }; 96 | channel.BasicQos(0, 1, false); 97 | var tx = typeof(T) == typeof(string); 98 | consumer.Received += (obj, ea) => 99 | { 100 | try 101 | { 102 | var body = Encoding.UTF8.GetString(ea.Body); 103 | var result = false; 104 | if (tx) 105 | result = action((T)((object)body)); 106 | else 107 | { 108 | var msg = JsonConvert.DeserializeObject(body, setting); 109 | result = action(msg); 110 | } 111 | if (result) 112 | { 113 | consumer.Model.BasicAck(ea.DeliveryTag, true); 114 | } 115 | else 116 | { 117 | consumer.Model.BasicReject(ea.DeliveryTag, false); 118 | } 119 | } 120 | catch (Exception ex) 121 | { 122 | _logger.LogError(0, ex, "eventbus.subscribe.consumer"); 123 | } 124 | }; 125 | _logger.LogInformation("eventbus.subscribe." + queueName); 126 | channel.BasicConsume(queueName, false, consumer); 127 | } 128 | 129 | public static void Exit() 130 | { 131 | ((IDisposable)_CacheManager).Dispose(); 132 | } 133 | 134 | public static void Configure(IConfigurationRoot config, IServiceProvider internalServiceProvider = null) 135 | { 136 | var logger = internalServiceProvider?.GetService>(); 137 | _logger = logger; 138 | _CacheManager = new CacheManager(); 139 | _CacheManager.Configure(new EventBusSettings(config, logger)); 140 | } 141 | 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Home Page"; 3 | } 4 | 5 | 67 | 68 | 110 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/Project_Readme.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Welcome to ASP.NET Core 6 | 127 | 128 | 129 | 130 | 138 | 139 |
    140 |
    141 |

    This application consists of:

    142 |
      143 |
    • Sample pages using ASP.NET Core MVC
    • 144 |
    • Bower for managing client-side libraries
    • 145 |
    • Theming using Bootstrap
    • 146 |
    147 |
    148 | 160 | 172 |
    173 |

    Run & Deploy

    174 | 179 |
    180 | 181 | 184 |
    185 | 186 | 187 | 188 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/wwwroot/images/banner2.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/wwwroot/images/banner1.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/wwwroot/images/banner3.svg: -------------------------------------------------------------------------------- 1 | banner3b -------------------------------------------------------------------------------- /src/NetCoreWebApp/wwwroot/images/banner4.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/NetCoreWebApp/wwwroot/lib/jquery-validation/dist/additional-methods.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery Validation Plugin - v1.14.0 - 6/30/2015 2 | * http://jqueryvalidation.org/ 3 | * Copyright (c) 2015 Jörn Zaefferer; Licensed MIT */ 4 | !function(a){"function"==typeof define&&define.amd?define(["jquery","./jquery.validate.min"],a):a(jQuery)}(function(a){!function(){function b(a){return a.replace(/<.[^<>]*?>/g," ").replace(/ | /gi," ").replace(/[.(),;:!?%#$'\"_+=\/\-“”’]*/g,"")}a.validator.addMethod("maxWords",function(a,c,d){return this.optional(c)||b(a).match(/\b\w+\b/g).length<=d},a.validator.format("Please enter {0} words or less.")),a.validator.addMethod("minWords",function(a,c,d){return this.optional(c)||b(a).match(/\b\w+\b/g).length>=d},a.validator.format("Please enter at least {0} words.")),a.validator.addMethod("rangeWords",function(a,c,d){var e=b(a),f=/\b\w+\b/g;return this.optional(c)||e.match(f).length>=d[0]&&e.match(f).length<=d[1]},a.validator.format("Please enter between {0} and {1} words."))}(),a.validator.addMethod("accept",function(b,c,d){var e,f,g="string"==typeof d?d.replace(/\s/g,"").replace(/,/g,"|"):"image/*",h=this.optional(c);if(h)return h;if("file"===a(c).attr("type")&&(g=g.replace(/\*/g,".*"),c.files&&c.files.length))for(e=0;ec;c++)d=h-c,e=f.substring(c,c+1),g+=d*e;return g%11===0},"Please specify a valid bank account number"),a.validator.addMethod("bankorgiroaccountNL",function(b,c){return this.optional(c)||a.validator.methods.bankaccountNL.call(this,b,c)||a.validator.methods.giroaccountNL.call(this,b,c)},"Please specify a valid bank or giro account number"),a.validator.addMethod("bic",function(a,b){return this.optional(b)||/^([A-Z]{6}[A-Z2-9][A-NP-Z1-2])(X{3}|[A-WY-Z0-9][A-Z0-9]{2})?$/.test(a)},"Please specify a valid BIC code"),a.validator.addMethod("cifES",function(a){"use strict";var b,c,d,e,f,g,h=[];if(a=a.toUpperCase(),!a.match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)"))return!1;for(d=0;9>d;d++)h[d]=parseInt(a.charAt(d),10);for(c=h[2]+h[4]+h[6],e=1;8>e;e+=2)f=(2*h[e]).toString(),g=f.charAt(1),c+=parseInt(f.charAt(0),10)+(""===g?0:parseInt(g,10));return/^[ABCDEFGHJNPQRSUVW]{1}/.test(a)?(c+="",b=10-parseInt(c.charAt(c.length-1),10),a+=b,h[8].toString()===String.fromCharCode(64+b)||h[8].toString()===a.charAt(a.length-1)):!1},"Please specify a valid CIF number."),a.validator.addMethod("cpfBR",function(a){if(a=a.replace(/([~!@#$%^&*()_+=`{}\[\]\-|\\:;'<>,.\/? ])+/g,""),11!==a.length)return!1;var b,c,d,e,f=0;if(b=parseInt(a.substring(9,10),10),c=parseInt(a.substring(10,11),10),d=function(a,b){var c=10*a%11;return(10===c||11===c)&&(c=0),c===b},""===a||"00000000000"===a||"11111111111"===a||"22222222222"===a||"33333333333"===a||"44444444444"===a||"55555555555"===a||"66666666666"===a||"77777777777"===a||"88888888888"===a||"99999999999"===a)return!1;for(e=1;9>=e;e++)f+=parseInt(a.substring(e-1,e),10)*(11-e);if(d(f,b)){for(f=0,e=1;10>=e;e++)f+=parseInt(a.substring(e-1,e),10)*(12-e);return d(f,c)}return!1},"Please specify a valid CPF number"),a.validator.addMethod("creditcardtypes",function(a,b,c){if(/[^0-9\-]+/.test(a))return!1;a=a.replace(/\D/g,"");var d=0;return c.mastercard&&(d|=1),c.visa&&(d|=2),c.amex&&(d|=4),c.dinersclub&&(d|=8),c.enroute&&(d|=16),c.discover&&(d|=32),c.jcb&&(d|=64),c.unknown&&(d|=128),c.all&&(d=255),1&d&&/^(5[12345])/.test(a)?16===a.length:2&d&&/^(4)/.test(a)?16===a.length:4&d&&/^(3[47])/.test(a)?15===a.length:8&d&&/^(3(0[012345]|[68]))/.test(a)?14===a.length:16&d&&/^(2(014|149))/.test(a)?15===a.length:32&d&&/^(6011)/.test(a)?16===a.length:64&d&&/^(3)/.test(a)?16===a.length:64&d&&/^(2131|1800)/.test(a)?15===a.length:128&d?!0:!1},"Please enter a valid credit card number."),a.validator.addMethod("currency",function(a,b,c){var d,e="string"==typeof c,f=e?c:c[0],g=e?!0:c[1];return f=f.replace(/,/g,""),f=g?f+"]":f+"]?",d="^["+f+"([1-9]{1}[0-9]{0,2}(\\,[0-9]{3})*(\\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\\.[0-9]{0,2})?|0(\\.[0-9]{0,2})?|(\\.[0-9]{1,2})?)$",d=new RegExp(d),this.optional(b)||d.test(a)},"Please specify a valid currency"),a.validator.addMethod("dateFA",function(a,b){return this.optional(b)||/^[1-4]\d{3}\/((0?[1-6]\/((3[0-1])|([1-2][0-9])|(0?[1-9])))|((1[0-2]|(0?[7-9]))\/(30|([1-2][0-9])|(0?[1-9]))))$/.test(a)},a.validator.messages.date),a.validator.addMethod("dateITA",function(a,b){var c,d,e,f,g,h=!1,i=/^\d{1,2}\/\d{1,2}\/\d{4}$/;return i.test(a)?(c=a.split("/"),d=parseInt(c[0],10),e=parseInt(c[1],10),f=parseInt(c[2],10),g=new Date(Date.UTC(f,e-1,d,12,0,0,0)),h=g.getUTCFullYear()===f&&g.getUTCMonth()===e-1&&g.getUTCDate()===d?!0:!1):h=!1,this.optional(b)||h},a.validator.messages.date),a.validator.addMethod("dateNL",function(a,b){return this.optional(b)||/^(0?[1-9]|[12]\d|3[01])[\.\/\-](0?[1-9]|1[012])[\.\/\-]([12]\d)?(\d\d)$/.test(a)},a.validator.messages.date),a.validator.addMethod("extension",function(a,b,c){return c="string"==typeof c?c.replace(/,/g,"|"):"png|jpe?g|gif",this.optional(b)||a.match(new RegExp("\\.("+c+")$","i"))},a.validator.format("Please enter a value with a valid extension.")),a.validator.addMethod("giroaccountNL",function(a,b){return this.optional(b)||/^[0-9]{1,7}$/.test(a)},"Please specify a valid giro account number"),a.validator.addMethod("iban",function(a,b){if(this.optional(b))return!0;var c,d,e,f,g,h,i,j,k,l=a.replace(/ /g,"").toUpperCase(),m="",n=!0,o="",p="";if(c=l.substring(0,2),h={AL:"\\d{8}[\\dA-Z]{16}",AD:"\\d{8}[\\dA-Z]{12}",AT:"\\d{16}",AZ:"[\\dA-Z]{4}\\d{20}",BE:"\\d{12}",BH:"[A-Z]{4}[\\dA-Z]{14}",BA:"\\d{16}",BR:"\\d{23}[A-Z][\\dA-Z]",BG:"[A-Z]{4}\\d{6}[\\dA-Z]{8}",CR:"\\d{17}",HR:"\\d{17}",CY:"\\d{8}[\\dA-Z]{16}",CZ:"\\d{20}",DK:"\\d{14}",DO:"[A-Z]{4}\\d{20}",EE:"\\d{16}",FO:"\\d{14}",FI:"\\d{14}",FR:"\\d{10}[\\dA-Z]{11}\\d{2}",GE:"[\\dA-Z]{2}\\d{16}",DE:"\\d{18}",GI:"[A-Z]{4}[\\dA-Z]{15}",GR:"\\d{7}[\\dA-Z]{16}",GL:"\\d{14}",GT:"[\\dA-Z]{4}[\\dA-Z]{20}",HU:"\\d{24}",IS:"\\d{22}",IE:"[\\dA-Z]{4}\\d{14}",IL:"\\d{19}",IT:"[A-Z]\\d{10}[\\dA-Z]{12}",KZ:"\\d{3}[\\dA-Z]{13}",KW:"[A-Z]{4}[\\dA-Z]{22}",LV:"[A-Z]{4}[\\dA-Z]{13}",LB:"\\d{4}[\\dA-Z]{20}",LI:"\\d{5}[\\dA-Z]{12}",LT:"\\d{16}",LU:"\\d{3}[\\dA-Z]{13}",MK:"\\d{3}[\\dA-Z]{10}\\d{2}",MT:"[A-Z]{4}\\d{5}[\\dA-Z]{18}",MR:"\\d{23}",MU:"[A-Z]{4}\\d{19}[A-Z]{3}",MC:"\\d{10}[\\dA-Z]{11}\\d{2}",MD:"[\\dA-Z]{2}\\d{18}",ME:"\\d{18}",NL:"[A-Z]{4}\\d{10}",NO:"\\d{11}",PK:"[\\dA-Z]{4}\\d{16}",PS:"[\\dA-Z]{4}\\d{21}",PL:"\\d{24}",PT:"\\d{21}",RO:"[A-Z]{4}[\\dA-Z]{16}",SM:"[A-Z]\\d{10}[\\dA-Z]{12}",SA:"\\d{2}[\\dA-Z]{18}",RS:"\\d{18}",SK:"\\d{20}",SI:"\\d{15}",ES:"\\d{20}",SE:"\\d{20}",CH:"\\d{5}[\\dA-Z]{12}",TN:"\\d{20}",TR:"\\d{5}[\\dA-Z]{17}",AE:"\\d{3}\\d{16}",GB:"[A-Z]{4}\\d{14}",VG:"[\\dA-Z]{4}\\d{16}"},g=h[c],"undefined"!=typeof g&&(i=new RegExp("^[A-Z]{2}\\d{2}"+g+"$",""),!i.test(l)))return!1;for(d=l.substring(4,l.length)+l.substring(0,4),j=0;j9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?|0)7(?:[1345789]\d{2}|624)\s?\d{3}\s?\d{3})$/)},"Please specify a valid mobile number"),a.validator.addMethod("nieES",function(a){"use strict";return a=a.toUpperCase(),a.match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)")?/^[T]{1}/.test(a)?a[8]===/^[T]{1}[A-Z0-9]{8}$/.test(a):/^[XYZ]{1}/.test(a)?a[8]==="TRWAGMYFPDXBNJZSQVHLCKE".charAt(a.replace("X","0").replace("Y","1").replace("Z","2").substring(0,8)%23):!1:!1},"Please specify a valid NIE number."),a.validator.addMethod("nifES",function(a){"use strict";return a=a.toUpperCase(),a.match("((^[A-Z]{1}[0-9]{7}[A-Z0-9]{1}$|^[T]{1}[A-Z0-9]{8}$)|^[0-9]{8}[A-Z]{1}$)")?/^[0-9]{8}[A-Z]{1}$/.test(a)?"TRWAGMYFPDXBNJZSQVHLCKE".charAt(a.substring(8,0)%23)===a.charAt(8):/^[KLM]{1}/.test(a)?a[8]===String.fromCharCode(64):!1:!1},"Please specify a valid NIF number."),jQuery.validator.addMethod("notEqualTo",function(b,c,d){return this.optional(c)||!a.validator.methods.equalTo.call(this,b,c,d)},"Please enter a different value, values must not be the same."),a.validator.addMethod("nowhitespace",function(a,b){return this.optional(b)||/^\S+$/i.test(a)},"No white space please"),a.validator.addMethod("pattern",function(a,b,c){return this.optional(b)?!0:("string"==typeof c&&(c=new RegExp("^(?:"+c+")$")),c.test(a))},"Invalid format."),a.validator.addMethod("phoneNL",function(a,b){return this.optional(b)||/^((\+|00(\s|\s?\-\s?)?)31(\s|\s?\-\s?)?(\(0\)[\-\s]?)?|0)[1-9]((\s|\s?\-\s?)?[0-9]){8}$/.test(a)},"Please specify a valid phone number."),a.validator.addMethod("phoneUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?)|(?:\(?0))(?:\d{2}\)?\s?\d{4}\s?\d{4}|\d{3}\)?\s?\d{3}\s?\d{3,4}|\d{4}\)?\s?(?:\d{5}|\d{3}\s?\d{3})|\d{5}\)?\s?\d{4,5})$/)},"Please specify a valid phone number"),a.validator.addMethod("phoneUS",function(a,b){return a=a.replace(/\s+/g,""),this.optional(b)||a.length>9&&a.match(/^(\+?1-?)?(\([2-9]([02-9]\d|1[02-9])\)|[2-9]([02-9]\d|1[02-9]))-?[2-9]([02-9]\d|1[02-9])-?\d{4}$/)},"Please specify a valid phone number"),a.validator.addMethod("phonesUK",function(a,b){return a=a.replace(/\(|\)|\s+|-/g,""),this.optional(b)||a.length>9&&a.match(/^(?:(?:(?:00\s?|\+)44\s?|0)(?:1\d{8,9}|[23]\d{9}|7(?:[1345789]\d{8}|624\d{6})))$/)},"Please specify a valid uk phone number"),a.validator.addMethod("postalCodeCA",function(a,b){return this.optional(b)||/^[ABCEGHJKLMNPRSTVXY]\d[A-Z] \d[A-Z]\d$/.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postalcodeBR",function(a,b){return this.optional(b)||/^\d{2}.\d{3}-\d{3}?$|^\d{5}-?\d{3}?$/.test(a)},"Informe um CEP válido."),a.validator.addMethod("postalcodeIT",function(a,b){return this.optional(b)||/^\d{5}$/.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postalcodeNL",function(a,b){return this.optional(b)||/^[1-9][0-9]{3}\s?[a-zA-Z]{2}$/.test(a)},"Please specify a valid postal code"),a.validator.addMethod("postcodeUK",function(a,b){return this.optional(b)||/^((([A-PR-UWYZ][0-9])|([A-PR-UWYZ][0-9][0-9])|([A-PR-UWYZ][A-HK-Y][0-9])|([A-PR-UWYZ][A-HK-Y][0-9][0-9])|([A-PR-UWYZ][0-9][A-HJKSTUW])|([A-PR-UWYZ][A-HK-Y][0-9][ABEHMNPRVWXY]))\s?([0-9][ABD-HJLNP-UW-Z]{2})|(GIR)\s?(0AA))$/i.test(a)},"Please specify a valid UK postcode"),a.validator.addMethod("require_from_group",function(b,c,d){var e=a(d[1],c.form),f=e.eq(0),g=f.data("valid_req_grp")?f.data("valid_req_grp"):a.extend({},this),h=e.filter(function(){return g.elementValue(this)}).length>=d[0];return f.data("valid_req_grp",g),a(c).data("being_validated")||(e.data("being_validated",!0),e.each(function(){g.element(this)}),e.data("being_validated",!1)),h},a.validator.format("Please fill at least {0} of these fields.")),a.validator.addMethod("skip_or_fill_minimum",function(b,c,d){var e=a(d[1],c.form),f=e.eq(0),g=f.data("valid_skip")?f.data("valid_skip"):a.extend({},this),h=e.filter(function(){return g.elementValue(this)}).length,i=0===h||h>=d[0];return f.data("valid_skip",g),a(c).data("being_validated")||(e.data("being_validated",!0),e.each(function(){g.element(this)}),e.data("being_validated",!1)),i},a.validator.format("Please either skip these fields or fill at least {0} of them.")),a.validator.addMethod("stateUS",function(a,b,c){var d,e="undefined"==typeof c,f=e||"undefined"==typeof c.caseSensitive?!1:c.caseSensitive,g=e||"undefined"==typeof c.includeTerritories?!1:c.includeTerritories,h=e||"undefined"==typeof c.includeMilitary?!1:c.includeMilitary;return d=g||h?g&&h?"^(A[AEKLPRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$":g?"^(A[KLRSZ]|C[AOT]|D[CE]|FL|G[AU]|HI|I[ADLN]|K[SY]|LA|M[ADEINOPST]|N[CDEHJMVY]|O[HKR]|P[AR]|RI|S[CD]|T[NX]|UT|V[AIT]|W[AIVY])$":"^(A[AEKLPRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$":"^(A[KLRZ]|C[AOT]|D[CE]|FL|GA|HI|I[ADLN]|K[SY]|LA|M[ADEINOST]|N[CDEHJMVY]|O[HKR]|PA|RI|S[CD]|T[NX]|UT|V[AT]|W[AIVY])$",d=f?new RegExp(d):new RegExp(d,"i"),this.optional(b)||d.test(a)},"Please specify a valid state"),a.validator.addMethod("strippedminlength",function(b,c,d){return a(b).text().length>=d},a.validator.format("Please enter at least {0} characters")),a.validator.addMethod("time",function(a,b){return this.optional(b)||/^([01]\d|2[0-3]|[0-9])(:[0-5]\d){1,2}$/.test(a)},"Please enter a valid time, between 00:00 and 23:59"),a.validator.addMethod("time12h",function(a,b){return this.optional(b)||/^((0?[1-9]|1[012])(:[0-5]\d){1,2}(\ ?[AP]M))$/i.test(a)},"Please enter a valid time in 12-hour am/pm format"),a.validator.addMethod("url2",function(a,b){return this.optional(b)||/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(a)},a.validator.messages.url),a.validator.addMethod("vinUS",function(a){if(17!==a.length)return!1;var b,c,d,e,f,g,h=["A","B","C","D","E","F","G","H","J","K","L","M","N","P","R","S","T","U","V","W","X","Y","Z"],i=[1,2,3,4,5,6,7,8,1,2,3,4,5,7,9,2,3,4,5,6,7,8,9],j=[8,7,6,5,4,3,2,10,0,9,8,7,6,5,4,3,2],k=0;for(b=0;17>b;b++){if(e=j[b],d=a.slice(b,b+1),8===b&&(g=d),isNaN(d)){for(c=0;c").attr("name",c.submitButton.name).val(a(c.submitButton).val()).appendTo(c.currentForm)),e=c.settings.submitHandler.call(c,c.currentForm,b),c.submitButton&&d.remove(),void 0!==e?e:!1):!0}return c.settings.debug&&b.preventDefault(),c.cancelSubmit?(c.cancelSubmit=!1,d()):c.form()?c.pendingRequest?(c.formSubmitted=!0,!1):d():(c.focusInvalid(),!1)})),c)},valid:function(){var b,c,d;return a(this[0]).is("form")?b=this.validate().form():(d=[],b=!0,c=a(this[0].form).validate(),this.each(function(){b=c.element(this)&&b,d=d.concat(c.errorList)}),c.errorList=d),b},rules:function(b,c){var d,e,f,g,h,i,j=this[0];if(b)switch(d=a.data(j.form,"validator").settings,e=d.rules,f=a.validator.staticRules(j),b){case"add":a.extend(f,a.validator.normalizeRule(c)),delete f.messages,e[j.name]=f,c.messages&&(d.messages[j.name]=a.extend(d.messages[j.name],c.messages));break;case"remove":return c?(i={},a.each(c.split(/\s/),function(b,c){i[c]=f[c],delete f[c],"required"===c&&a(j).removeAttr("aria-required")}),i):(delete e[j.name],f)}return g=a.validator.normalizeRules(a.extend({},a.validator.classRules(j),a.validator.attributeRules(j),a.validator.dataRules(j),a.validator.staticRules(j)),j),g.required&&(h=g.required,delete g.required,g=a.extend({required:h},g),a(j).attr("aria-required","true")),g.remote&&(h=g.remote,delete g.remote,g=a.extend(g,{remote:h})),g}}),a.extend(a.expr[":"],{blank:function(b){return!a.trim(""+a(b).val())},filled:function(b){return!!a.trim(""+a(b).val())},unchecked:function(b){return!a(b).prop("checked")}}),a.validator=function(b,c){this.settings=a.extend(!0,{},a.validator.defaults,b),this.currentForm=c,this.init()},a.validator.format=function(b,c){return 1===arguments.length?function(){var c=a.makeArray(arguments);return c.unshift(b),a.validator.format.apply(this,c)}:(arguments.length>2&&c.constructor!==Array&&(c=a.makeArray(arguments).slice(1)),c.constructor!==Array&&(c=[c]),a.each(c,function(a,c){b=b.replace(new RegExp("\\{"+a+"\\}","g"),function(){return c})}),b)},a.extend(a.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",validClass:"valid",errorElement:"label",focusCleanup:!1,focusInvalid:!0,errorContainer:a([]),errorLabelContainer:a([]),onsubmit:!0,ignore:":hidden",ignoreTitle:!1,onfocusin:function(a){this.lastActive=a,this.settings.focusCleanup&&(this.settings.unhighlight&&this.settings.unhighlight.call(this,a,this.settings.errorClass,this.settings.validClass),this.hideThese(this.errorsFor(a)))},onfocusout:function(a){this.checkable(a)||!(a.name in this.submitted)&&this.optional(a)||this.element(a)},onkeyup:function(b,c){var d=[16,17,18,20,35,36,37,38,39,40,45,144,225];9===c.which&&""===this.elementValue(b)||-1!==a.inArray(c.keyCode,d)||(b.name in this.submitted||b===this.lastElement)&&this.element(b)},onclick:function(a){a.name in this.submitted?this.element(a):a.parentNode.name in this.submitted&&this.element(a.parentNode)},highlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).addClass(c).removeClass(d):a(b).addClass(c).removeClass(d)},unhighlight:function(b,c,d){"radio"===b.type?this.findByName(b.name).removeClass(c).addClass(d):a(b).removeClass(c).addClass(d)}},setDefaults:function(b){a.extend(a.validator.defaults,b)},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date ( ISO ).",number:"Please enter a valid number.",digits:"Please enter only digits.",creditcard:"Please enter a valid credit card number.",equalTo:"Please enter the same value again.",maxlength:a.validator.format("Please enter no more than {0} characters."),minlength:a.validator.format("Please enter at least {0} characters."),rangelength:a.validator.format("Please enter a value between {0} and {1} characters long."),range:a.validator.format("Please enter a value between {0} and {1}."),max:a.validator.format("Please enter a value less than or equal to {0}."),min:a.validator.format("Please enter a value greater than or equal to {0}.")},autoCreateRanges:!1,prototype:{init:function(){function b(b){var c=a.data(this.form,"validator"),d="on"+b.type.replace(/^validate/,""),e=c.settings;e[d]&&!a(this).is(e.ignore)&&e[d].call(c,this,b)}this.labelContainer=a(this.settings.errorLabelContainer),this.errorContext=this.labelContainer.length&&this.labelContainer||a(this.currentForm),this.containers=a(this.settings.errorContainer).add(this.settings.errorLabelContainer),this.submitted={},this.valueCache={},this.pendingRequest=0,this.pending={},this.invalid={},this.reset();var c,d=this.groups={};a.each(this.settings.groups,function(b,c){"string"==typeof c&&(c=c.split(/\s/)),a.each(c,function(a,c){d[c]=b})}),c=this.settings.rules,a.each(c,function(b,d){c[b]=a.validator.normalizeRule(d)}),a(this.currentForm).on("focusin.validate focusout.validate keyup.validate",":text, [type='password'], [type='file'], select, textarea, [type='number'], [type='search'], [type='tel'], [type='url'], [type='email'], [type='datetime'], [type='date'], [type='month'], [type='week'], [type='time'], [type='datetime-local'], [type='range'], [type='color'], [type='radio'], [type='checkbox']",b).on("click.validate","select, option, [type='radio'], [type='checkbox']",b),this.settings.invalidHandler&&a(this.currentForm).on("invalid-form.validate",this.settings.invalidHandler),a(this.currentForm).find("[required], [data-rule-required], .required").attr("aria-required","true")},form:function(){return this.checkForm(),a.extend(this.submitted,this.errorMap),this.invalid=a.extend({},this.errorMap),this.valid()||a(this.currentForm).triggerHandler("invalid-form",[this]),this.showErrors(),this.valid()},checkForm:function(){this.prepareForm();for(var a=0,b=this.currentElements=this.elements();b[a];a++)this.check(b[a]);return this.valid()},element:function(b){var c=this.clean(b),d=this.validationTargetFor(c),e=!0;return this.lastElement=d,void 0===d?delete this.invalid[c.name]:(this.prepareElement(d),this.currentElements=a(d),e=this.check(d)!==!1,e?delete this.invalid[d.name]:this.invalid[d.name]=!0),a(b).attr("aria-invalid",!e),this.numberOfInvalids()||(this.toHide=this.toHide.add(this.containers)),this.showErrors(),e},showErrors:function(b){if(b){a.extend(this.errorMap,b),this.errorList=[];for(var c in b)this.errorList.push({message:b[c],element:this.findByName(c)[0]});this.successList=a.grep(this.successList,function(a){return!(a.name in b)})}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors()},resetForm:function(){a.fn.resetForm&&a(this.currentForm).resetForm(),this.submitted={},this.lastElement=null,this.prepareForm(),this.hideErrors();var b,c=this.elements().removeData("previousValue").removeAttr("aria-invalid");if(this.settings.unhighlight)for(b=0;c[b];b++)this.settings.unhighlight.call(this,c[b],this.settings.errorClass,"");else c.removeClass(this.settings.errorClass)},numberOfInvalids:function(){return this.objectLength(this.invalid)},objectLength:function(a){var b,c=0;for(b in a)c++;return c},hideErrors:function(){this.hideThese(this.toHide)},hideThese:function(a){a.not(this.containers).text(""),this.addWrapper(a).hide()},valid:function(){return 0===this.size()},size:function(){return this.errorList.length},focusInvalid:function(){if(this.settings.focusInvalid)try{a(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus().trigger("focusin")}catch(b){}},findLastActive:function(){var b=this.lastActive;return b&&1===a.grep(this.errorList,function(a){return a.element.name===b.name}).length&&b},elements:function(){var b=this,c={};return a(this.currentForm).find("input, select, textarea").not(":submit, :reset, :image, :disabled").not(this.settings.ignore).filter(function(){return!this.name&&b.settings.debug&&window.console&&console.error("%o has no name assigned",this),this.name in c||!b.objectLength(a(this).rules())?!1:(c[this.name]=!0,!0)})},clean:function(b){return a(b)[0]},errors:function(){var b=this.settings.errorClass.split(" ").join(".");return a(this.settings.errorElement+"."+b,this.errorContext)},reset:function(){this.successList=[],this.errorList=[],this.errorMap={},this.toShow=a([]),this.toHide=a([]),this.currentElements=a([])},prepareForm:function(){this.reset(),this.toHide=this.errors().add(this.containers)},prepareElement:function(a){this.reset(),this.toHide=this.errorsFor(a)},elementValue:function(b){var c,d=a(b),e=b.type;return"radio"===e||"checkbox"===e?this.findByName(b.name).filter(":checked").val():"number"===e&&"undefined"!=typeof b.validity?b.validity.badInput?!1:d.val():(c=d.val(),"string"==typeof c?c.replace(/\r/g,""):c)},check:function(b){b=this.validationTargetFor(this.clean(b));var c,d,e,f=a(b).rules(),g=a.map(f,function(a,b){return b}).length,h=!1,i=this.elementValue(b);for(d in f){e={method:d,parameters:f[d]};try{if(c=a.validator.methods[d].call(this,i,b,e.parameters),"dependency-mismatch"===c&&1===g){h=!0;continue}if(h=!1,"pending"===c)return void(this.toHide=this.toHide.not(this.errorsFor(b)));if(!c)return this.formatAndAdd(b,e),!1}catch(j){throw this.settings.debug&&window.console&&console.log("Exception occurred when checking element "+b.id+", check the '"+e.method+"' method.",j),j instanceof TypeError&&(j.message+=". Exception occurred when checking element "+b.id+", check the '"+e.method+"' method."),j}}if(!h)return this.objectLength(f)&&this.successList.push(b),!0},customDataMessage:function(b,c){return a(b).data("msg"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase())||a(b).data("msg")},customMessage:function(a,b){var c=this.settings.messages[a];return c&&(c.constructor===String?c:c[b])},findDefined:function(){for(var a=0;aWarning: No message defined for "+b.name+"")},formatAndAdd:function(b,c){var d=this.defaultMessage(b,c.method),e=/\$?\{(\d+)\}/g;"function"==typeof d?d=d.call(this,c.parameters,b):e.test(d)&&(d=a.validator.format(d.replace(e,"{$1}"),c.parameters)),this.errorList.push({message:d,element:b,method:c.method}),this.errorMap[b.name]=d,this.submitted[b.name]=d},addWrapper:function(a){return this.settings.wrapper&&(a=a.add(a.parent(this.settings.wrapper))),a},defaultShowErrors:function(){var a,b,c;for(a=0;this.errorList[a];a++)c=this.errorList[a],this.settings.highlight&&this.settings.highlight.call(this,c.element,this.settings.errorClass,this.settings.validClass),this.showLabel(c.element,c.message);if(this.errorList.length&&(this.toShow=this.toShow.add(this.containers)),this.settings.success)for(a=0;this.successList[a];a++)this.showLabel(this.successList[a]);if(this.settings.unhighlight)for(a=0,b=this.validElements();b[a];a++)this.settings.unhighlight.call(this,b[a],this.settings.errorClass,this.settings.validClass);this.toHide=this.toHide.not(this.toShow),this.hideErrors(),this.addWrapper(this.toShow).show()},validElements:function(){return this.currentElements.not(this.invalidElements())},invalidElements:function(){return a(this.errorList).map(function(){return this.element})},showLabel:function(b,c){var d,e,f,g=this.errorsFor(b),h=this.idOrName(b),i=a(b).attr("aria-describedby");g.length?(g.removeClass(this.settings.validClass).addClass(this.settings.errorClass),g.html(c)):(g=a("<"+this.settings.errorElement+">").attr("id",h+"-error").addClass(this.settings.errorClass).html(c||""),d=g,this.settings.wrapper&&(d=g.hide().show().wrap("<"+this.settings.wrapper+"/>").parent()),this.labelContainer.length?this.labelContainer.append(d):this.settings.errorPlacement?this.settings.errorPlacement(d,a(b)):d.insertAfter(b),g.is("label")?g.attr("for",h):0===g.parents("label[for='"+h+"']").length&&(f=g.attr("id").replace(/(:|\.|\[|\]|\$)/g,"\\$1"),i?i.match(new RegExp("\\b"+f+"\\b"))||(i+=" "+f):i=f,a(b).attr("aria-describedby",i),e=this.groups[b.name],e&&a.each(this.groups,function(b,c){c===e&&a("[name='"+b+"']",this.currentForm).attr("aria-describedby",g.attr("id"))}))),!c&&this.settings.success&&(g.text(""),"string"==typeof this.settings.success?g.addClass(this.settings.success):this.settings.success(g,b)),this.toShow=this.toShow.add(g)},errorsFor:function(b){var c=this.idOrName(b),d=a(b).attr("aria-describedby"),e="label[for='"+c+"'], label[for='"+c+"'] *";return d&&(e=e+", #"+d.replace(/\s+/g,", #")),this.errors().filter(e)},idOrName:function(a){return this.groups[a.name]||(this.checkable(a)?a.name:a.id||a.name)},validationTargetFor:function(b){return this.checkable(b)&&(b=this.findByName(b.name)),a(b).not(this.settings.ignore)[0]},checkable:function(a){return/radio|checkbox/i.test(a.type)},findByName:function(b){return a(this.currentForm).find("[name='"+b+"']")},getLength:function(b,c){switch(c.nodeName.toLowerCase()){case"select":return a("option:selected",c).length;case"input":if(this.checkable(c))return this.findByName(c.name).filter(":checked").length}return b.length},depend:function(a,b){return this.dependTypes[typeof a]?this.dependTypes[typeof a](a,b):!0},dependTypes:{"boolean":function(a){return a},string:function(b,c){return!!a(b,c.form).length},"function":function(a,b){return a(b)}},optional:function(b){var c=this.elementValue(b);return!a.validator.methods.required.call(this,c,b)&&"dependency-mismatch"},startRequest:function(a){this.pending[a.name]||(this.pendingRequest++,this.pending[a.name]=!0)},stopRequest:function(b,c){this.pendingRequest--,this.pendingRequest<0&&(this.pendingRequest=0),delete this.pending[b.name],c&&0===this.pendingRequest&&this.formSubmitted&&this.form()?(a(this.currentForm).submit(),this.formSubmitted=!1):!c&&0===this.pendingRequest&&this.formSubmitted&&(a(this.currentForm).triggerHandler("invalid-form",[this]),this.formSubmitted=!1)},previousValue:function(b){return a.data(b,"previousValue")||a.data(b,"previousValue",{old:null,valid:!0,message:this.defaultMessage(b,"remote")})},destroy:function(){this.resetForm(),a(this.currentForm).off(".validate").removeData("validator")}},classRuleSettings:{required:{required:!0},email:{email:!0},url:{url:!0},date:{date:!0},dateISO:{dateISO:!0},number:{number:!0},digits:{digits:!0},creditcard:{creditcard:!0}},addClassRules:function(b,c){b.constructor===String?this.classRuleSettings[b]=c:a.extend(this.classRuleSettings,b)},classRules:function(b){var c={},d=a(b).attr("class");return d&&a.each(d.split(" "),function(){this in a.validator.classRuleSettings&&a.extend(c,a.validator.classRuleSettings[this])}),c},normalizeAttributeRule:function(a,b,c,d){/min|max/.test(c)&&(null===b||/number|range|text/.test(b))&&(d=Number(d),isNaN(d)&&(d=void 0)),d||0===d?a[c]=d:b===c&&"range"!==b&&(a[c]=!0)},attributeRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)"required"===c?(d=b.getAttribute(c),""===d&&(d=!0),d=!!d):d=f.attr(c),this.normalizeAttributeRule(e,g,c,d);return e.maxlength&&/-1|2147483647|524288/.test(e.maxlength)&&delete e.maxlength,e},dataRules:function(b){var c,d,e={},f=a(b),g=b.getAttribute("type");for(c in a.validator.methods)d=f.data("rule"+c.charAt(0).toUpperCase()+c.substring(1).toLowerCase()),this.normalizeAttributeRule(e,g,c,d);return e},staticRules:function(b){var c={},d=a.data(b.form,"validator");return d.settings.rules&&(c=a.validator.normalizeRule(d.settings.rules[b.name])||{}),c},normalizeRules:function(b,c){return a.each(b,function(d,e){if(e===!1)return void delete b[d];if(e.param||e.depends){var f=!0;switch(typeof e.depends){case"string":f=!!a(e.depends,c.form).length;break;case"function":f=e.depends.call(c,c)}f?b[d]=void 0!==e.param?e.param:!0:delete b[d]}}),a.each(b,function(d,e){b[d]=a.isFunction(e)?e(c):e}),a.each(["minlength","maxlength"],function(){b[this]&&(b[this]=Number(b[this]))}),a.each(["rangelength","range"],function(){var c;b[this]&&(a.isArray(b[this])?b[this]=[Number(b[this][0]),Number(b[this][1])]:"string"==typeof b[this]&&(c=b[this].replace(/[\[\]]/g,"").split(/[\s,]+/),b[this]=[Number(c[0]),Number(c[1])]))}),a.validator.autoCreateRanges&&(null!=b.min&&null!=b.max&&(b.range=[b.min,b.max],delete b.min,delete b.max),null!=b.minlength&&null!=b.maxlength&&(b.rangelength=[b.minlength,b.maxlength],delete b.minlength,delete b.maxlength)),b},normalizeRule:function(b){if("string"==typeof b){var c={};a.each(b.split(/\s/),function(){c[this]=!0}),b=c}return b},addMethod:function(b,c,d){a.validator.methods[b]=c,a.validator.messages[b]=void 0!==d?d:a.validator.messages[b],c.length<3&&a.validator.addClassRules(b,a.validator.normalizeRule(b))},methods:{required:function(b,c,d){if(!this.depend(d,c))return"dependency-mismatch";if("select"===c.nodeName.toLowerCase()){var e=a(c).val();return e&&e.length>0}return this.checkable(c)?this.getLength(b,c)>0:b.length>0},email:function(a,b){return this.optional(b)||/^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test(a)},url:function(a,b){return this.optional(b)||/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(a)},date:function(a,b){return this.optional(b)||!/Invalid|NaN/.test(new Date(a).toString())},dateISO:function(a,b){return this.optional(b)||/^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test(a)},number:function(a,b){return this.optional(b)||/^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(a)},digits:function(a,b){return this.optional(b)||/^\d+$/.test(a)},creditcard:function(a,b){if(this.optional(b))return"dependency-mismatch";if(/[^0-9 \-]+/.test(a))return!1;var c,d,e=0,f=0,g=!1;if(a=a.replace(/\D/g,""),a.length<13||a.length>19)return!1;for(c=a.length-1;c>=0;c--)d=a.charAt(c),f=parseInt(d,10),g&&(f*=2)>9&&(f-=9),e+=f,g=!g;return e%10===0},minlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d},maxlength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||d>=e},rangelength:function(b,c,d){var e=a.isArray(b)?b.length:this.getLength(b,c);return this.optional(c)||e>=d[0]&&e<=d[1]},min:function(a,b,c){return this.optional(b)||a>=c},max:function(a,b,c){return this.optional(b)||c>=a},range:function(a,b,c){return this.optional(b)||a>=c[0]&&a<=c[1]},equalTo:function(b,c,d){var e=a(d);return this.settings.onfocusout&&e.off(".validate-equalTo").on("blur.validate-equalTo",function(){a(c).valid()}),b===e.val()},remote:function(b,c,d){if(this.optional(c))return"dependency-mismatch";var e,f,g=this.previousValue(c);return this.settings.messages[c.name]||(this.settings.messages[c.name]={}),g.originalMessage=this.settings.messages[c.name].remote,this.settings.messages[c.name].remote=g.message,d="string"==typeof d&&{url:d}||d,g.old===b?g.valid:(g.old=b,e=this,this.startRequest(c),f={},f[c.name]=b,a.ajax(a.extend(!0,{mode:"abort",port:"validate"+c.name,dataType:"json",data:f,context:e.currentForm,success:function(d){var f,h,i,j=d===!0||"true"===d;e.settings.messages[c.name].remote=g.originalMessage,j?(i=e.formSubmitted,e.prepareElement(c),e.formSubmitted=i,e.successList.push(c),delete e.invalid[c.name],e.showErrors()):(f={},h=d||e.defaultMessage(c,"remote"),f[c.name]=g.message=a.isFunction(h)?h(b):h,e.invalid[c.name]=!0,e.showErrors(f)),g.valid=j,e.stopRequest(c,j)}},d)),"pending")}}});var b,c={};a.ajaxPrefilter?a.ajaxPrefilter(function(a,b,d){var e=a.port;"abort"===a.mode&&(c[e]&&c[e].abort(),c[e]=d)}):(b=a.ajax,a.ajax=function(d){var e=("mode"in d?d:a.ajaxSettings).mode,f=("port"in d?d:a.ajaxSettings).port;return"abort"===e?(c[f]&&c[f].abort(),c[f]=b.apply(this,arguments),c[f]):b.apply(this,arguments)})}); -------------------------------------------------------------------------------- /src/NetCoreWebApp/wwwroot/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js: -------------------------------------------------------------------------------- 1 | /*! 2 | ** Unobtrusive validation support library for jQuery and jQuery Validate 3 | ** Copyright (C) Microsoft Corporation. All rights reserved. 4 | */ 5 | 6 | /*jslint white: true, browser: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true, strict: false */ 7 | /*global document: false, jQuery: false */ 8 | 9 | (function ($) { 10 | var $jQval = $.validator, 11 | adapters, 12 | data_validation = "unobtrusiveValidation"; 13 | 14 | function setValidationValues(options, ruleName, value) { 15 | options.rules[ruleName] = value; 16 | if (options.message) { 17 | options.messages[ruleName] = options.message; 18 | } 19 | } 20 | 21 | function splitAndTrim(value) { 22 | return value.replace(/^\s+|\s+$/g, "").split(/\s*,\s*/g); 23 | } 24 | 25 | function escapeAttributeValue(value) { 26 | // As mentioned on http://api.jquery.com/category/selectors/ 27 | return value.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g, "\\$1"); 28 | } 29 | 30 | function getModelPrefix(fieldName) { 31 | return fieldName.substr(0, fieldName.lastIndexOf(".") + 1); 32 | } 33 | 34 | function appendModelPrefix(value, prefix) { 35 | if (value.indexOf("*.") === 0) { 36 | value = value.replace("*.", prefix); 37 | } 38 | return value; 39 | } 40 | 41 | function onError(error, inputElement) { // 'this' is the form element 42 | var container = $(this).find("[data-valmsg-for='" + escapeAttributeValue(inputElement[0].name) + "']"), 43 | replaceAttrValue = container.attr("data-valmsg-replace"), 44 | replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) !== false : null; 45 | 46 | container.removeClass("field-validation-valid").addClass("field-validation-error"); 47 | error.data("unobtrusiveContainer", container); 48 | 49 | if (replace) { 50 | container.empty(); 51 | error.removeClass("input-validation-error").appendTo(container); 52 | } 53 | else { 54 | error.hide(); 55 | } 56 | } 57 | 58 | function onErrors(event, validator) { // 'this' is the form element 59 | var container = $(this).find("[data-valmsg-summary=true]"), 60 | list = container.find("ul"); 61 | 62 | if (list && list.length && validator.errorList.length) { 63 | list.empty(); 64 | container.addClass("validation-summary-errors").removeClass("validation-summary-valid"); 65 | 66 | $.each(validator.errorList, function () { 67 | $("
  • ").html(this.message).appendTo(list); 68 | }); 69 | } 70 | } 71 | 72 | function onSuccess(error) { // 'this' is the form element 73 | var container = error.data("unobtrusiveContainer"); 74 | 75 | if (container) { 76 | var replaceAttrValue = container.attr("data-valmsg-replace"), 77 | replace = replaceAttrValue ? $.parseJSON(replaceAttrValue) : null; 78 | 79 | container.addClass("field-validation-valid").removeClass("field-validation-error"); 80 | error.removeData("unobtrusiveContainer"); 81 | 82 | if (replace) { 83 | container.empty(); 84 | } 85 | } 86 | } 87 | 88 | function onReset(event) { // 'this' is the form element 89 | var $form = $(this), 90 | key = '__jquery_unobtrusive_validation_form_reset'; 91 | if ($form.data(key)) { 92 | return; 93 | } 94 | // Set a flag that indicates we're currently resetting the form. 95 | $form.data(key, true); 96 | try { 97 | $form.data("validator").resetForm(); 98 | } finally { 99 | $form.removeData(key); 100 | } 101 | 102 | $form.find(".validation-summary-errors") 103 | .addClass("validation-summary-valid") 104 | .removeClass("validation-summary-errors"); 105 | $form.find(".field-validation-error") 106 | .addClass("field-validation-valid") 107 | .removeClass("field-validation-error") 108 | .removeData("unobtrusiveContainer") 109 | .find(">*") // If we were using valmsg-replace, get the underlying error 110 | .removeData("unobtrusiveContainer"); 111 | } 112 | 113 | function validationInfo(form) { 114 | var $form = $(form), 115 | result = $form.data(data_validation), 116 | onResetProxy = $.proxy(onReset, form), 117 | defaultOptions = $jQval.unobtrusive.options || {}, 118 | execInContext = function (name, args) { 119 | var func = defaultOptions[name]; 120 | func && $.isFunction(func) && func.apply(form, args); 121 | } 122 | 123 | if (!result) { 124 | result = { 125 | options: { // options structure passed to jQuery Validate's validate() method 126 | errorClass: defaultOptions.errorClass || "input-validation-error", 127 | errorElement: defaultOptions.errorElement || "span", 128 | errorPlacement: function () { 129 | onError.apply(form, arguments); 130 | execInContext("errorPlacement", arguments); 131 | }, 132 | invalidHandler: function () { 133 | onErrors.apply(form, arguments); 134 | execInContext("invalidHandler", arguments); 135 | }, 136 | messages: {}, 137 | rules: {}, 138 | success: function () { 139 | onSuccess.apply(form, arguments); 140 | execInContext("success", arguments); 141 | } 142 | }, 143 | attachValidation: function () { 144 | $form 145 | .off("reset." + data_validation, onResetProxy) 146 | .on("reset." + data_validation, onResetProxy) 147 | .validate(this.options); 148 | }, 149 | validate: function () { // a validation function that is called by unobtrusive Ajax 150 | $form.validate(); 151 | return $form.valid(); 152 | } 153 | }; 154 | $form.data(data_validation, result); 155 | } 156 | 157 | return result; 158 | } 159 | 160 | $jQval.unobtrusive = { 161 | adapters: [], 162 | 163 | parseElement: function (element, skipAttach) { 164 | /// 165 | /// Parses a single HTML element for unobtrusive validation attributes. 166 | /// 167 | /// The HTML element to be parsed. 168 | /// [Optional] true to skip attaching the 169 | /// validation to the form. If parsing just this single element, you should specify true. 170 | /// If parsing several elements, you should specify false, and manually attach the validation 171 | /// to the form when you are finished. The default is false. 172 | var $element = $(element), 173 | form = $element.parents("form")[0], 174 | valInfo, rules, messages; 175 | 176 | if (!form) { // Cannot do client-side validation without a form 177 | return; 178 | } 179 | 180 | valInfo = validationInfo(form); 181 | valInfo.options.rules[element.name] = rules = {}; 182 | valInfo.options.messages[element.name] = messages = {}; 183 | 184 | $.each(this.adapters, function () { 185 | var prefix = "data-val-" + this.name, 186 | message = $element.attr(prefix), 187 | paramValues = {}; 188 | 189 | if (message !== undefined) { // Compare against undefined, because an empty message is legal (and falsy) 190 | prefix += "-"; 191 | 192 | $.each(this.params, function () { 193 | paramValues[this] = $element.attr(prefix + this); 194 | }); 195 | 196 | this.adapt({ 197 | element: element, 198 | form: form, 199 | message: message, 200 | params: paramValues, 201 | rules: rules, 202 | messages: messages 203 | }); 204 | } 205 | }); 206 | 207 | $.extend(rules, { "__dummy__": true }); 208 | 209 | if (!skipAttach) { 210 | valInfo.attachValidation(); 211 | } 212 | }, 213 | 214 | parse: function (selector) { 215 | /// 216 | /// Parses all the HTML elements in the specified selector. It looks for input elements decorated 217 | /// with the [data-val=true] attribute value and enables validation according to the data-val-* 218 | /// attribute values. 219 | /// 220 | /// Any valid jQuery selector. 221 | 222 | // $forms includes all forms in selector's DOM hierarchy (parent, children and self) that have at least one 223 | // element with data-val=true 224 | var $selector = $(selector), 225 | $forms = $selector.parents() 226 | .addBack() 227 | .filter("form") 228 | .add($selector.find("form")) 229 | .has("[data-val=true]"); 230 | 231 | $selector.find("[data-val=true]").each(function () { 232 | $jQval.unobtrusive.parseElement(this, true); 233 | }); 234 | 235 | $forms.each(function () { 236 | var info = validationInfo(this); 237 | if (info) { 238 | info.attachValidation(); 239 | } 240 | }); 241 | } 242 | }; 243 | 244 | adapters = $jQval.unobtrusive.adapters; 245 | 246 | adapters.add = function (adapterName, params, fn) { 247 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation. 248 | /// The name of the adapter to be added. This matches the name used 249 | /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name). 250 | /// [Optional] An array of parameter names (strings) that will 251 | /// be extracted from the data-val-nnnn-mmmm HTML attributes (where nnnn is the adapter name, and 252 | /// mmmm is the parameter name). 253 | /// The function to call, which adapts the values from the HTML 254 | /// attributes into jQuery Validate rules and/or messages. 255 | /// 256 | if (!fn) { // Called with no params, just a function 257 | fn = params; 258 | params = []; 259 | } 260 | this.push({ name: adapterName, params: params, adapt: fn }); 261 | return this; 262 | }; 263 | 264 | adapters.addBool = function (adapterName, ruleName) { 265 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where 266 | /// the jQuery Validate validation rule has no parameter values. 267 | /// The name of the adapter to be added. This matches the name used 268 | /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name). 269 | /// [Optional] The name of the jQuery Validate rule. If not provided, the value 270 | /// of adapterName will be used instead. 271 | /// 272 | return this.add(adapterName, function (options) { 273 | setValidationValues(options, ruleName || adapterName, true); 274 | }); 275 | }; 276 | 277 | adapters.addMinMax = function (adapterName, minRuleName, maxRuleName, minMaxRuleName, minAttribute, maxAttribute) { 278 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where 279 | /// the jQuery Validate validation has three potential rules (one for min-only, one for max-only, and 280 | /// one for min-and-max). The HTML parameters are expected to be named -min and -max. 281 | /// The name of the adapter to be added. This matches the name used 282 | /// in the data-val-nnnn HTML attribute (where nnnn is the adapter name). 283 | /// The name of the jQuery Validate rule to be used when you only 284 | /// have a minimum value. 285 | /// The name of the jQuery Validate rule to be used when you only 286 | /// have a maximum value. 287 | /// The name of the jQuery Validate rule to be used when you 288 | /// have both a minimum and maximum value. 289 | /// [Optional] The name of the HTML attribute that 290 | /// contains the minimum value. The default is "min". 291 | /// [Optional] The name of the HTML attribute that 292 | /// contains the maximum value. The default is "max". 293 | /// 294 | return this.add(adapterName, [minAttribute || "min", maxAttribute || "max"], function (options) { 295 | var min = options.params.min, 296 | max = options.params.max; 297 | 298 | if (min && max) { 299 | setValidationValues(options, minMaxRuleName, [min, max]); 300 | } 301 | else if (min) { 302 | setValidationValues(options, minRuleName, min); 303 | } 304 | else if (max) { 305 | setValidationValues(options, maxRuleName, max); 306 | } 307 | }); 308 | }; 309 | 310 | adapters.addSingleVal = function (adapterName, attribute, ruleName) { 311 | /// Adds a new adapter to convert unobtrusive HTML into a jQuery Validate validation, where 312 | /// the jQuery Validate validation rule has a single value. 313 | /// The name of the adapter to be added. This matches the name used 314 | /// in the data-val-nnnn HTML attribute(where nnnn is the adapter name). 315 | /// [Optional] The name of the HTML attribute that contains the value. 316 | /// The default is "val". 317 | /// [Optional] The name of the jQuery Validate rule. If not provided, the value 318 | /// of adapterName will be used instead. 319 | /// 320 | return this.add(adapterName, [attribute || "val"], function (options) { 321 | setValidationValues(options, ruleName || adapterName, options.params[attribute]); 322 | }); 323 | }; 324 | 325 | $jQval.addMethod("__dummy__", function (value, element, params) { 326 | return true; 327 | }); 328 | 329 | $jQval.addMethod("regex", function (value, element, params) { 330 | var match; 331 | if (this.optional(element)) { 332 | return true; 333 | } 334 | 335 | match = new RegExp(params).exec(value); 336 | return (match && (match.index === 0) && (match[0].length === value.length)); 337 | }); 338 | 339 | $jQval.addMethod("nonalphamin", function (value, element, nonalphamin) { 340 | var match; 341 | if (nonalphamin) { 342 | match = value.match(/\W/g); 343 | match = match && match.length >= nonalphamin; 344 | } 345 | return match; 346 | }); 347 | 348 | if ($jQval.methods.extension) { 349 | adapters.addSingleVal("accept", "mimtype"); 350 | adapters.addSingleVal("extension", "extension"); 351 | } else { 352 | // for backward compatibility, when the 'extension' validation method does not exist, such as with versions 353 | // of JQuery Validation plugin prior to 1.10, we should use the 'accept' method for 354 | // validating the extension, and ignore mime-type validations as they are not supported. 355 | adapters.addSingleVal("extension", "extension", "accept"); 356 | } 357 | 358 | adapters.addSingleVal("regex", "pattern"); 359 | adapters.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url"); 360 | adapters.addMinMax("length", "minlength", "maxlength", "rangelength").addMinMax("range", "min", "max", "range"); 361 | adapters.addMinMax("minlength", "minlength").addMinMax("maxlength", "minlength", "maxlength"); 362 | adapters.add("equalto", ["other"], function (options) { 363 | var prefix = getModelPrefix(options.element.name), 364 | other = options.params.other, 365 | fullOtherName = appendModelPrefix(other, prefix), 366 | element = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(fullOtherName) + "']")[0]; 367 | 368 | setValidationValues(options, "equalTo", element); 369 | }); 370 | adapters.add("required", function (options) { 371 | // jQuery Validate equates "required" with "mandatory" for checkbox elements 372 | if (options.element.tagName.toUpperCase() !== "INPUT" || options.element.type.toUpperCase() !== "CHECKBOX") { 373 | setValidationValues(options, "required", true); 374 | } 375 | }); 376 | adapters.add("remote", ["url", "type", "additionalfields"], function (options) { 377 | var value = { 378 | url: options.params.url, 379 | type: options.params.type || "GET", 380 | data: {} 381 | }, 382 | prefix = getModelPrefix(options.element.name); 383 | 384 | $.each(splitAndTrim(options.params.additionalfields || options.element.name), function (i, fieldName) { 385 | var paramName = appendModelPrefix(fieldName, prefix); 386 | value.data[paramName] = function () { 387 | var field = $(options.form).find(":input").filter("[name='" + escapeAttributeValue(paramName) + "']"); 388 | // For checkboxes and radio buttons, only pick up values from checked fields. 389 | if (field.is(":checkbox")) { 390 | return field.filter(":checked").val() || field.filter(":hidden").val() || ''; 391 | } 392 | else if (field.is(":radio")) { 393 | return field.filter(":checked").val() || ''; 394 | } 395 | return field.val(); 396 | }; 397 | }); 398 | 399 | setValidationValues(options, "remote", value); 400 | }); 401 | adapters.add("password", ["min", "nonalphamin", "regex"], function (options) { 402 | if (options.params.min) { 403 | setValidationValues(options, "minlength", options.params.min); 404 | } 405 | if (options.params.nonalphamin) { 406 | setValidationValues(options, "nonalphamin", options.params.nonalphamin); 407 | } 408 | if (options.params.regex) { 409 | setValidationValues(options, "regex", options.params.regex); 410 | } 411 | }); 412 | 413 | $(function () { 414 | $jQval.unobtrusive.parse(document); 415 | }); 416 | }(jQuery)); --------------------------------------------------------------------------------