├── README.md ├── SimpleCQRS ├── SimpleCQRS.pidb ├── Message.cs ├── app.config ├── AssemblyInfo.cs ├── Events.cs ├── CommandHandlers.cs ├── Commands.cs ├── FakeBus.cs ├── EventStore.cs ├── Domain.cs ├── SimpleCQRS.csproj ├── ReadModel.cs └── InfrastructureCrap.DontBotherReadingItsNotImportant.cs ├── CQRSGui ├── Global.asax ├── ServiceLocator.cs ├── Views │ ├── Shared │ │ ├── Error.aspx │ │ └── Site.Master │ ├── Home │ │ ├── Add.aspx │ │ ├── ChangeName.aspx │ │ ├── CheckIn.aspx │ │ ├── Remove.aspx │ │ ├── Index.aspx │ │ └── Details.aspx │ └── Web.config ├── Web.Debug.config ├── Web.Release.config ├── Properties │ └── AssemblyInfo.cs ├── ReadModel.cs ├── FakeBus.cs ├── Global.asax.cs ├── EventStore.cs ├── Controllers │ └── HomeController.cs ├── Web.config ├── Scripts │ ├── MicrosoftMvcAjax.js │ ├── MicrosoftMvcValidation.js │ ├── MicrosoftMvcAjax.debug.js │ ├── jquery.validate.min.js │ └── MicrosoftMvcValidation.debug.js ├── Content │ └── Site.css └── CQRSGui.csproj ├── FsSimpleCQRS ├── EventStore.fs ├── Events.fs ├── Commands.fs ├── CommandHandlers.fs ├── Domain.fs ├── ReadModel.fs └── FsSimpleCQRS.fsproj ├── .gitignore ├── SimplestPossibleThing.userprefs └── SimplestPossibleThing.sln /README.md: -------------------------------------------------------------------------------- 1 | This repository has moved to Codeberg: https://codeberg.org/thinkbeforecoding/m-r 2 | -------------------------------------------------------------------------------- /SimpleCQRS/SimpleCQRS.pidb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thinkbeforecoding/m-r/HEAD/SimpleCQRS/SimpleCQRS.pidb -------------------------------------------------------------------------------- /CQRSGui/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="CQRSGui.MvcApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /SimpleCQRS/Message.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace SimpleCQRS 3 | { 4 | public interface Message 5 | { 6 | } 7 | } 8 | 9 | -------------------------------------------------------------------------------- /SimpleCQRS/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /CQRSGui/ServiceLocator.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | namespace CQRSGui 4 | { 5 | public static class ServiceLocator 6 | { 7 | public static FakeBus Bus { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /FsSimpleCQRS/EventStore.fs: -------------------------------------------------------------------------------- 1 | namespace SimpleCQRS 2 | open System 3 | open SimpleCQRS.Events 4 | 5 | type IEventStore = 6 | abstract member GetEventsForAggregate : Guid -> Event seq 7 | abstract member SaveEvents : Guid -> int -> Event seq -> unit 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | #ignore thumbnails created by windows 3 | Thumbs.db 4 | #Ignore files build by Visual Studio 5 | *.obj 6 | *.exe 7 | *.pdb 8 | *.user 9 | *.aps 10 | *.pch 11 | *.vspscc 12 | *_i.c 13 | *_p.c 14 | *.ncb 15 | *.suo 16 | *.tlb 17 | *.tlh 18 | *.bak 19 | *.cache 20 | *.ilk 21 | *.log 22 | [Bb]in 23 | [Dd]ebug*/ 24 | *.lib 25 | *.sbr 26 | obj/ 27 | [Rr]elease*/ 28 | _ReSharper*/ 29 | [Tt]est[Rr]esult* -------------------------------------------------------------------------------- /CQRSGui/Views/Shared/Error.aspx: -------------------------------------------------------------------------------- 1 | <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %> 2 | 3 | 4 | Error 5 | 6 | 7 | 8 |

9 | Sorry, an error occurred while processing your request. 10 |

11 |
12 | -------------------------------------------------------------------------------- /CQRSGui/Views/Home/Add.aspx: -------------------------------------------------------------------------------- 1 | <%@ Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Views/Shared/Site.Master" %> 2 | 3 | 4 | <% using (Html.BeginForm()) 5 | {%> 6 | 7 | Name:<%: Html.TextBox("Name") %>
8 | 9 | 10 | <% 11 | }%> 12 |
13 | -------------------------------------------------------------------------------- /CQRSGui/Views/Home/ChangeName.aspx: -------------------------------------------------------------------------------- 1 | <%@ Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Views/Shared/Site.Master" %> 2 | 3 | 4 | <% using (Html.BeginForm()) 5 | {%> 6 | <%: Html.Hidden("Id",Model.Id) %> 7 | <%: Html.Hidden("Version",Model.Version) %> 8 | Name:<%: Html.TextBox("Name") %>
9 | 10 | 11 | <% 12 | }%> 13 |
14 | -------------------------------------------------------------------------------- /CQRSGui/Views/Home/CheckIn.aspx: -------------------------------------------------------------------------------- 1 | <%@ Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Views/Shared/Site.Master" %> 2 | 3 | 4 | <% using (Html.BeginForm()) 5 | {%> 6 | <%: Html.Hidden("Id",Model.Id) %> 7 | <%: Html.Hidden("Version",Model.Version) %> 8 | Number:<%: Html.TextBox("Number") %>
9 | 10 | 11 | <% 12 | }%> 13 |
14 | -------------------------------------------------------------------------------- /CQRSGui/Views/Home/Remove.aspx: -------------------------------------------------------------------------------- 1 | <%@ Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Views/Shared/Site.Master" %> 2 | 3 | 4 | <% using (Html.BeginForm()) 5 | {%> 6 | <%: Html.Hidden("Id",Model.Id) %> 7 | <%: Html.Hidden("Version",Model.Version) %> 8 | Number:<%: Html.TextBox("Number") %>
9 | 10 | 11 | <% 12 | }%> 13 | 14 |
15 | -------------------------------------------------------------------------------- /CQRSGui/Views/Home/Index.aspx: -------------------------------------------------------------------------------- 1 | <%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage>" %> 2 | 3 | 4 | Home Page 5 | 6 | 7 | 8 |

All items:

9 |
    <% foreach (var inventoryItemListDto in Model) 10 | {%>
  • 11 | <%: Html.ActionLink("Name: " + inventoryItemListDto.Name,"Details",new{Id=inventoryItemListDto.Id}) %> 12 |
  • 13 | <%} %>
14 | <%: Html.ActionLink("Add","Add") %> 15 |
16 | -------------------------------------------------------------------------------- /SimplestPossibleThing.userprefs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /CQRSGui/Views/Home/Details.aspx: -------------------------------------------------------------------------------- 1 | <%@ Page Title="" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Views/Shared/Site.Master" %> 2 | 3 | 4 |

Details:

5 | Id: <%:Model.Id%>
6 | Name: <%:Model.Name%>
7 | Count: <%: Model.CurrentCount %>

8 | 9 | <%: Html.ActionLink("Rename","ChangeName", new{Id=Model.Id}) %>
10 | <%: Html.ActionLink("Deactivate","Deactivate",new{Id=Model.Id, Version=Model.Version}) %>
11 | <%: Html.ActionLink("Check in","CheckIn", new{Id=Model.Id}) %>
12 | <%: Html.ActionLink("Remove","Remove", new{Id=Model.Id,Version=Model.Version}) %> 13 |
14 | -------------------------------------------------------------------------------- /FsSimpleCQRS/Events.fs: -------------------------------------------------------------------------------- 1 | namespace SimpleCQRS.Events 2 | open System 3 | 4 | type Event = 5 | interface 6 | end 7 | 8 | type EventMetadata = 9 | { 10 | Version : int 11 | } 12 | 13 | type InventoryItemDeactivated = 14 | { 15 | Id: Guid 16 | } 17 | interface Event 18 | 19 | 20 | type InventoryItemCreated = 21 | { 22 | Id: Guid 23 | Name: string 24 | } 25 | interface Event 26 | 27 | type InventoryItemRenamed = 28 | { 29 | Id: Guid 30 | NewName: string 31 | } 32 | interface Event 33 | 34 | type ItemsCheckedInToInventory = 35 | { 36 | Id: Guid 37 | Count: int 38 | } 39 | interface Event 40 | 41 | type ItemsRemovedFromInventory = 42 | { 43 | Id: Guid 44 | Count: int 45 | } 46 | interface Event 47 | -------------------------------------------------------------------------------- /FsSimpleCQRS/Commands.fs: -------------------------------------------------------------------------------- 1 | namespace SimpleCQRS.Commands 2 | open System 3 | 4 | type Command = 5 | interface 6 | end 7 | 8 | type ICommandSender = 9 | abstract member Send : Command -> unit 10 | 11 | type DeactivateInventoryItem = 12 | { 13 | InventoryItemId: Guid 14 | OriginalVersion: int 15 | } 16 | interface Command 17 | 18 | type CreateInventoryItem = 19 | { 20 | InventoryItemId: Guid 21 | Name: string 22 | } 23 | interface Command 24 | 25 | type RenameInventoryItem = 26 | { 27 | InventoryItemId: Guid 28 | NewName: string 29 | OriginalVersion: int 30 | } 31 | interface Command 32 | 33 | type CheckInItemsToInventory = 34 | { 35 | InventoryItemId: Guid 36 | Count: int 37 | OriginalVersion: int 38 | } 39 | interface Command 40 | 41 | type RemoveItemsFromInventory = 42 | { 43 | InventoryItemId: Guid 44 | Count: int 45 | OriginalVersion: int 46 | } 47 | interface Command 48 | -------------------------------------------------------------------------------- /SimpleCQRS/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | 4 | // Information about this assembly is defined by the following attributes. 5 | // Change them to the values specific to your project. 6 | 7 | [assembly: AssemblyTitle("SimpleCQRS")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("")] 12 | [assembly: AssemblyCopyright("")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". 17 | // The form "{Major}.{Minor}.*" will automatically update the build and revision, 18 | // and "{Major}.{Minor}.{Build}.*" will update just the revision. 19 | 20 | [assembly: AssemblyVersion("1.0.*")] 21 | 22 | // The following attributes are used to specify the signing key for the assembly, 23 | // if desired. See the Mono documentation for more information about signing. 24 | 25 | //[assembly: AssemblyDelaySign(false)] 26 | //[assembly: AssemblyKeyFile("")] 27 | 28 | -------------------------------------------------------------------------------- /CQRSGui/Views/Shared/Site.Master: -------------------------------------------------------------------------------- 1 | <%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %> 2 | 3 | 4 | 5 | 6 | <asp:ContentPlaceHolder ID="TitleContent" runat="server" /> 7 | 8 | 9 | 10 | 11 |
12 | 13 | 29 | 30 |
31 | 32 | 33 | 35 |
36 |
37 | 38 | 39 | -------------------------------------------------------------------------------- /FsSimpleCQRS/CommandHandlers.fs: -------------------------------------------------------------------------------- 1 | namespace SimpleCQRS 2 | open SimpleCQRS.Commands 3 | open SimpleCQRS.Events 4 | open InventoryItem 5 | 6 | 7 | type InventoryCommandHandlers (eventStore: IEventStore) = 8 | let load id = eventStore.GetEventsForAggregate id |> replayInventoryItem 9 | let save = eventStore.SaveEvents 10 | 11 | // load aggregate, execute f on it, then save 12 | let applyOn id version f = 13 | load id |> 14 | f |> 15 | save id version 16 | 17 | member x.Handle (c: CreateInventoryItem) = 18 | create c.InventoryItemId c.Name |> 19 | save c.InventoryItemId -1 20 | 21 | member x.Handle (c: DeactivateInventoryItem) = 22 | deactivate |> 23 | applyOn c.InventoryItemId c.OriginalVersion 24 | 25 | member x.Handle (c: RemoveItemsFromInventory) = 26 | remove c.Count |> 27 | applyOn c.InventoryItemId c.OriginalVersion 28 | 29 | member x.Handle (c: CheckInItemsToInventory) = 30 | checkIn c.Count |> 31 | applyOn c.InventoryItemId c.OriginalVersion 32 | 33 | member x.Handle (c: RenameInventoryItem) = 34 | rename c.NewName |> 35 | applyOn c.InventoryItemId c.OriginalVersion 36 | -------------------------------------------------------------------------------- /CQRSGui/Web.Debug.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /SimpleCQRS/Events.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace SimpleCQRS 3 | { 4 | public class Event : Message 5 | { 6 | public int Version; 7 | } 8 | 9 | public class InventoryItemDeactivated : Event { 10 | public readonly Guid Id; 11 | 12 | public InventoryItemDeactivated(Guid id) 13 | { 14 | Id = id; 15 | } 16 | } 17 | 18 | public class InventoryItemCreated : Event { 19 | public readonly Guid Id; 20 | public readonly string Name; 21 | public InventoryItemCreated(Guid id, string name) { 22 | Id = id; 23 | Name = name; 24 | } 25 | } 26 | 27 | public class InventoryItemRenamed : Event 28 | { 29 | public readonly Guid Id; 30 | public readonly string NewName; 31 | 32 | public InventoryItemRenamed(Guid id, string newName) 33 | { 34 | Id = id; 35 | NewName = newName; 36 | } 37 | } 38 | 39 | public class ItemsCheckedInToInventory : Event 40 | { 41 | public Guid Id; 42 | public readonly int Count; 43 | 44 | public ItemsCheckedInToInventory(Guid id, int count) { 45 | Id = id; 46 | Count = count; 47 | } 48 | } 49 | 50 | public class ItemsRemovedFromInventory : Event 51 | { 52 | public Guid Id; 53 | public readonly int Count; 54 | 55 | public ItemsRemovedFromInventory(Guid id, int count) { 56 | Id = id; 57 | Count = count; 58 | } 59 | } 60 | } 61 | 62 | -------------------------------------------------------------------------------- /CQRSGui/Web.Release.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | -------------------------------------------------------------------------------- /CQRSGui/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: AssemblyTitle("CQRSGui")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("CQRSGui")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2010")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("608117cf-f424-47eb-a480-05e10627b5f6")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Revision and Build Numbers 33 | // by using the '*' as shown below: 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /CQRSGui/ReadModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | using SimpleCQRS; 7 | 8 | namespace CQRSGui 9 | { 10 | public interface IReadModelFacade 11 | { 12 | IEnumerable GetInventoryItems(); 13 | InventoryItemDetailsDto GetInventoryItemDetails(Guid id); 14 | } 15 | 16 | public class ReadModelFacade : IReadModelFacade 17 | { 18 | private readonly IDatabase database; 19 | 20 | public ReadModelFacade(IDatabase database) 21 | { 22 | this.database = database; 23 | } 24 | 25 | public IEnumerable GetInventoryItems() 26 | { 27 | return database.List; 28 | } 29 | 30 | public InventoryItemDetailsDto GetInventoryItemDetails(Guid id) 31 | { 32 | return database.Details[id]; 33 | } 34 | } 35 | 36 | 37 | public class BullShitDatabase : IDatabase 38 | { 39 | private readonly Dictionary details = new Dictionary(); 40 | private readonly List list = new List(); 41 | 42 | public Dictionary Details 43 | { 44 | get { return details; } 45 | } 46 | 47 | public List List 48 | { 49 | get { return list; } 50 | } 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /CQRSGui/Views/Web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 16 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /SimpleCQRS/CommandHandlers.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SimpleCQRS 4 | { 5 | public class InventoryCommandHandlers 6 | { 7 | private readonly IRepository _repository; 8 | public InventoryCommandHandlers(IRepository repository) 9 | { 10 | _repository = repository; 11 | } 12 | public void Handle(CreateInventoryItem message) 13 | { 14 | var item = new InventoryItem(message.InventoryItemId, message.Name); 15 | _repository.Save(item, -1); 16 | } 17 | public void Handle(DeactivateInventoryItem message) 18 | { 19 | var item = _repository.GetById(message.InventoryItemId); 20 | item.Deactivate(); 21 | _repository.Save(item, message.OriginalVersion); 22 | } 23 | public void Handle(RemoveItemsFromInventory message) 24 | { 25 | var item = _repository.GetById(message.InventoryItemId); 26 | item.Remove(message.Count); 27 | _repository.Save(item, message.OriginalVersion); 28 | } 29 | public void Handle(CheckInItemsToInventory message) 30 | { 31 | var item = _repository.GetById(message.InventoryItemId); 32 | item.CheckIn(message.Count); 33 | _repository.Save(item, message.OriginalVersion); 34 | } 35 | public void Handle(RenameInventoryItem message) 36 | { 37 | var item = _repository.GetById(message.InventoryItemId); 38 | item.ChangeName(message.NewName); 39 | _repository.Save(item, message.OriginalVersion); 40 | } 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /FsSimpleCQRS/Domain.fs: -------------------------------------------------------------------------------- 1 | namespace SimpleCQRS 2 | open System 3 | open SimpleCQRS.Events 4 | 5 | module InventoryItem = 6 | 7 | type State = 8 | { 9 | Id: Guid 10 | Activated: bool 11 | } 12 | 13 | let fire o = 14 | [o :> Event] 15 | 16 | let rename newName s = 17 | if String.IsNullOrEmpty(newName) then raise (ArgumentException "newName") 18 | fire {InventoryItemRenamed.Id= s.Id; NewName = newName} 19 | 20 | let remove count s = 21 | if count <= 0 then raise (InvalidOperationException "cant remove negative count from inventory") 22 | fire {ItemsRemovedFromInventory.Id = s.Id; Count = count} 23 | 24 | let checkIn count s = 25 | if count <= 0 then raise (InvalidOperationException "must have a count greater than 0 to add to inventory") 26 | fire {ItemsCheckedInToInventory.Id= s.Id; Count = count} 27 | 28 | let deactivate s = 29 | if not s.Activated then raise (InvalidOperationException "already deactivated") 30 | fire {InventoryItemDeactivated.Id = s.Id} 31 | 32 | let create id name = 33 | fire {InventoryItemCreated.Id = id; Name = name} 34 | 35 | let applyOnInventoryItem s (e: Event) = 36 | match e with 37 | | :? InventoryItemCreated as e -> {Id = e.Id; Activated = true } 38 | | :? InventoryItemDeactivated as e -> {s with Activated = false; } 39 | | _ -> s 40 | 41 | let replay = Seq.fold 42 | 43 | let replayInventoryItem events = 44 | let empty = { Id = Guid.Empty; Activated = false} 45 | replay applyOnInventoryItem empty events 46 | -------------------------------------------------------------------------------- /SimpleCQRS/Commands.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | namespace SimpleCQRS 3 | { 4 | public class Command : Message 5 | { 6 | } 7 | 8 | public class DeactivateInventoryItem : Command { 9 | public readonly Guid InventoryItemId; 10 | public readonly int OriginalVersion; 11 | 12 | public DeactivateInventoryItem(Guid inventoryItemId, int originalVersion) 13 | { 14 | InventoryItemId = inventoryItemId; 15 | OriginalVersion = originalVersion; 16 | } 17 | } 18 | 19 | public class CreateInventoryItem : Command { 20 | public readonly Guid InventoryItemId; 21 | public readonly string Name; 22 | 23 | public CreateInventoryItem(Guid inventoryItemId, string name) 24 | { 25 | InventoryItemId = inventoryItemId; 26 | Name = name; 27 | } 28 | } 29 | 30 | public class RenameInventoryItem : Command { 31 | public readonly Guid InventoryItemId; 32 | public readonly string NewName; 33 | public readonly int OriginalVersion; 34 | 35 | public RenameInventoryItem(Guid inventoryItemId, string newName, int originalVersion) 36 | { 37 | InventoryItemId = inventoryItemId; 38 | NewName = newName; 39 | OriginalVersion = originalVersion; 40 | } 41 | } 42 | 43 | public class CheckInItemsToInventory : Command { 44 | public Guid InventoryItemId; 45 | public readonly int Count; 46 | public readonly int OriginalVersion; 47 | 48 | public CheckInItemsToInventory(Guid inventoryItemId, int count, int originalVersion) { 49 | InventoryItemId = inventoryItemId; 50 | Count = count; 51 | OriginalVersion = originalVersion; 52 | } 53 | } 54 | 55 | public class RemoveItemsFromInventory : Command { 56 | public Guid InventoryItemId; 57 | public readonly int Count; 58 | public readonly int OriginalVersion; 59 | 60 | public RemoveItemsFromInventory(Guid inventoryItemId, int count, int originalVersion) 61 | { 62 | InventoryItemId = inventoryItemId; 63 | Count = count; 64 | OriginalVersion = originalVersion; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /SimplestPossibleThing.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2012 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleCQRS", "SimpleCQRS\SimpleCQRS.csproj", "{DAFD2A8A-D6B0-4433-8DDF-B98460C64EC6}" 5 | EndProject 6 | Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FsSimpleCQRS", "FsSimpleCQRS\FsSimpleCQRS.fsproj", "{E1188906-3B37-4D26-A4DC-E5DAEC747D5F}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CQRSGui", "CQRSGui\CQRSGui.csproj", "{29ECBF37-9526-4CB6-8429-D09CF0301C26}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {29ECBF37-9526-4CB6-8429-D09CF0301C26}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {29ECBF37-9526-4CB6-8429-D09CF0301C26}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {29ECBF37-9526-4CB6-8429-D09CF0301C26}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {29ECBF37-9526-4CB6-8429-D09CF0301C26}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {DAFD2A8A-D6B0-4433-8DDF-B98460C64EC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {DAFD2A8A-D6B0-4433-8DDF-B98460C64EC6}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {DAFD2A8A-D6B0-4433-8DDF-B98460C64EC6}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {DAFD2A8A-D6B0-4433-8DDF-B98460C64EC6}.Release|Any CPU.Build.0 = Release|Any CPU 24 | {E1188906-3B37-4D26-A4DC-E5DAEC747D5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {E1188906-3B37-4D26-A4DC-E5DAEC747D5F}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {E1188906-3B37-4D26-A4DC-E5DAEC747D5F}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {E1188906-3B37-4D26-A4DC-E5DAEC747D5F}.Release|Any CPU.Build.0 = Release|Any CPU 28 | EndGlobalSection 29 | GlobalSection(SolutionProperties) = preSolution 30 | HideSolutionNode = FALSE 31 | EndGlobalSection 32 | GlobalSection(MonoDevelopProperties) = preSolution 33 | StartupItem = SimpleCQRS\SimpleCQRS.csproj 34 | EndGlobalSection 35 | EndGlobal 36 | -------------------------------------------------------------------------------- /FsSimpleCQRS/ReadModel.fs: -------------------------------------------------------------------------------- 1 | namespace SimpleCQRS 2 | 3 | open SimpleCQRS.Events 4 | open System 5 | open System.Collections.Generic 6 | 7 | type InventoryItemListDto = 8 | { 9 | Id: Guid 10 | mutable Name: string 11 | } 12 | 13 | type InventoryItemDetailsDto = 14 | { 15 | Id: Guid 16 | mutable Name: string 17 | mutable CurrentCount: int 18 | mutable Version: int 19 | } 20 | 21 | type IDatabase = 22 | abstract member Details : Dictionary 23 | abstract member List : List 24 | 25 | 26 | type InventoryListView(database: IDatabase) = 27 | member x.Handle (e: InventoryItemCreated) = 28 | database.List.Add({ Id = e.Id; Name = e.Name }) 29 | 30 | member x.Handle (e: InventoryItemRenamed) = 31 | let item = database.List.Find(fun x -> x.Id = e.Id) 32 | item.Name <- e.NewName 33 | 34 | member x.Handle (e: InventoryItemDeactivated) = 35 | database.List.RemoveAll (fun x -> x.Id = e.Id) |> ignore 36 | 37 | 38 | type InventoryItemDetailView(database: IDatabase) = 39 | let find id = database.Details.[id] 40 | 41 | member x.Handle (e: InventoryItemCreated, m : EventMetadata ) = 42 | database.Details.Add(e.Id, {Id = e.Id; Name = e.Name; CurrentCount = 0; Version= m.Version}) 43 | 44 | member x.Handle (e: InventoryItemRenamed, m : EventMetadata ) = 45 | let item = find e.Id 46 | item.Name <- e.NewName 47 | item.Version <- m.Version 48 | 49 | member x.Handle (e: ItemsRemovedFromInventory, m : EventMetadata ) = 50 | let item = find e.Id 51 | item.CurrentCount <- item.CurrentCount - e.Count 52 | item.Version <- m.Version 53 | 54 | member x.Handle (e: ItemsCheckedInToInventory, m : EventMetadata ) = 55 | let item = find e.Id 56 | item.CurrentCount <- item.CurrentCount + e.Count 57 | item.Version <- m.Version 58 | 59 | member x.Handle (e: InventoryItemDeactivated) = 60 | database.Details.Remove(e.Id) |> ignore 61 | -------------------------------------------------------------------------------- /SimpleCQRS/FakeBus.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading; 4 | 5 | namespace SimpleCQRS 6 | { 7 | public class FakeBus : ICommandSender, IEventPublisher 8 | { 9 | private readonly Dictionary>> _routes = new Dictionary>>(); 10 | 11 | public void RegisterHandler(Action handler) where T : Message 12 | { 13 | List> handlers; 14 | if(!_routes.TryGetValue(typeof(T), out handlers)) 15 | { 16 | handlers = new List>(); 17 | _routes.Add(typeof(T), handlers); 18 | } 19 | handlers.Add(DelegateAdjuster.CastArgument(x => handler(x))); 20 | } 21 | 22 | public void Send(T command) where T : Command 23 | { 24 | List> handlers; 25 | if (_routes.TryGetValue(typeof(T), out handlers)) 26 | { 27 | if (handlers.Count != 1) throw new InvalidOperationException("cannot send to more than one handler"); 28 | handlers[0](command); 29 | } 30 | else 31 | { 32 | throw new InvalidOperationException("no handler registered"); 33 | } 34 | } 35 | 36 | public void Publish(T @event) where T : Event 37 | { 38 | List> handlers; 39 | if (!_routes.TryGetValue(@event.GetType(), out handlers)) return; 40 | foreach(var handler in handlers) 41 | { 42 | //dispatch on thread pool for added awesomeness 43 | var handler1 = handler; 44 | ThreadPool.QueueUserWorkItem(x => handler1(@event)); 45 | } 46 | } 47 | } 48 | 49 | public interface Handles 50 | { 51 | void Handle(T message); 52 | } 53 | 54 | public interface ICommandSender 55 | { 56 | void Send(T command) where T : Command; 57 | 58 | } 59 | public interface IEventPublisher 60 | { 61 | void Publish(T @event) where T : Event; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /CQRSGui/FakeBus.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using SimpleCQRS.Commands; 4 | using SimpleCQRS.Events; 5 | 6 | namespace CQRSGui 7 | { 8 | public interface IEventPublisher 9 | { 10 | void Publish(Event @event, EventMetadata metadata); 11 | } 12 | 13 | 14 | public class FakeBus : IEventPublisher, ICommandSender 15 | { 16 | readonly Dictionary> handlers = new Dictionary>(); 17 | readonly Dictionary> metadataHandlers = new Dictionary>(); 18 | 19 | public void RegisterHandler(Action handler) 20 | { 21 | List list; 22 | if (!handlers.TryGetValue(typeof(T), out list)) 23 | { 24 | list = new List(); 25 | handlers.Add(typeof(T), list); 26 | } 27 | list.Add(handler); 28 | } 29 | 30 | public void RegisterHandler(Action handler) 31 | { 32 | List list; 33 | if (!metadataHandlers.TryGetValue(typeof(T), out list)) 34 | { 35 | list = new List(); 36 | metadataHandlers.Add(typeof(T), list); 37 | } 38 | list.Add(handler); 39 | } 40 | 41 | public void Publish(Event @event, EventMetadata metadata) 42 | { 43 | List list; 44 | Type type = @event.GetType(); 45 | if (handlers.TryGetValue(type, out list)) 46 | foreach (var handler in list) 47 | handler((dynamic)@event); 48 | if (metadataHandlers.TryGetValue(type, out list)) 49 | foreach (var handler in list) 50 | handler((dynamic)@event, metadata); 51 | } 52 | 53 | public void Send(Command command) 54 | { 55 | List list; 56 | if (!handlers.TryGetValue(command.GetType(), out list) || list.Count > 1) 57 | throw new Exception("A command should be sent to only one recipient"); 58 | dynamic handler = list[0]; 59 | handler((dynamic)command); 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /CQRSGui/Global.asax.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | using System.Web.Routing; 3 | using SimpleCQRS; 4 | using SimpleCQRS.Commands; 5 | using SimpleCQRS.Events; 6 | 7 | namespace CQRSGui 8 | { 9 | // Note: For instructions on enabling IIS6 or IIS7 classic mode, 10 | // visit http://go.microsoft.com/?LinkId=9394801 11 | 12 | public class MvcApplication : System.Web.HttpApplication 13 | { 14 | public static readonly IDatabase Database = new BullShitDatabase(); 15 | 16 | public static void RegisterRoutes(RouteCollection routes) 17 | { 18 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 19 | 20 | routes.MapRoute( 21 | "Default", // Route name 22 | "{controller}/{action}/{id}", // URL with parameters 23 | new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults 24 | ); 25 | 26 | } 27 | 28 | protected void Application_Start() 29 | { 30 | AreaRegistration.RegisterAllAreas(); 31 | 32 | RegisterRoutes(RouteTable.Routes); 33 | 34 | var bus = new FakeBus(); 35 | 36 | var storage = new EventStore(bus); 37 | var commands = new InventoryCommandHandlers(storage); 38 | bus.RegisterHandler(commands.Handle); 39 | bus.RegisterHandler(commands.Handle); 40 | bus.RegisterHandler(commands.Handle); 41 | bus.RegisterHandler(commands.Handle); 42 | bus.RegisterHandler(commands.Handle); 43 | var detail = new InventoryItemDetailView(Database); 44 | bus.RegisterHandler(detail.Handle); 45 | bus.RegisterHandler(detail.Handle); 46 | bus.RegisterHandler(detail.Handle); 47 | bus.RegisterHandler(detail.Handle); 48 | bus.RegisterHandler(detail.Handle); 49 | var list = new InventoryListView(Database); 50 | bus.RegisterHandler(list.Handle); 51 | bus.RegisterHandler(list.Handle); 52 | bus.RegisterHandler(list.Handle); 53 | ServiceLocator.Bus = bus; 54 | } 55 | } 56 | } -------------------------------------------------------------------------------- /CQRSGui/EventStore.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using SimpleCQRS; 5 | using SimpleCQRS.Events; 6 | 7 | namespace CQRSGui 8 | { 9 | public class EventStore : IEventStore 10 | { 11 | private readonly IEventPublisher _publisher; 12 | 13 | private struct EventDescriptor 14 | { 15 | 16 | public readonly Event EventData; 17 | public readonly Guid Id; 18 | public readonly int Version; 19 | 20 | public EventDescriptor(Guid id, Event eventData, int version) 21 | { 22 | EventData = eventData; 23 | Version = version; 24 | Id = id; 25 | } 26 | } 27 | 28 | public EventStore(IEventPublisher publisher) 29 | { 30 | _publisher = publisher; 31 | } 32 | 33 | private readonly Dictionary> _current = new Dictionary>(); 34 | 35 | public void SaveEvents(Guid aggregateId, int expectedVersion, IEnumerable events) 36 | { 37 | List eventDescriptors; 38 | if(!_current.TryGetValue(aggregateId, out eventDescriptors)) 39 | { 40 | eventDescriptors = new List(); 41 | _current.Add(aggregateId,eventDescriptors); 42 | } 43 | else if(eventDescriptors[eventDescriptors.Count - 1].Version != expectedVersion && expectedVersion != -1) 44 | { 45 | throw new ConcurrencyException(); 46 | } 47 | var i = expectedVersion; 48 | foreach (var @event in events) 49 | { 50 | i++; 51 | 52 | eventDescriptors.Add(new EventDescriptor(aggregateId,@event,i)); 53 | 54 | var metadata = new EventMetadata(i); 55 | 56 | _publisher.Publish(@event, metadata); 57 | } 58 | } 59 | 60 | public IEnumerable GetEventsForAggregate(Guid aggregateId) 61 | { 62 | List eventDescriptors; 63 | if (!_current.TryGetValue(aggregateId, out eventDescriptors)) 64 | { 65 | throw new AggregateNotFoundException(); 66 | } 67 | return eventDescriptors.Select(desc => desc.EventData).ToList(); 68 | } 69 | 70 | } 71 | 72 | public class AggregateNotFoundException : Exception 73 | { 74 | } 75 | 76 | public class ConcurrencyException : Exception 77 | { 78 | } 79 | 80 | } -------------------------------------------------------------------------------- /SimpleCQRS/EventStore.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace SimpleCQRS 6 | { 7 | public interface IEventStore 8 | { 9 | void SaveEvents(Guid aggregateId, IEnumerable events, int expectedVersion); 10 | List GetEventsForAggregate(Guid aggregateId); 11 | } 12 | 13 | public class EventStore : IEventStore 14 | { 15 | private readonly IEventPublisher _publisher; 16 | 17 | private struct EventDescriptor 18 | { 19 | 20 | public readonly Event EventData; 21 | public readonly Guid Id; 22 | public readonly int Version; 23 | 24 | public EventDescriptor(Guid id, Event eventData, int version) 25 | { 26 | EventData = eventData; 27 | Version = version; 28 | Id = id; 29 | } 30 | } 31 | 32 | public EventStore(IEventPublisher publisher) 33 | { 34 | _publisher = publisher; 35 | } 36 | 37 | private readonly Dictionary> _current = new Dictionary>(); 38 | 39 | public void SaveEvents(Guid aggregateId, IEnumerable events, int expectedVersion) 40 | { 41 | List eventDescriptors; 42 | if(!_current.TryGetValue(aggregateId, out eventDescriptors)) 43 | { 44 | eventDescriptors = new List(); 45 | _current.Add(aggregateId,eventDescriptors); 46 | } 47 | else if(eventDescriptors[eventDescriptors.Count - 1].Version != expectedVersion && expectedVersion != -1) 48 | { 49 | throw new ConcurrencyException(); 50 | } 51 | var i = expectedVersion; 52 | foreach (var @event in events) 53 | { 54 | i++; 55 | @event.Version = i; 56 | eventDescriptors.Add(new EventDescriptor(aggregateId,@event,i)); 57 | _publisher.Publish(@event); 58 | } 59 | } 60 | 61 | public List GetEventsForAggregate(Guid aggregateId) 62 | { 63 | List eventDescriptors; 64 | if (!_current.TryGetValue(aggregateId, out eventDescriptors)) 65 | { 66 | throw new AggregateNotFoundException(); 67 | } 68 | return eventDescriptors.Select(desc => desc.EventData).ToList(); 69 | } 70 | } 71 | 72 | public class AggregateNotFoundException : Exception 73 | { 74 | } 75 | 76 | public class ConcurrencyException : Exception 77 | { 78 | } 79 | } -------------------------------------------------------------------------------- /CQRSGui/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Web.Mvc; 3 | using SimpleCQRS; 4 | using SimpleCQRS.Commands; 5 | 6 | namespace CQRSGui.Controllers 7 | { 8 | [HandleError] 9 | public class HomeController : Controller 10 | { 11 | private FakeBus _bus; 12 | private IReadModelFacade _readmodel; 13 | 14 | public HomeController() 15 | { 16 | _bus = ServiceLocator.Bus; 17 | _readmodel = new ReadModelFacade(MvcApplication.Database); 18 | } 19 | 20 | public ActionResult Index() 21 | { 22 | ViewData.Model = _readmodel.GetInventoryItems(); 23 | 24 | return View(); 25 | } 26 | 27 | public ActionResult Details(Guid id) 28 | { 29 | ViewData.Model = _readmodel.GetInventoryItemDetails(id); 30 | return View(); 31 | } 32 | 33 | public ActionResult Add() 34 | { 35 | return View(); 36 | } 37 | 38 | [HttpPost] 39 | public ActionResult Add(string name) 40 | { 41 | _bus.Send(new CreateInventoryItem(Guid.NewGuid(), name)); 42 | 43 | return RedirectToAction("Index"); 44 | } 45 | 46 | public ActionResult ChangeName(Guid id) 47 | { 48 | ViewData.Model = _readmodel.GetInventoryItemDetails(id); 49 | return View(); 50 | } 51 | 52 | [HttpPost] 53 | public ActionResult ChangeName(Guid id, string name, int version) 54 | { 55 | var command = new RenameInventoryItem(id, name, version); 56 | _bus.Send(command); 57 | 58 | return RedirectToAction("Index"); 59 | } 60 | 61 | public ActionResult Deactivate(Guid id, int version) 62 | { 63 | _bus.Send(new DeactivateInventoryItem(id, version)); 64 | return RedirectToAction("Index"); 65 | } 66 | 67 | public ActionResult CheckIn(Guid id) 68 | { 69 | ViewData.Model = _readmodel.GetInventoryItemDetails(id); 70 | return View(); 71 | } 72 | 73 | [HttpPost] 74 | public ActionResult CheckIn(Guid id, int number, int version) 75 | { 76 | _bus.Send(new CheckInItemsToInventory(id, number, version)); 77 | return RedirectToAction("Index"); 78 | } 79 | 80 | public ActionResult Remove(Guid id) 81 | { 82 | ViewData.Model = _readmodel.GetInventoryItemDetails(id); 83 | return View(); 84 | } 85 | 86 | [HttpPost] 87 | public ActionResult Remove(Guid id, int number, int version) 88 | { 89 | _bus.Send(new RemoveItemsFromInventory(id, number, version)); 90 | return RedirectToAction("Index"); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /CQRSGui/Web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /FsSimpleCQRS/FsSimpleCQRS.fsproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 5 | 6 | 7 | 8 | Debug 9 | AnyCPU 10 | 8.0.30703 11 | 2.0 12 | e1188906-3b37-4d26-a4dc-e5daec747d5f 13 | Library 14 | FsSimpleCQRS 15 | FsSimpleCQRS 16 | v4.0 17 | FsSimpleCQRS 18 | 19 | 20 | 21 | true 22 | full 23 | false 24 | false 25 | bin\Debug\ 26 | DEBUG;TRACE 27 | 3 28 | bin\Debug\FsSimpleCQRS.XML 29 | 30 | 31 | pdbonly 32 | true 33 | true 34 | bin\Release\ 35 | TRACE 36 | 3 37 | bin\Release\FsSimpleCQRS.XML 38 | 39 | 40 | 41 | 42 | True 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 65 | -------------------------------------------------------------------------------- /SimpleCQRS/Domain.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace SimpleCQRS 5 | { 6 | public class InventoryItem : AggregateRoot 7 | { 8 | private bool _activated; 9 | private Guid _id; 10 | 11 | private void Apply(InventoryItemCreated e) 12 | { 13 | _id = e.Id; 14 | _activated = true; 15 | } 16 | 17 | private void Apply(InventoryItemDeactivated e) 18 | { 19 | _activated = false; 20 | } 21 | 22 | public void ChangeName(string newName) 23 | { 24 | if (string.IsNullOrEmpty(newName)) throw new ArgumentException("newName"); 25 | ApplyChange(new InventoryItemRenamed(_id, newName)); 26 | } 27 | 28 | public void Remove(int count) 29 | { 30 | if (count <= 0) throw new InvalidOperationException("cant remove negative count from inventory"); 31 | ApplyChange(new ItemsRemovedFromInventory(_id, count)); 32 | } 33 | 34 | 35 | public void CheckIn(int count) 36 | { 37 | if(count <= 0) throw new InvalidOperationException("must have a count greater than 0 to add to inventory"); 38 | ApplyChange(new ItemsCheckedInToInventory(_id, count)); 39 | } 40 | 41 | public void Deactivate() 42 | { 43 | if(!_activated) throw new InvalidOperationException("already deactivated"); 44 | ApplyChange(new InventoryItemDeactivated(_id)); 45 | } 46 | 47 | public override Guid Id 48 | { 49 | get { return _id; } 50 | } 51 | 52 | public InventoryItem() 53 | { 54 | // used to create in repository ... many ways to avoid this, eg making private constructor 55 | } 56 | 57 | public InventoryItem(Guid id, string name) 58 | { 59 | ApplyChange(new InventoryItemCreated(id, name)); 60 | } 61 | } 62 | 63 | public abstract class AggregateRoot 64 | { 65 | private readonly List _changes = new List(); 66 | 67 | public abstract Guid Id { get; } 68 | public int Version { get; internal set; } 69 | 70 | public IEnumerable GetUncommittedChanges() 71 | { 72 | return _changes; 73 | } 74 | 75 | public void MarkChangesAsCommitted() 76 | { 77 | _changes.Clear(); 78 | } 79 | 80 | public void LoadsFromHistory(IEnumerable history) 81 | { 82 | foreach (var e in history) ApplyChange(e, false); 83 | } 84 | 85 | protected void ApplyChange(Event @event) 86 | { 87 | ApplyChange(@event, true); 88 | } 89 | 90 | private void ApplyChange(Event @event, bool isNew) 91 | { 92 | this.AsDynamic().Apply(@event); 93 | if(isNew) _changes.Add(@event); 94 | } 95 | } 96 | 97 | public interface IRepository where T : AggregateRoot, new() 98 | { 99 | void Save(AggregateRoot aggregate, int expectedVersion); 100 | T GetById(Guid id); 101 | } 102 | 103 | public class Repository : IRepository where T: AggregateRoot, new() //shortcut you can do as you see fit with new() 104 | { 105 | private readonly IEventStore _storage; 106 | 107 | public Repository(IEventStore storage) 108 | { 109 | _storage = storage; 110 | } 111 | 112 | public void Save(AggregateRoot aggregate, int expectedVersion) 113 | { 114 | _storage.SaveEvents(aggregate.Id, aggregate.GetUncommittedChanges(), expectedVersion); 115 | } 116 | 117 | public T GetById(Guid id) 118 | { 119 | var obj = new T();//lots of ways to do this 120 | var e = _storage.GetEventsForAggregate(id); 121 | obj.LoadsFromHistory(e); 122 | return obj; 123 | } 124 | } 125 | 126 | } 127 | 128 | -------------------------------------------------------------------------------- /SimpleCQRS/SimpleCQRS.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | x86 6 | 9.0.21022 7 | 2.0 8 | {DAFD2A8A-D6B0-4433-8DDF-B98460C64EC6} 9 | Library 10 | SimpleCQRS 11 | SimpleCQRS 12 | v4.0 13 | 14 | 15 | 3.5 16 | 17 | publish\ 18 | true 19 | Disk 20 | false 21 | Foreground 22 | 7 23 | Days 24 | false 25 | false 26 | true 27 | 0 28 | 1.0.0.%2a 29 | false 30 | false 31 | true 32 | 33 | 34 | 35 | 36 | 37 | 38 | true 39 | bin\Debug\ 40 | DEBUG 41 | full 42 | AnyCPU 43 | prompt 44 | AllRules.ruleset 45 | false 46 | 47 | 48 | bin\Release\ 49 | AnyCPU 50 | prompt 51 | AllRules.ruleset 52 | false 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | False 73 | .NET Framework 3.5 SP1 Client Profile 74 | false 75 | 76 | 77 | False 78 | .NET Framework 3.5 SP1 79 | true 80 | 81 | 82 | False 83 | Windows Installer 3.1 84 | true 85 | 86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /SimpleCQRS/ReadModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace SimpleCQRS 5 | { 6 | public interface IReadModelFacade 7 | { 8 | IEnumerable GetInventoryItems(); 9 | InventoryItemDetailsDto GetInventoryItemDetails(Guid id); 10 | } 11 | 12 | public class InventoryItemDetailsDto 13 | { 14 | public Guid Id; 15 | public string Name; 16 | public int CurrentCount; 17 | public int Version; 18 | 19 | public InventoryItemDetailsDto(Guid id, string name, int currentCount, int version) 20 | { 21 | Id = id; 22 | Name = name; 23 | CurrentCount = currentCount; 24 | Version = version; 25 | } 26 | } 27 | 28 | public class InventoryItemListDto 29 | { 30 | public Guid Id; 31 | public string Name; 32 | 33 | public InventoryItemListDto(Guid id, string name) 34 | { 35 | Id = id; 36 | Name = name; 37 | } 38 | } 39 | 40 | public class InventoryListView : Handles, Handles, Handles 41 | { 42 | public void Handle(InventoryItemCreated message) 43 | { 44 | BullShitDatabase.list.Add(new InventoryItemListDto(message.Id, message.Name)); 45 | } 46 | 47 | public void Handle(InventoryItemRenamed message) 48 | { 49 | var item = BullShitDatabase.list.Find(x => x.Id == message.Id); 50 | item.Name = message.NewName; 51 | } 52 | 53 | public void Handle(InventoryItemDeactivated message) 54 | { 55 | BullShitDatabase.list.RemoveAll(x => x.Id == message.Id); 56 | } 57 | } 58 | 59 | public class InvenotryItemDetailView : Handles, Handles, Handles, Handles, Handles 60 | { 61 | public void Handle(InventoryItemCreated message) 62 | { 63 | BullShitDatabase.details.Add(message.Id, new InventoryItemDetailsDto(message.Id, message.Name, 0,0)); 64 | } 65 | 66 | public void Handle(InventoryItemRenamed message) 67 | { 68 | InventoryItemDetailsDto d = GetDetailsItem(message.Id); 69 | d.Name = message.NewName; 70 | d.Version = message.Version; 71 | } 72 | 73 | private InventoryItemDetailsDto GetDetailsItem(Guid id) 74 | { 75 | InventoryItemDetailsDto d; 76 | if(!BullShitDatabase.details.TryGetValue(id, out d)) 77 | { 78 | throw new InvalidOperationException("did not find the original inventory this shouldnt happen"); 79 | } 80 | return d; 81 | } 82 | 83 | public void Handle(ItemsRemovedFromInventory message) 84 | { 85 | InventoryItemDetailsDto d = GetDetailsItem(message.Id); 86 | d.CurrentCount -= message.Count; 87 | d.Version = message.Version; 88 | } 89 | 90 | public void Handle(ItemsCheckedInToInventory message) 91 | { 92 | InventoryItemDetailsDto d = GetDetailsItem(message.Id); 93 | d.CurrentCount += message.Count; 94 | d.Version = message.Version; 95 | } 96 | 97 | public void Handle(InventoryItemDeactivated message) 98 | { 99 | BullShitDatabase.details.Remove(message.Id); 100 | } 101 | } 102 | 103 | public class ReadModelFacade : IReadModelFacade 104 | { 105 | public IEnumerable GetInventoryItems() 106 | { 107 | return BullShitDatabase.list; 108 | } 109 | 110 | public InventoryItemDetailsDto GetInventoryItemDetails(Guid id) 111 | { 112 | return BullShitDatabase.details[id]; 113 | } 114 | } 115 | 116 | public static class BullShitDatabase 117 | { 118 | public static Dictionary details = new Dictionary(); 119 | public static List list = new List(); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /CQRSGui/Scripts/MicrosoftMvcAjax.js: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------- 2 | // Copyright (C) Microsoft Corporation. All rights reserved. 3 | //---------------------------------------------------------- 4 | // MicrosoftMvcAjax.js 5 | 6 | Type.registerNamespace('Sys.Mvc');Sys.Mvc.$create_AjaxOptions=function(){return {};} 7 | Sys.Mvc.InsertionMode=function(){};Sys.Mvc.InsertionMode.prototype = {replace:0,insertBefore:1,insertAfter:2} 8 | Sys.Mvc.InsertionMode.registerEnum('Sys.Mvc.InsertionMode',false);Sys.Mvc.AjaxContext=function(request,updateTarget,loadingElement,insertionMode){this.$3=request;this.$4=updateTarget;this.$1=loadingElement;this.$0=insertionMode;} 9 | Sys.Mvc.AjaxContext.prototype={$0:0,$1:null,$2:null,$3:null,$4:null,get_data:function(){if(this.$2){return this.$2.get_responseData();}else{return null;}},get_insertionMode:function(){return this.$0;},get_loadingElement:function(){return this.$1;},get_object:function(){var $0=this.get_response();return ($0)?$0.get_object():null;},get_response:function(){return this.$2;},set_response:function(value){this.$2=value;return value;},get_request:function(){return this.$3;},get_updateTarget:function(){return this.$4;}} 10 | Sys.Mvc.AsyncHyperlink=function(){} 11 | Sys.Mvc.AsyncHyperlink.handleClick=function(anchor,evt,ajaxOptions){evt.preventDefault();Sys.Mvc.MvcHelpers.$2(anchor.href,'post','',anchor,ajaxOptions);} 12 | Sys.Mvc.MvcHelpers=function(){} 13 | Sys.Mvc.MvcHelpers.$0=function($p0,$p1,$p2){if($p0.disabled){return null;}var $0=$p0.name;if($0){var $1=$p0.tagName.toUpperCase();var $2=encodeURIComponent($0);var $3=$p0;if($1==='INPUT'){var $4=$3.type;if($4==='submit'){return $2+'='+encodeURIComponent($3.value);}else if($4==='image'){return $2+'.x='+$p1+'&'+$2+'.y='+$p2;}}else if(($1==='BUTTON')&&($0.length)&&($3.type==='submit')){return $2+'='+encodeURIComponent($3.value);}}return null;} 14 | Sys.Mvc.MvcHelpers.$1=function($p0){var $0=$p0.elements;var $1=new Sys.StringBuilder();var $2=$0.length;for(var $4=0;$4<$2;$4++){var $5=$0[$4];var $6=$5.name;if(!$6||!$6.length){continue;}var $7=$5.tagName.toUpperCase();if($7==='INPUT'){var $8=$5;var $9=$8.type;if(($9==='text')||($9==='password')||($9==='hidden')||((($9==='checkbox')||($9==='radio'))&&$5.checked)){$1.append(encodeURIComponent($6));$1.append('=');$1.append(encodeURIComponent($8.value));$1.append('&');}}else if($7==='SELECT'){var $A=$5;var $B=$A.options.length;for(var $C=0;$C<$B;$C++){var $D=$A.options[$C];if($D.selected){$1.append(encodeURIComponent($6));$1.append('=');$1.append(encodeURIComponent($D.value));$1.append('&');}}}else if($7==='TEXTAREA'){$1.append(encodeURIComponent($6));$1.append('=');$1.append(encodeURIComponent(($5.value)));$1.append('&');}}var $3=$p0._additionalInput;if($3){$1.append($3);$1.append('&');}return $1.toString();} 15 | Sys.Mvc.MvcHelpers.$2=function($p0,$p1,$p2,$p3,$p4){if($p4.confirm){if(!confirm($p4.confirm)){return;}}if($p4.url){$p0=$p4.url;}if($p4.httpMethod){$p1=$p4.httpMethod;}if($p2.length>0&&!$p2.endsWith('&')){$p2+='&';}$p2+='X-Requested-With=XMLHttpRequest';var $0=$p1.toUpperCase();var $1=($0==='GET'||$0==='POST');if(!$1){$p2+='&';$p2+='X-HTTP-Method-Override='+$0;}var $2='';if($0==='GET'||$0==='DELETE'){if($p0.indexOf('?')>-1){if(!$p0.endsWith('&')){$p0+='&';}$p0+=$p2;}else{$p0+='?';$p0+=$p2;}}else{$2=$p2;}var $3=new Sys.Net.WebRequest();$3.set_url($p0);if($1){$3.set_httpVerb($p1);}else{$3.set_httpVerb('POST');$3.get_headers()['X-HTTP-Method-Override']=$0;}$3.set_body($2);if($p1.toUpperCase()==='PUT'){$3.get_headers()['Content-Type']='application/x-www-form-urlencoded;';}$3.get_headers()['X-Requested-With']='XMLHttpRequest';var $4=null;if($p4.updateTargetId){$4=$get($p4.updateTargetId);}var $5=null;if($p4.loadingElementId){$5=$get($p4.loadingElementId);}var $6=new Sys.Mvc.AjaxContext($3,$4,$5,$p4.insertionMode);var $7=true;if($p4.onBegin){$7=$p4.onBegin($6)!==false;}if($5){Sys.UI.DomElement.setVisible($6.get_loadingElement(),true);}if($7){$3.add_completed(Function.createDelegate(null,function($p1_0){ 16 | Sys.Mvc.MvcHelpers.$3($3,$p4,$6);}));$3.invoke();}} 17 | Sys.Mvc.MvcHelpers.$3=function($p0,$p1,$p2){$p2.set_response($p0.get_executor());if($p1.onComplete&&$p1.onComplete($p2)===false){return;}var $0=$p2.get_response().get_statusCode();if(($0>=200&&$0<300)||$0===304||$0===1223){if($0!==204&&$0!==304&&$0!==1223){var $1=$p2.get_response().getResponseHeader('Content-Type');if(($1)&&($1.indexOf('application/x-javascript')!==-1)){eval($p2.get_data());}else{Sys.Mvc.MvcHelpers.updateDomElement($p2.get_updateTarget(),$p2.get_insertionMode(),$p2.get_data());}}if($p1.onSuccess){$p1.onSuccess($p2);}}else{if($p1.onFailure){$p1.onFailure($p2);}}if($p2.get_loadingElement()){Sys.UI.DomElement.setVisible($p2.get_loadingElement(),false);}} 18 | Sys.Mvc.MvcHelpers.updateDomElement=function(target,insertionMode,content){if(target){switch(insertionMode){case 0:target.innerHTML=content;break;case 1:if(content&&content.length>0){target.innerHTML=content+target.innerHTML.trimStart();}break;case 2:if(content&&content.length>0){target.innerHTML=target.innerHTML.trimEnd()+content;}break;}}} 19 | Sys.Mvc.AsyncForm=function(){} 20 | Sys.Mvc.AsyncForm.handleClick=function(form,evt){var $0=Sys.Mvc.MvcHelpers.$0(evt.target,evt.offsetX,evt.offsetY);form._additionalInput = $0;} 21 | Sys.Mvc.AsyncForm.handleSubmit=function(form,evt,ajaxOptions){evt.preventDefault();var $0=form.validationCallbacks;if($0){for(var $2=0;$2<$0.length;$2++){var $3=$0[$2];if(!$3()){return;}}}var $1=Sys.Mvc.MvcHelpers.$1(form);Sys.Mvc.MvcHelpers.$2(form.action,form.method||'post',$1,form,ajaxOptions);} 22 | Sys.Mvc.AjaxContext.registerClass('Sys.Mvc.AjaxContext');Sys.Mvc.AsyncHyperlink.registerClass('Sys.Mvc.AsyncHyperlink');Sys.Mvc.MvcHelpers.registerClass('Sys.Mvc.MvcHelpers');Sys.Mvc.AsyncForm.registerClass('Sys.Mvc.AsyncForm'); 23 | // ---- Do not remove this footer ---- 24 | // Generated using Script# v0.5.0.0 (http://projects.nikhilk.net) 25 | // ----------------------------------- 26 | -------------------------------------------------------------------------------- /CQRSGui/Content/Site.css: -------------------------------------------------------------------------------- 1 | /*---------------------------------------------------------- 2 | The base color for this template is #5c87b2. If you'd like 3 | to use a different color start by replacing all instances of 4 | #5c87b2 with your new color. 5 | ----------------------------------------------------------*/ 6 | body 7 | { 8 | background-color: #5c87b2; 9 | font-size: .75em; 10 | font-family: Verdana, Helvetica, Sans-Serif; 11 | margin: 0; 12 | padding: 0; 13 | color: #696969; 14 | } 15 | 16 | a:link 17 | { 18 | color: #034af3; 19 | text-decoration: underline; 20 | } 21 | a:visited 22 | { 23 | color: #505abc; 24 | } 25 | a:hover 26 | { 27 | color: #1d60ff; 28 | text-decoration: none; 29 | } 30 | a:active 31 | { 32 | color: #12eb87; 33 | } 34 | 35 | p, ul 36 | { 37 | margin-bottom: 20px; 38 | line-height: 1.6em; 39 | } 40 | 41 | /* HEADINGS 42 | ----------------------------------------------------------*/ 43 | h1, h2, h3, h4, h5, h6 44 | { 45 | font-size: 1.5em; 46 | color: #000; 47 | font-family: Arial, Helvetica, sans-serif; 48 | } 49 | 50 | h1 51 | { 52 | font-size: 2em; 53 | padding-bottom: 0; 54 | margin-bottom: 0; 55 | } 56 | h2 57 | { 58 | padding: 0 0 10px 0; 59 | } 60 | h3 61 | { 62 | font-size: 1.2em; 63 | } 64 | h4 65 | { 66 | font-size: 1.1em; 67 | } 68 | h5, h6 69 | { 70 | font-size: 1em; 71 | } 72 | 73 | /* this rule styles

tags that are the 74 | first child of the left and right table columns */ 75 | .rightColumn > h1, .rightColumn > h2, .leftColumn > h1, .leftColumn > h2 76 | { 77 | margin-top: 0; 78 | } 79 | 80 | /* PRIMARY LAYOUT ELEMENTS 81 | ----------------------------------------------------------*/ 82 | 83 | /* you can specify a greater or lesser percentage for the 84 | page width. Or, you can specify an exact pixel width. */ 85 | .page 86 | { 87 | width: 90%; 88 | margin-left: auto; 89 | margin-right: auto; 90 | } 91 | 92 | #header 93 | { 94 | position: relative; 95 | margin-bottom: 0px; 96 | color: #000; 97 | padding: 0; 98 | } 99 | 100 | #header h1 101 | { 102 | font-weight: bold; 103 | padding: 5px 0; 104 | margin: 0; 105 | color: #fff; 106 | border: none; 107 | line-height: 2em; 108 | font-family: Arial, Helvetica, sans-serif; 109 | font-size: 32px !important; 110 | } 111 | 112 | #main 113 | { 114 | padding: 30px 30px 15px 30px; 115 | background-color: #fff; 116 | margin-bottom: 30px; 117 | _height: 1px; /* only IE6 applies CSS properties starting with an underscore */ 118 | } 119 | 120 | #footer 121 | { 122 | color: #999; 123 | padding: 10px 0; 124 | text-align: center; 125 | line-height: normal; 126 | margin: 0; 127 | font-size: .9em; 128 | } 129 | 130 | /* TAB MENU 131 | ----------------------------------------------------------*/ 132 | ul#menu 133 | { 134 | border-bottom: 1px #5C87B2 solid; 135 | padding: 0 0 2px; 136 | position: relative; 137 | margin: 0; 138 | text-align: right; 139 | } 140 | 141 | ul#menu li 142 | { 143 | display: inline; 144 | list-style: none; 145 | } 146 | 147 | ul#menu li#greeting 148 | { 149 | padding: 10px 20px; 150 | font-weight: bold; 151 | text-decoration: none; 152 | line-height: 2.8em; 153 | color: #fff; 154 | } 155 | 156 | ul#menu li a 157 | { 158 | padding: 10px 20px; 159 | font-weight: bold; 160 | text-decoration: none; 161 | line-height: 2.8em; 162 | background-color: #e8eef4; 163 | color: #034af3; 164 | } 165 | 166 | ul#menu li a:hover 167 | { 168 | background-color: #fff; 169 | text-decoration: none; 170 | } 171 | 172 | ul#menu li a:active 173 | { 174 | background-color: #a6e2a6; 175 | text-decoration: none; 176 | } 177 | 178 | ul#menu li.selected a 179 | { 180 | background-color: #fff; 181 | color: #000; 182 | } 183 | 184 | /* FORM LAYOUT ELEMENTS 185 | ----------------------------------------------------------*/ 186 | 187 | fieldset 188 | { 189 | margin: 1em 0; 190 | padding: 1em; 191 | border: 1px solid #CCC; 192 | } 193 | 194 | fieldset p 195 | { 196 | margin: 2px 12px 10px 10px; 197 | } 198 | 199 | legend 200 | { 201 | font-size: 1.1em; 202 | font-weight: 600; 203 | padding: 2px 4px 8px 4px; 204 | } 205 | 206 | input[type="text"] 207 | { 208 | width: 200px; 209 | border: 1px solid #CCC; 210 | } 211 | 212 | input[type="password"] 213 | { 214 | width: 200px; 215 | border: 1px solid #CCC; 216 | } 217 | 218 | /* TABLE 219 | ----------------------------------------------------------*/ 220 | 221 | table 222 | { 223 | border: solid 1px #e8eef4; 224 | border-collapse: collapse; 225 | } 226 | 227 | table td 228 | { 229 | padding: 5px; 230 | border: solid 1px #e8eef4; 231 | } 232 | 233 | table th 234 | { 235 | padding: 6px 5px; 236 | text-align: left; 237 | background-color: #e8eef4; 238 | border: solid 1px #e8eef4; 239 | } 240 | 241 | /* MISC 242 | ----------------------------------------------------------*/ 243 | .clear 244 | { 245 | clear: both; 246 | } 247 | 248 | .error 249 | { 250 | color:Red; 251 | } 252 | 253 | #menucontainer 254 | { 255 | margin-top:40px; 256 | } 257 | 258 | div#title 259 | { 260 | margin-top: -40px; 261 | display:block; 262 | float:left; 263 | text-align:left; 264 | } 265 | 266 | #logindisplay 267 | { 268 | font-size:1.1em; 269 | display:block; 270 | text-align:right; 271 | margin:10px; 272 | color:White; 273 | } 274 | 275 | #logindisplay a:link 276 | { 277 | color: white; 278 | text-decoration: underline; 279 | } 280 | 281 | #logindisplay a:visited 282 | { 283 | color: white; 284 | text-decoration: underline; 285 | } 286 | 287 | #logindisplay a:hover 288 | { 289 | color: white; 290 | text-decoration: none; 291 | } 292 | 293 | /* Styles for validation helpers 294 | -----------------------------------------------------------*/ 295 | .field-validation-error 296 | { 297 | color: #ff0000; 298 | } 299 | 300 | .field-validation-valid 301 | { 302 | display: none; 303 | } 304 | 305 | .input-validation-error 306 | { 307 | border: 1px solid #ff0000; 308 | background-color: #ffeeee; 309 | } 310 | 311 | .validation-summary-errors 312 | { 313 | font-weight: bold; 314 | color: #ff0000; 315 | } 316 | 317 | .validation-summary-valid 318 | { 319 | display: none; 320 | } 321 | 322 | /* Styles for editor and display helpers 323 | ----------------------------------------------------------*/ 324 | .display-label, 325 | .editor-label, 326 | .display-field, 327 | .editor-field 328 | { 329 | margin: 0.5em 0; 330 | } 331 | 332 | .text-box 333 | { 334 | width: 30em; 335 | } 336 | 337 | .text-box.multi-line 338 | { 339 | height: 6.5em; 340 | } 341 | 342 | .tri-state 343 | { 344 | width: 6em; 345 | } 346 | -------------------------------------------------------------------------------- /CQRSGui/CQRSGui.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | 8 | 9 | 2.0 10 | {29ECBF37-9526-4CB6-8429-D09CF0301C26} 11 | {E53F8FEA-EAE0-44A6-8774-FFD645390401};{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} 12 | Library 13 | Properties 14 | CQRSGui 15 | CQRSGui 16 | v4.0 17 | false 18 | false 19 | ..\..\Siriona.SalesRepresentative.Extranet\ 20 | true 21 | 22 | 23 | 24 | 25 | 4.0 26 | 27 | 28 | 29 | 30 | 31 | 32 | true 33 | full 34 | false 35 | bin\ 36 | DEBUG;TRACE 37 | prompt 38 | 4 39 | 40 | 41 | pdbonly 42 | true 43 | bin\ 44 | TRACE 45 | prompt 46 | 4 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 3.5 58 | 59 | 60 | 3.5 61 | 62 | 63 | 3.5 64 | 65 | 66 | 67 | 3.5 68 | 69 | 70 | 71 | 3.5 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | Global.asax 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | Designer 100 | 101 | 102 | Web.config 103 | 104 | 105 | Web.config 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | {e1188906-3b37-4d26-a4dc-e5daec747d5f} 132 | FsSimpleCQRS 133 | 134 | 135 | 136 | 137 | 138 | 139 | 10.0 140 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 141 | 142 | 143 | 144 | 145 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | False 157 | True 158 | 52410 159 | / 160 | 161 | 162 | False 163 | False 164 | 165 | 166 | False 167 | 168 | 169 | 170 | 171 | -------------------------------------------------------------------------------- /SimpleCQRS/InfrastructureCrap.DontBotherReadingItsNotImportant.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Concurrent; 3 | using System.Collections.Generic; 4 | using System.Dynamic; 5 | using System.Linq; 6 | using System.Linq.Expressions; 7 | using System.Reflection; 8 | using System.Text; 9 | 10 | namespace SimpleCQRS 11 | { 12 | 13 | //FROM http://blogs.msdn.com/b/davidebb/archive/2010/01/18/use-c-4-0-dynamic-to-drastically-simplify-your-private-reflection-code.aspx 14 | //doesnt count to line counts :) 15 | class PrivateReflectionDynamicObject : DynamicObject 16 | { 17 | 18 | private static IDictionary> _propertiesOnType = new ConcurrentDictionary>(); 19 | 20 | // Simple abstraction to make field and property access consistent 21 | interface IProperty 22 | { 23 | string Name { get; } 24 | object GetValue(object obj, object[] index); 25 | void SetValue(object obj, object val, object[] index); 26 | } 27 | 28 | // IProperty implementation over a PropertyInfo 29 | class Property : IProperty 30 | { 31 | internal PropertyInfo PropertyInfo { get; set; } 32 | 33 | string IProperty.Name 34 | { 35 | get 36 | { 37 | return PropertyInfo.Name; 38 | } 39 | } 40 | 41 | object IProperty.GetValue(object obj, object[] index) 42 | { 43 | return PropertyInfo.GetValue(obj, index); 44 | } 45 | 46 | void IProperty.SetValue(object obj, object val, object[] index) 47 | { 48 | PropertyInfo.SetValue(obj, val, index); 49 | } 50 | } 51 | 52 | // IProperty implementation over a FieldInfo 53 | class Field : IProperty 54 | { 55 | internal FieldInfo FieldInfo { get; set; } 56 | 57 | string IProperty.Name 58 | { 59 | get 60 | { 61 | return FieldInfo.Name; 62 | } 63 | } 64 | 65 | 66 | object IProperty.GetValue(object obj, object[] index) 67 | { 68 | return FieldInfo.GetValue(obj); 69 | } 70 | 71 | void IProperty.SetValue(object obj, object val, object[] index) 72 | { 73 | FieldInfo.SetValue(obj, val); 74 | } 75 | } 76 | 77 | 78 | private object RealObject { get; set; } 79 | private const BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic; 80 | 81 | internal static object WrapObjectIfNeeded(object o) 82 | { 83 | // Don't wrap primitive types, which don't have many interesting internal APIs 84 | if (o == null || o.GetType().IsPrimitive || o is string) 85 | return o; 86 | 87 | return new PrivateReflectionDynamicObject() { RealObject = o }; 88 | } 89 | 90 | public override bool TryGetMember(GetMemberBinder binder, out object result) 91 | { 92 | IProperty prop = GetProperty(binder.Name); 93 | 94 | // Get the property value 95 | result = prop.GetValue(RealObject, index: null); 96 | 97 | // Wrap the sub object if necessary. This allows nested anonymous objects to work. 98 | result = WrapObjectIfNeeded(result); 99 | 100 | return true; 101 | } 102 | 103 | public override bool TrySetMember(SetMemberBinder binder, object value) 104 | { 105 | IProperty prop = GetProperty(binder.Name); 106 | 107 | // Set the property value 108 | prop.SetValue(RealObject, value, index: null); 109 | 110 | return true; 111 | } 112 | 113 | public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result) 114 | { 115 | // The indexed property is always named "Item" in C# 116 | IProperty prop = GetIndexProperty(); 117 | result = prop.GetValue(RealObject, indexes); 118 | 119 | // Wrap the sub object if necessary. This allows nested anonymous objects to work. 120 | result = WrapObjectIfNeeded(result); 121 | 122 | return true; 123 | } 124 | 125 | public override bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value) 126 | { 127 | // The indexed property is always named "Item" in C# 128 | IProperty prop = GetIndexProperty(); 129 | prop.SetValue(RealObject, value, indexes); 130 | return true; 131 | } 132 | 133 | // Called when a method is called 134 | public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) 135 | { 136 | result = InvokeMemberOnType(RealObject.GetType(), RealObject, binder.Name, args); 137 | 138 | // Wrap the sub object if necessary. This allows nested anonymous objects to work. 139 | result = WrapObjectIfNeeded(result); 140 | 141 | return true; 142 | } 143 | 144 | public override bool TryConvert(ConvertBinder binder, out object result) 145 | { 146 | result = Convert.ChangeType(RealObject, binder.Type); 147 | return true; 148 | } 149 | 150 | public override string ToString() 151 | { 152 | return RealObject.ToString(); 153 | } 154 | 155 | private IProperty GetIndexProperty() 156 | { 157 | // The index property is always named "Item" in C# 158 | return GetProperty("Item"); 159 | } 160 | 161 | private IProperty GetProperty(string propertyName) 162 | { 163 | 164 | // Get the list of properties and fields for this type 165 | IDictionary typeProperties = GetTypeProperties(RealObject.GetType()); 166 | 167 | // Look for the one we want 168 | IProperty property; 169 | if (typeProperties.TryGetValue(propertyName, out property)) 170 | { 171 | return property; 172 | } 173 | 174 | // The property doesn't exist 175 | 176 | // Get a list of supported properties and fields and show them as part of the exception message 177 | // For fields, skip the auto property backing fields (which name start with <) 178 | var propNames = typeProperties.Keys.Where(name => name[0] != '<').OrderBy(name => name); 179 | throw new ArgumentException( 180 | String.Format( 181 | "The property {0} doesn't exist on type {1}. Supported properties are: {2}", 182 | propertyName, RealObject.GetType(), String.Join(", ", propNames))); 183 | } 184 | 185 | private static IDictionary GetTypeProperties(Type type) 186 | { 187 | // First, check if we already have it cached 188 | IDictionary typeProperties; 189 | if (_propertiesOnType.TryGetValue(type, out typeProperties)) 190 | { 191 | return typeProperties; 192 | } 193 | 194 | // Not cache, so we need to build it 195 | 196 | typeProperties = new ConcurrentDictionary(); 197 | 198 | // First, add all the properties 199 | foreach (PropertyInfo prop in type.GetProperties(bindingFlags).Where(p => p.DeclaringType == type)) 200 | { 201 | typeProperties[prop.Name] = new Property() { PropertyInfo = prop }; 202 | } 203 | 204 | // Now, add all the fields 205 | foreach (FieldInfo field in type.GetFields(bindingFlags).Where(p => p.DeclaringType == type)) 206 | { 207 | typeProperties[field.Name] = new Field() { FieldInfo = field }; 208 | } 209 | 210 | // Finally, recurse on the base class to add its fields 211 | if (type.BaseType != null) 212 | { 213 | foreach (IProperty prop in GetTypeProperties(type.BaseType).Values) 214 | { 215 | typeProperties[prop.Name] = prop; 216 | } 217 | } 218 | 219 | // Cache it for next time 220 | _propertiesOnType[type] = typeProperties; 221 | 222 | return typeProperties; 223 | } 224 | 225 | private static object InvokeMemberOnType(Type type, object target, string name, object[] args) 226 | { 227 | try 228 | { 229 | // Try to incoke the method 230 | return type.InvokeMember( 231 | name, 232 | BindingFlags.InvokeMethod | bindingFlags, 233 | null, 234 | target, 235 | args); 236 | } 237 | catch (MissingMethodException) 238 | { 239 | // If we couldn't find the method, try on the base class 240 | if (type.BaseType != null) 241 | { 242 | return InvokeMemberOnType(type.BaseType, target, name, args); 243 | } 244 | //quick greg hack to allow methods to not exist! 245 | return null; 246 | } 247 | } 248 | } 249 | 250 | 251 | public static class PrivateReflectionDynamicObjectExtensions 252 | { 253 | public static dynamic AsDynamic(this object o) 254 | { 255 | return PrivateReflectionDynamicObject.WrapObjectIfNeeded(o); 256 | } 257 | } 258 | 259 | public class DelegateAdjuster 260 | { 261 | public static Action CastArgument(Expression> source) where DerivedT : BaseT 262 | { 263 | if (typeof(DerivedT) == typeof(BaseT)) 264 | { 265 | return (Action)((Delegate)source.Compile()); 266 | 267 | } 268 | ParameterExpression sourceParameter = Expression.Parameter(typeof(BaseT), "source"); 269 | var result = Expression.Lambda>( 270 | Expression.Invoke( 271 | source, 272 | Expression.Convert(sourceParameter, typeof(DerivedT))), 273 | sourceParameter); 274 | return result.Compile(); 275 | } 276 | } 277 | } 278 | 279 | -------------------------------------------------------------------------------- /CQRSGui/Scripts/MicrosoftMvcValidation.js: -------------------------------------------------------------------------------- 1 | //---------------------------------------------------------- 2 | // Copyright (C) Microsoft Corporation. All rights reserved. 3 | //---------------------------------------------------------- 4 | // MicrosoftMvcValidation.js 5 | 6 | Type.registerNamespace('Sys.Mvc');Sys.Mvc.$create_Validation=function(){return {};} 7 | Sys.Mvc.$create_JsonValidationField=function(){return {};} 8 | Sys.Mvc.$create_JsonValidationOptions=function(){return {};} 9 | Sys.Mvc.$create_JsonValidationRule=function(){return {};} 10 | Sys.Mvc.$create_ValidationContext=function(){return {};} 11 | Sys.Mvc.NumberValidator=function(){} 12 | Sys.Mvc.NumberValidator.create=function(rule){return Function.createDelegate(new Sys.Mvc.NumberValidator(),new Sys.Mvc.NumberValidator().validate);} 13 | Sys.Mvc.NumberValidator.prototype={validate:function(value,context){if(Sys.Mvc._ValidationUtil.$1(value)){return true;}var $0=Number.parseLocale(value);return (!isNaN($0));}} 14 | Sys.Mvc.FormContext=function(formElement,validationSummaryElement){this.$5=[];this.fields=new Array(0);this.$9=formElement;this.$7=validationSummaryElement;formElement['__MVC_FormValidation'] = this;if(validationSummaryElement){var $0=validationSummaryElement.getElementsByTagName('ul');if($0.length>0){this.$8=$0[0];}}this.$3=Function.createDelegate(this,this.$D);this.$4=Function.createDelegate(this,this.$E);} 15 | Sys.Mvc.FormContext._Application_Load=function(){var $0=window.mvcClientValidationMetadata;if($0){while($0.length>0){var $1=$0.pop();Sys.Mvc.FormContext.$12($1);}}} 16 | Sys.Mvc.FormContext.$F=function($p0,$p1){var $0=[];var $1=document.getElementsByName($p1);for(var $2=0;$2<$1.length;$2++){var $3=$1[$2];if(Sys.Mvc.FormContext.$10($p0,$3)){Array.add($0,$3);}}return $0;} 17 | Sys.Mvc.FormContext.getValidationForForm=function(formElement){return formElement['__MVC_FormValidation'];} 18 | Sys.Mvc.FormContext.$10=function($p0,$p1){while($p1){if($p0===$p1){return true;}$p1=$p1.parentNode;}return false;} 19 | Sys.Mvc.FormContext.$12=function($p0){var $0=$get($p0.FormId);var $1=(!Sys.Mvc._ValidationUtil.$1($p0.ValidationSummaryId))?$get($p0.ValidationSummaryId):null;var $2=new Sys.Mvc.FormContext($0,$1);$2.enableDynamicValidation();$2.replaceValidationSummary=$p0.ReplaceValidationSummary;for(var $4=0;$4<$p0.Fields.length;$4++){var $5=$p0.Fields[$4];var $6=Sys.Mvc.FormContext.$F($0,$5.FieldName);var $7=(!Sys.Mvc._ValidationUtil.$1($5.ValidationMessageId))?$get($5.ValidationMessageId):null;var $8=new Sys.Mvc.FieldContext($2);Array.addRange($8.elements,$6);$8.validationMessageElement=$7;$8.replaceValidationMessageContents=$5.ReplaceValidationMessageContents;for(var $9=0;$9<$5.ValidationRules.length;$9++){var $A=$5.ValidationRules[$9];var $B=Sys.Mvc.ValidatorRegistry.getValidator($A);if($B){var $C=Sys.Mvc.$create_Validation();$C.fieldErrorMessage=$A.ErrorMessage;$C.validator=$B;Array.add($8.validations,$C);}}$8.enableDynamicValidation();Array.add($2.fields,$8);}var $3=$0.validationCallbacks;if(!$3){$3=[];$0.validationCallbacks = $3;}$3.push(Function.createDelegate(null,function(){ 20 | return Sys.Mvc._ValidationUtil.$0($2.validate('submit'));}));return $2;} 21 | Sys.Mvc.FormContext.prototype={$3:null,$4:null,$6:null,$7:null,$8:null,$9:null,replaceValidationSummary:false,addError:function(message){this.addErrors([message]);},addErrors:function(messages){if(!Sys.Mvc._ValidationUtil.$0(messages)){Array.addRange(this.$5,messages);this.$11();}},clearErrors:function(){Array.clear(this.$5);this.$11();},$A:function(){if(this.$7){if(this.$8){Sys.Mvc._ValidationUtil.$3(this.$8);for(var $0=0;$0=8){Sys.UI.DomEvent.addHandler($2,'propertychange',this.$9);}}else{Sys.UI.DomEvent.addHandler($2,'input',this.$8);}Sys.UI.DomEvent.addHandler($2,'change',this.$7);Sys.UI.DomEvent.addHandler($2,'blur',this.$6);}},$11:function($p0,$p1){var $0=$p1||this.defaultErrorMessage;if(Boolean.isInstanceOfType($p0)){return ($p0)?null:$0;}if(String.isInstanceOfType($p0)){return (($p0).length)?$p0:$0;}return null;},$12:function(){var $0=this.elements;return ($0.length>0)?$0[0].value:null;},$13:function(){var $0=this.elements;for(var $1=0;$1<$0.length;$1++){var $2=$0[$1];$2['__MVC_HasValidationFired'] = true;}},$14:function(){if(!this.$A.length){this.$C();}else{this.$B();}},validate:function(eventName){var $0=this.validations;var $1=[];var $2=this.$12();for(var $3=0;$3<$0.length;$3++){var $4=$0[$3];var $5=Sys.Mvc.$create_ValidationContext();$5.eventName=eventName;$5.fieldContext=this;$5.validation=$4;var $6=$4.validator($2,$5);var $7=this.$11($6,$4.fieldErrorMessage);if(!Sys.Mvc._ValidationUtil.$1($7)){Array.add($1,$7);}}this.$13();this.clearErrors();this.addErrors($1);return $1;}} 24 | Sys.Mvc.RangeValidator=function(minimum,maximum){this.$0=minimum;this.$1=maximum;} 25 | Sys.Mvc.RangeValidator.create=function(rule){var $0=rule.ValidationParameters['minimum'];var $1=rule.ValidationParameters['maximum'];return Function.createDelegate(new Sys.Mvc.RangeValidator($0,$1),new Sys.Mvc.RangeValidator($0,$1).validate);} 26 | Sys.Mvc.RangeValidator.prototype={$0:null,$1:null,validate:function(value,context){if(Sys.Mvc._ValidationUtil.$1(value)){return true;}var $0=Number.parseLocale(value);return (!isNaN($0)&&this.$0<=$0&&$0<=this.$1);}} 27 | Sys.Mvc.RegularExpressionValidator=function(pattern){this.$0=pattern;} 28 | Sys.Mvc.RegularExpressionValidator.create=function(rule){var $0=rule.ValidationParameters['pattern'];return Function.createDelegate(new Sys.Mvc.RegularExpressionValidator($0),new Sys.Mvc.RegularExpressionValidator($0).validate);} 29 | Sys.Mvc.RegularExpressionValidator.prototype={$0:null,validate:function(value,context){if(Sys.Mvc._ValidationUtil.$1(value)){return true;}var $0=new RegExp(this.$0);var $1=$0.exec(value);return (!Sys.Mvc._ValidationUtil.$0($1)&&$1[0].length===value.length);}} 30 | Sys.Mvc.RequiredValidator=function(){} 31 | Sys.Mvc.RequiredValidator.create=function(rule){return Function.createDelegate(new Sys.Mvc.RequiredValidator(),new Sys.Mvc.RequiredValidator().validate);} 32 | Sys.Mvc.RequiredValidator.$0=function($p0){if($p0.tagName.toUpperCase()==='INPUT'){var $0=($p0.type).toUpperCase();if($0==='RADIO'){return true;}}return false;} 33 | Sys.Mvc.RequiredValidator.$1=function($p0){if($p0.tagName.toUpperCase()==='SELECT'){return true;}return false;} 34 | Sys.Mvc.RequiredValidator.$2=function($p0){if($p0.tagName.toUpperCase()==='INPUT'){var $0=($p0.type).toUpperCase();switch($0){case 'TEXT':case 'PASSWORD':case 'FILE':return true;}}if($p0.tagName.toUpperCase()==='TEXTAREA'){return true;}return false;} 35 | Sys.Mvc.RequiredValidator.$3=function($p0){for(var $0=0;$0<$p0.length;$0++){var $1=$p0[$0];if($1.checked){return true;}}return false;} 36 | Sys.Mvc.RequiredValidator.$4=function($p0){for(var $0=0;$0<$p0.length;$0++){var $1=$p0[$0];if($1.selected){if(!Sys.Mvc._ValidationUtil.$1($1.value)){return true;}}}return false;} 37 | Sys.Mvc.RequiredValidator.$5=function($p0){return (!Sys.Mvc._ValidationUtil.$1($p0.value));} 38 | Sys.Mvc.RequiredValidator.prototype={validate:function(value,context){var $0=context.fieldContext.elements;if(!$0.length){return true;}var $1=$0[0];if(Sys.Mvc.RequiredValidator.$2($1)){return Sys.Mvc.RequiredValidator.$5($1);}if(Sys.Mvc.RequiredValidator.$0($1)){return Sys.Mvc.RequiredValidator.$3($0);}if(Sys.Mvc.RequiredValidator.$1($1)){return Sys.Mvc.RequiredValidator.$4(($1).options);}return true;}} 39 | Sys.Mvc.StringLengthValidator=function(minLength,maxLength){this.$1=minLength;this.$0=maxLength;} 40 | Sys.Mvc.StringLengthValidator.create=function(rule){var $0=rule.ValidationParameters['minimumLength'];var $1=rule.ValidationParameters['maximumLength'];return Function.createDelegate(new Sys.Mvc.StringLengthValidator($0,$1),new Sys.Mvc.StringLengthValidator($0,$1).validate);} 41 | Sys.Mvc.StringLengthValidator.prototype={$0:0,$1:0,validate:function(value,context){if(Sys.Mvc._ValidationUtil.$1(value)){return true;}return (this.$1<=value.length&&value.length<=this.$0);}} 42 | Sys.Mvc._ValidationUtil=function(){} 43 | Sys.Mvc._ValidationUtil.$0=function($p0){return (!$p0||!$p0.length);} 44 | Sys.Mvc._ValidationUtil.$1=function($p0){return (!$p0||!$p0.length);} 45 | Sys.Mvc._ValidationUtil.$2=function($p0,$p1){return ($p1 in $p0);} 46 | Sys.Mvc._ValidationUtil.$3=function($p0){while($p0.firstChild){$p0.removeChild($p0.firstChild);}} 47 | Sys.Mvc._ValidationUtil.$4=function($p0,$p1){var $0=document.createTextNode($p1);Sys.Mvc._ValidationUtil.$3($p0);$p0.appendChild($0);} 48 | Sys.Mvc.ValidatorRegistry=function(){} 49 | Sys.Mvc.ValidatorRegistry.getValidator=function(rule){var $0=Sys.Mvc.ValidatorRegistry.validators[rule.ValidationType];return ($0)?$0(rule):null;} 50 | Sys.Mvc.ValidatorRegistry.$0=function(){return {required:Function.createDelegate(null,Sys.Mvc.RequiredValidator.create),stringLength:Function.createDelegate(null,Sys.Mvc.StringLengthValidator.create),regularExpression:Function.createDelegate(null,Sys.Mvc.RegularExpressionValidator.create),range:Function.createDelegate(null,Sys.Mvc.RangeValidator.create),number:Function.createDelegate(null,Sys.Mvc.NumberValidator.create)};} 51 | Sys.Mvc.NumberValidator.registerClass('Sys.Mvc.NumberValidator');Sys.Mvc.FormContext.registerClass('Sys.Mvc.FormContext');Sys.Mvc.FieldContext.registerClass('Sys.Mvc.FieldContext');Sys.Mvc.RangeValidator.registerClass('Sys.Mvc.RangeValidator');Sys.Mvc.RegularExpressionValidator.registerClass('Sys.Mvc.RegularExpressionValidator');Sys.Mvc.RequiredValidator.registerClass('Sys.Mvc.RequiredValidator');Sys.Mvc.StringLengthValidator.registerClass('Sys.Mvc.StringLengthValidator');Sys.Mvc._ValidationUtil.registerClass('Sys.Mvc._ValidationUtil');Sys.Mvc.ValidatorRegistry.registerClass('Sys.Mvc.ValidatorRegistry');Sys.Mvc.ValidatorRegistry.validators=Sys.Mvc.ValidatorRegistry.$0(); 52 | // ---- Do not remove this footer ---- 53 | // Generated using Script# v0.5.0.0 (http://projects.nikhilk.net) 54 | // ----------------------------------- 55 | Sys.Application.add_load(function(){Sys.Application.remove_load(arguments.callee);Sys.Mvc.FormContext._Application_Load();}); -------------------------------------------------------------------------------- /CQRSGui/Scripts/MicrosoftMvcAjax.debug.js: -------------------------------------------------------------------------------- 1 | //!---------------------------------------------------------- 2 | //! Copyright (C) Microsoft Corporation. All rights reserved. 3 | //!---------------------------------------------------------- 4 | //! MicrosoftMvcAjax.js 5 | 6 | Type.registerNamespace('Sys.Mvc'); 7 | 8 | //////////////////////////////////////////////////////////////////////////////// 9 | // Sys.Mvc.AjaxOptions 10 | 11 | Sys.Mvc.$create_AjaxOptions = function Sys_Mvc_AjaxOptions() { return {}; } 12 | 13 | 14 | //////////////////////////////////////////////////////////////////////////////// 15 | // Sys.Mvc.InsertionMode 16 | 17 | Sys.Mvc.InsertionMode = function() { 18 | /// 19 | /// 20 | /// 21 | /// 22 | /// 23 | /// 24 | }; 25 | Sys.Mvc.InsertionMode.prototype = { 26 | replace: 0, 27 | insertBefore: 1, 28 | insertAfter: 2 29 | } 30 | Sys.Mvc.InsertionMode.registerEnum('Sys.Mvc.InsertionMode', false); 31 | 32 | 33 | //////////////////////////////////////////////////////////////////////////////// 34 | // Sys.Mvc.AjaxContext 35 | 36 | Sys.Mvc.AjaxContext = function Sys_Mvc_AjaxContext(request, updateTarget, loadingElement, insertionMode) { 37 | /// 38 | /// 39 | /// 40 | /// 41 | /// 42 | /// 43 | /// 44 | /// 45 | /// 46 | /// 47 | /// 48 | /// 49 | /// 50 | /// 51 | /// 52 | /// 53 | /// 54 | /// 55 | this._request = request; 56 | this._updateTarget = updateTarget; 57 | this._loadingElement = loadingElement; 58 | this._insertionMode = insertionMode; 59 | } 60 | Sys.Mvc.AjaxContext.prototype = { 61 | _insertionMode: 0, 62 | _loadingElement: null, 63 | _response: null, 64 | _request: null, 65 | _updateTarget: null, 66 | 67 | get_data: function Sys_Mvc_AjaxContext$get_data() { 68 | /// 69 | if (this._response) { 70 | return this._response.get_responseData(); 71 | } 72 | else { 73 | return null; 74 | } 75 | }, 76 | 77 | get_insertionMode: function Sys_Mvc_AjaxContext$get_insertionMode() { 78 | /// 79 | return this._insertionMode; 80 | }, 81 | 82 | get_loadingElement: function Sys_Mvc_AjaxContext$get_loadingElement() { 83 | /// 84 | return this._loadingElement; 85 | }, 86 | 87 | get_object: function Sys_Mvc_AjaxContext$get_object() { 88 | /// 89 | var executor = this.get_response(); 90 | return (executor) ? executor.get_object() : null; 91 | }, 92 | 93 | get_response: function Sys_Mvc_AjaxContext$get_response() { 94 | /// 95 | return this._response; 96 | }, 97 | set_response: function Sys_Mvc_AjaxContext$set_response(value) { 98 | /// 99 | this._response = value; 100 | return value; 101 | }, 102 | 103 | get_request: function Sys_Mvc_AjaxContext$get_request() { 104 | /// 105 | return this._request; 106 | }, 107 | 108 | get_updateTarget: function Sys_Mvc_AjaxContext$get_updateTarget() { 109 | /// 110 | return this._updateTarget; 111 | } 112 | } 113 | 114 | 115 | //////////////////////////////////////////////////////////////////////////////// 116 | // Sys.Mvc.AsyncHyperlink 117 | 118 | Sys.Mvc.AsyncHyperlink = function Sys_Mvc_AsyncHyperlink() { 119 | } 120 | Sys.Mvc.AsyncHyperlink.handleClick = function Sys_Mvc_AsyncHyperlink$handleClick(anchor, evt, ajaxOptions) { 121 | /// 122 | /// 123 | /// 124 | /// 125 | /// 126 | /// 127 | evt.preventDefault(); 128 | Sys.Mvc.MvcHelpers._asyncRequest(anchor.href, 'post', '', anchor, ajaxOptions); 129 | } 130 | 131 | 132 | //////////////////////////////////////////////////////////////////////////////// 133 | // Sys.Mvc.MvcHelpers 134 | 135 | Sys.Mvc.MvcHelpers = function Sys_Mvc_MvcHelpers() { 136 | } 137 | Sys.Mvc.MvcHelpers._serializeSubmitButton = function Sys_Mvc_MvcHelpers$_serializeSubmitButton(element, offsetX, offsetY) { 138 | /// 139 | /// 140 | /// 141 | /// 142 | /// 143 | /// 144 | /// 145 | if (element.disabled) { 146 | return null; 147 | } 148 | var name = element.name; 149 | if (name) { 150 | var tagName = element.tagName.toUpperCase(); 151 | var encodedName = encodeURIComponent(name); 152 | var inputElement = element; 153 | if (tagName === 'INPUT') { 154 | var type = inputElement.type; 155 | if (type === 'submit') { 156 | return encodedName + '=' + encodeURIComponent(inputElement.value); 157 | } 158 | else if (type === 'image') { 159 | return encodedName + '.x=' + offsetX + '&' + encodedName + '.y=' + offsetY; 160 | } 161 | } 162 | else if ((tagName === 'BUTTON') && (name.length) && (inputElement.type === 'submit')) { 163 | return encodedName + '=' + encodeURIComponent(inputElement.value); 164 | } 165 | } 166 | return null; 167 | } 168 | Sys.Mvc.MvcHelpers._serializeForm = function Sys_Mvc_MvcHelpers$_serializeForm(form) { 169 | /// 170 | /// 171 | /// 172 | var formElements = form.elements; 173 | var formBody = new Sys.StringBuilder(); 174 | var count = formElements.length; 175 | for (var i = 0; i < count; i++) { 176 | var element = formElements[i]; 177 | var name = element.name; 178 | if (!name || !name.length) { 179 | continue; 180 | } 181 | var tagName = element.tagName.toUpperCase(); 182 | if (tagName === 'INPUT') { 183 | var inputElement = element; 184 | var type = inputElement.type; 185 | if ((type === 'text') || (type === 'password') || (type === 'hidden') || (((type === 'checkbox') || (type === 'radio')) && element.checked)) { 186 | formBody.append(encodeURIComponent(name)); 187 | formBody.append('='); 188 | formBody.append(encodeURIComponent(inputElement.value)); 189 | formBody.append('&'); 190 | } 191 | } 192 | else if (tagName === 'SELECT') { 193 | var selectElement = element; 194 | var optionCount = selectElement.options.length; 195 | for (var j = 0; j < optionCount; j++) { 196 | var optionElement = selectElement.options[j]; 197 | if (optionElement.selected) { 198 | formBody.append(encodeURIComponent(name)); 199 | formBody.append('='); 200 | formBody.append(encodeURIComponent(optionElement.value)); 201 | formBody.append('&'); 202 | } 203 | } 204 | } 205 | else if (tagName === 'TEXTAREA') { 206 | formBody.append(encodeURIComponent(name)); 207 | formBody.append('='); 208 | formBody.append(encodeURIComponent((element.value))); 209 | formBody.append('&'); 210 | } 211 | } 212 | var additionalInput = form._additionalInput; 213 | if (additionalInput) { 214 | formBody.append(additionalInput); 215 | formBody.append('&'); 216 | } 217 | return formBody.toString(); 218 | } 219 | Sys.Mvc.MvcHelpers._asyncRequest = function Sys_Mvc_MvcHelpers$_asyncRequest(url, verb, body, triggerElement, ajaxOptions) { 220 | /// 221 | /// 222 | /// 223 | /// 224 | /// 225 | /// 226 | /// 227 | /// 228 | /// 229 | /// 230 | if (ajaxOptions.confirm) { 231 | if (!confirm(ajaxOptions.confirm)) { 232 | return; 233 | } 234 | } 235 | if (ajaxOptions.url) { 236 | url = ajaxOptions.url; 237 | } 238 | if (ajaxOptions.httpMethod) { 239 | verb = ajaxOptions.httpMethod; 240 | } 241 | if (body.length > 0 && !body.endsWith('&')) { 242 | body += '&'; 243 | } 244 | body += 'X-Requested-With=XMLHttpRequest'; 245 | var upperCaseVerb = verb.toUpperCase(); 246 | var isGetOrPost = (upperCaseVerb === 'GET' || upperCaseVerb === 'POST'); 247 | if (!isGetOrPost) { 248 | body += '&'; 249 | body += 'X-HTTP-Method-Override=' + upperCaseVerb; 250 | } 251 | var requestBody = ''; 252 | if (upperCaseVerb === 'GET' || upperCaseVerb === 'DELETE') { 253 | if (url.indexOf('?') > -1) { 254 | if (!url.endsWith('&')) { 255 | url += '&'; 256 | } 257 | url += body; 258 | } 259 | else { 260 | url += '?'; 261 | url += body; 262 | } 263 | } 264 | else { 265 | requestBody = body; 266 | } 267 | var request = new Sys.Net.WebRequest(); 268 | request.set_url(url); 269 | if (isGetOrPost) { 270 | request.set_httpVerb(verb); 271 | } 272 | else { 273 | request.set_httpVerb('POST'); 274 | request.get_headers()['X-HTTP-Method-Override'] = upperCaseVerb; 275 | } 276 | request.set_body(requestBody); 277 | if (verb.toUpperCase() === 'PUT') { 278 | request.get_headers()['Content-Type'] = 'application/x-www-form-urlencoded;'; 279 | } 280 | request.get_headers()['X-Requested-With'] = 'XMLHttpRequest'; 281 | var updateElement = null; 282 | if (ajaxOptions.updateTargetId) { 283 | updateElement = $get(ajaxOptions.updateTargetId); 284 | } 285 | var loadingElement = null; 286 | if (ajaxOptions.loadingElementId) { 287 | loadingElement = $get(ajaxOptions.loadingElementId); 288 | } 289 | var ajaxContext = new Sys.Mvc.AjaxContext(request, updateElement, loadingElement, ajaxOptions.insertionMode); 290 | var continueRequest = true; 291 | if (ajaxOptions.onBegin) { 292 | continueRequest = ajaxOptions.onBegin(ajaxContext) !== false; 293 | } 294 | if (loadingElement) { 295 | Sys.UI.DomElement.setVisible(ajaxContext.get_loadingElement(), true); 296 | } 297 | if (continueRequest) { 298 | request.add_completed(Function.createDelegate(null, function(executor) { 299 | Sys.Mvc.MvcHelpers._onComplete(request, ajaxOptions, ajaxContext); 300 | })); 301 | request.invoke(); 302 | } 303 | } 304 | Sys.Mvc.MvcHelpers._onComplete = function Sys_Mvc_MvcHelpers$_onComplete(request, ajaxOptions, ajaxContext) { 305 | /// 306 | /// 307 | /// 308 | /// 309 | /// 310 | /// 311 | ajaxContext.set_response(request.get_executor()); 312 | if (ajaxOptions.onComplete && ajaxOptions.onComplete(ajaxContext) === false) { 313 | return; 314 | } 315 | var statusCode = ajaxContext.get_response().get_statusCode(); 316 | if ((statusCode >= 200 && statusCode < 300) || statusCode === 304 || statusCode === 1223) { 317 | if (statusCode !== 204 && statusCode !== 304 && statusCode !== 1223) { 318 | var contentType = ajaxContext.get_response().getResponseHeader('Content-Type'); 319 | if ((contentType) && (contentType.indexOf('application/x-javascript') !== -1)) { 320 | eval(ajaxContext.get_data()); 321 | } 322 | else { 323 | Sys.Mvc.MvcHelpers.updateDomElement(ajaxContext.get_updateTarget(), ajaxContext.get_insertionMode(), ajaxContext.get_data()); 324 | } 325 | } 326 | if (ajaxOptions.onSuccess) { 327 | ajaxOptions.onSuccess(ajaxContext); 328 | } 329 | } 330 | else { 331 | if (ajaxOptions.onFailure) { 332 | ajaxOptions.onFailure(ajaxContext); 333 | } 334 | } 335 | if (ajaxContext.get_loadingElement()) { 336 | Sys.UI.DomElement.setVisible(ajaxContext.get_loadingElement(), false); 337 | } 338 | } 339 | Sys.Mvc.MvcHelpers.updateDomElement = function Sys_Mvc_MvcHelpers$updateDomElement(target, insertionMode, content) { 340 | /// 341 | /// 342 | /// 343 | /// 344 | /// 345 | /// 346 | if (target) { 347 | switch (insertionMode) { 348 | case Sys.Mvc.InsertionMode.replace: 349 | target.innerHTML = content; 350 | break; 351 | case Sys.Mvc.InsertionMode.insertBefore: 352 | if (content && content.length > 0) { 353 | target.innerHTML = content + target.innerHTML.trimStart(); 354 | } 355 | break; 356 | case Sys.Mvc.InsertionMode.insertAfter: 357 | if (content && content.length > 0) { 358 | target.innerHTML = target.innerHTML.trimEnd() + content; 359 | } 360 | break; 361 | } 362 | } 363 | } 364 | 365 | 366 | //////////////////////////////////////////////////////////////////////////////// 367 | // Sys.Mvc.AsyncForm 368 | 369 | Sys.Mvc.AsyncForm = function Sys_Mvc_AsyncForm() { 370 | } 371 | Sys.Mvc.AsyncForm.handleClick = function Sys_Mvc_AsyncForm$handleClick(form, evt) { 372 | /// 373 | /// 374 | /// 375 | /// 376 | var additionalInput = Sys.Mvc.MvcHelpers._serializeSubmitButton(evt.target, evt.offsetX, evt.offsetY); 377 | form._additionalInput = additionalInput; 378 | } 379 | Sys.Mvc.AsyncForm.handleSubmit = function Sys_Mvc_AsyncForm$handleSubmit(form, evt, ajaxOptions) { 380 | /// 381 | /// 382 | /// 383 | /// 384 | /// 385 | /// 386 | evt.preventDefault(); 387 | var validationCallbacks = form.validationCallbacks; 388 | if (validationCallbacks) { 389 | for (var i = 0; i < validationCallbacks.length; i++) { 390 | var callback = validationCallbacks[i]; 391 | if (!callback()) { 392 | return; 393 | } 394 | } 395 | } 396 | var body = Sys.Mvc.MvcHelpers._serializeForm(form); 397 | Sys.Mvc.MvcHelpers._asyncRequest(form.action, form.method || 'post', body, form, ajaxOptions); 398 | } 399 | 400 | 401 | Sys.Mvc.AjaxContext.registerClass('Sys.Mvc.AjaxContext'); 402 | Sys.Mvc.AsyncHyperlink.registerClass('Sys.Mvc.AsyncHyperlink'); 403 | Sys.Mvc.MvcHelpers.registerClass('Sys.Mvc.MvcHelpers'); 404 | Sys.Mvc.AsyncForm.registerClass('Sys.Mvc.AsyncForm'); 405 | 406 | // ---- Do not remove this footer ---- 407 | // Generated using Script# v0.5.0.0 (http://projects.nikhilk.net) 408 | // ----------------------------------- 409 | -------------------------------------------------------------------------------- /CQRSGui/Scripts/jquery.validate.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery validation plug-in 1.6 3 | * 4 | * http://bassistance.de/jquery-plugins/jquery-plugin-validation/ 5 | * http://docs.jquery.com/Plugins/Validation 6 | * 7 | * Copyright (c) 2006 - 2008 Jörn Zaefferer 8 | * 9 | * $Id: jquery.validate.js 6403 2009-06-17 14:27:16Z joern.zaefferer $ 10 | * 11 | * Permission is hereby granted, free of charge, to any person obtaining 12 | * a copy of this software and associated documentation files (the 13 | * "Software"), to deal in the Software without restriction, including 14 | * without limitation the rights to use, copy, modify, merge, publish, 15 | * distribute, sublicense, and/or sell copies of the Software, and to 16 | * permit persons to whom the Software is furnished to do so, subject to 17 | * the following conditions: 18 | * 19 | * The above copyright notice and this permission notice shall be 20 | * included in all copies or substantial portions of the Software. 21 | * 22 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 25 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 26 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 27 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 28 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | */ 30 | (function($){$.extend($.fn,{validate:function(options){if(!this.length){options&&options.debug&&window.console&&console.warn("nothing selected, can't validate, returning nothing");return;}var validator=$.data(this[0],'validator');if(validator){return validator;}validator=new $.validator(options,this[0]);$.data(this[0],'validator',validator);if(validator.settings.onsubmit){this.find("input, button").filter(".cancel").click(function(){validator.cancelSubmit=true;});if(validator.settings.submitHandler){this.find("input, button").filter(":submit").click(function(){validator.submitButton=this;});}this.submit(function(event){if(validator.settings.debug)event.preventDefault();function handle(){if(validator.settings.submitHandler){if(validator.submitButton){var hidden=$("").attr("name",validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm);}validator.settings.submitHandler.call(validator,validator.currentForm);if(validator.submitButton){hidden.remove();}return false;}return true;}if(validator.cancelSubmit){validator.cancelSubmit=false;return handle();}if(validator.form()){if(validator.pendingRequest){validator.formSubmitted=true;return false;}return handle();}else{validator.focusInvalid();return false;}});}return validator;},valid:function(){if($(this[0]).is('form')){return this.validate().form();}else{var valid=true;var validator=$(this[0].form).validate();this.each(function(){valid&=validator.element(this);});return valid;}},removeAttrs:function(attributes){var result={},$element=this;$.each(attributes.split(/\s/),function(index,value){result[value]=$element.attr(value);$element.removeAttr(value);});return result;},rules:function(command,argument){var element=this[0];if(command){var settings=$.data(element.form,'validator').settings;var staticRules=settings.rules;var existingRules=$.validator.staticRules(element);switch(command){case"add":$.extend(existingRules,$.validator.normalizeRule(argument));staticRules[element.name]=existingRules;if(argument.messages)settings.messages[element.name]=$.extend(settings.messages[element.name],argument.messages);break;case"remove":if(!argument){delete staticRules[element.name];return existingRules;}var filtered={};$.each(argument.split(/\s/),function(index,method){filtered[method]=existingRules[method];delete existingRules[method];});return filtered;}}var data=$.validator.normalizeRules($.extend({},$.validator.metadataRules(element),$.validator.classRules(element),$.validator.attributeRules(element),$.validator.staticRules(element)),element);if(data.required){var param=data.required;delete data.required;data=$.extend({required:param},data);}return data;}});$.extend($.expr[":"],{blank:function(a){return!$.trim(""+a.value);},filled:function(a){return!!$.trim(""+a.value);},unchecked:function(a){return!a.checked;}});$.validator=function(options,form){this.settings=$.extend({},$.validator.defaults,options);this.currentForm=form;this.init();};$.validator.format=function(source,params){if(arguments.length==1)return function(){var args=$.makeArray(arguments);args.unshift(source);return $.validator.format.apply(this,args);};if(arguments.length>2&¶ms.constructor!=Array){params=$.makeArray(arguments).slice(1);}if(params.constructor!=Array){params=[params];}$.each(params,function(i,n){source=source.replace(new RegExp("\\{"+i+"\\}","g"),n);});return source;};$.extend($.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",validClass:"valid",errorElement:"label",focusInvalid:true,errorContainer:$([]),errorLabelContainer:$([]),onsubmit:true,ignore:[],ignoreTitle:false,onfocusin:function(element){this.lastActive=element;if(this.settings.focusCleanup&&!this.blockFocusCleanup){this.settings.unhighlight&&this.settings.unhighlight.call(this,element,this.settings.errorClass,this.settings.validClass);this.errorsFor(element).hide();}},onfocusout:function(element){if(!this.checkable(element)&&(element.name in this.submitted||!this.optional(element))){this.element(element);}},onkeyup:function(element){if(element.name in this.submitted||element==this.lastElement){this.element(element);}},onclick:function(element){if(element.name in this.submitted)this.element(element);else if(element.parentNode.name in this.submitted)this.element(element.parentNode)},highlight:function(element,errorClass,validClass){$(element).addClass(errorClass).removeClass(validClass);},unhighlight:function(element,errorClass,validClass){$(element).removeClass(errorClass).addClass(validClass);}},setDefaults:function(settings){$.extend($.validator.defaults,settings);},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.",accept:"Please enter a value with a valid extension.",maxlength:$.validator.format("Please enter no more than {0} characters."),minlength:$.validator.format("Please enter at least {0} characters."),rangelength:$.validator.format("Please enter a value between {0} and {1} characters long."),range:$.validator.format("Please enter a value between {0} and {1}."),max:$.validator.format("Please enter a value less than or equal to {0}."),min:$.validator.format("Please enter a value greater than or equal to {0}.")},autoCreateRanges:false,prototype:{init:function(){this.labelContainer=$(this.settings.errorLabelContainer);this.errorContext=this.labelContainer.length&&this.labelContainer||$(this.currentForm);this.containers=$(this.settings.errorContainer).add(this.settings.errorLabelContainer);this.submitted={};this.valueCache={};this.pendingRequest=0;this.pending={};this.invalid={};this.reset();var groups=(this.groups={});$.each(this.settings.groups,function(key,value){$.each(value.split(/\s/),function(index,name){groups[name]=key;});});var rules=this.settings.rules;$.each(rules,function(key,value){rules[key]=$.validator.normalizeRule(value);});function delegate(event){var validator=$.data(this[0].form,"validator");validator.settings["on"+event.type]&&validator.settings["on"+event.type].call(validator,this[0]);}$(this.currentForm).delegate("focusin focusout keyup",":text, :password, :file, select, textarea",delegate).delegate("click",":radio, :checkbox, select, option",delegate);if(this.settings.invalidHandler)$(this.currentForm).bind("invalid-form.validate",this.settings.invalidHandler);},form:function(){this.checkForm();$.extend(this.submitted,this.errorMap);this.invalid=$.extend({},this.errorMap);if(!this.valid())$(this.currentForm).triggerHandler("invalid-form",[this]);this.showErrors();return this.valid();},checkForm:function(){this.prepareForm();for(var i=0,elements=(this.currentElements=this.elements());elements[i];i++){this.check(elements[i]);}return this.valid();},element:function(element){element=this.clean(element);this.lastElement=element;this.prepareElement(element);this.currentElements=$(element);var result=this.check(element);if(result){delete this.invalid[element.name];}else{this.invalid[element.name]=true;}if(!this.numberOfInvalids()){this.toHide=this.toHide.add(this.containers);}this.showErrors();return result;},showErrors:function(errors){if(errors){$.extend(this.errorMap,errors);this.errorList=[];for(var name in errors){this.errorList.push({message:errors[name],element:this.findByName(name)[0]});}this.successList=$.grep(this.successList,function(element){return!(element.name in errors);});}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors();},resetForm:function(){if($.fn.resetForm)$(this.currentForm).resetForm();this.submitted={};this.prepareForm();this.hideErrors();this.elements().removeClass(this.settings.errorClass);},numberOfInvalids:function(){return this.objectLength(this.invalid);},objectLength:function(obj){var count=0;for(var i in obj)count++;return count;},hideErrors:function(){this.addWrapper(this.toHide).hide();},valid:function(){return this.size()==0;},size:function(){return this.errorList.length;},focusInvalid:function(){if(this.settings.focusInvalid){try{$(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus();}catch(e){}}},findLastActive:function(){var lastActive=this.lastActive;return lastActive&&$.grep(this.errorList,function(n){return n.element.name==lastActive.name;}).length==1&&lastActive;},elements:function(){var validator=this,rulesCache={};return $([]).add(this.currentForm.elements).filter(":input").not(":submit, :reset, :image, [disabled]").not(this.settings.ignore).filter(function(){!this.name&&validator.settings.debug&&window.console&&console.error("%o has no name assigned",this);if(this.name in rulesCache||!validator.objectLength($(this).rules()))return false;rulesCache[this.name]=true;return true;});},clean:function(selector){return $(selector)[0];},errors:function(){return $(this.settings.errorElement+"."+this.settings.errorClass,this.errorContext);},reset:function(){this.successList=[];this.errorList=[];this.errorMap={};this.toShow=$([]);this.toHide=$([]);this.currentElements=$([]);},prepareForm:function(){this.reset();this.toHide=this.errors().add(this.containers);},prepareElement:function(element){this.reset();this.toHide=this.errorsFor(element);},check:function(element){element=this.clean(element);if(this.checkable(element)){element=this.findByName(element.name)[0];}var rules=$(element).rules();var dependencyMismatch=false;for(method in rules){var rule={method:method,parameters:rules[method]};try{var result=$.validator.methods[method].call(this,element.value.replace(/\r/g,""),element,rule.parameters);if(result=="dependency-mismatch"){dependencyMismatch=true;continue;}dependencyMismatch=false;if(result=="pending"){this.toHide=this.toHide.not(this.errorsFor(element));return;}if(!result){this.formatAndAdd(element,rule);return false;}}catch(e){this.settings.debug&&window.console&&console.log("exception occured when checking element "+element.id 31 | +", check the '"+rule.method+"' method",e);throw e;}}if(dependencyMismatch)return;if(this.objectLength(rules))this.successList.push(element);return true;},customMetaMessage:function(element,method){if(!$.metadata)return;var meta=this.settings.meta?$(element).metadata()[this.settings.meta]:$(element).metadata();return meta&&meta.messages&&meta.messages[method];},customMessage:function(name,method){var m=this.settings.messages[name];return m&&(m.constructor==String?m:m[method]);},findDefined:function(){for(var i=0;iWarning: No message defined for "+element.name+"");},formatAndAdd:function(element,rule){var message=this.defaultMessage(element,rule.method),theregex=/\$?\{(\d+)\}/g;if(typeof message=="function"){message=message.call(this,rule.parameters,element);}else if(theregex.test(message)){message=jQuery.format(message.replace(theregex,'{$1}'),rule.parameters);}this.errorList.push({message:message,element:element});this.errorMap[element.name]=message;this.submitted[element.name]=message;},addWrapper:function(toToggle){if(this.settings.wrapper)toToggle=toToggle.add(toToggle.parent(this.settings.wrapper));return toToggle;},defaultShowErrors:function(){for(var i=0;this.errorList[i];i++){var error=this.errorList[i];this.settings.highlight&&this.settings.highlight.call(this,error.element,this.settings.errorClass,this.settings.validClass);this.showLabel(error.element,error.message);}if(this.errorList.length){this.toShow=this.toShow.add(this.containers);}if(this.settings.success){for(var i=0;this.successList[i];i++){this.showLabel(this.successList[i]);}}if(this.settings.unhighlight){for(var i=0,elements=this.validElements();elements[i];i++){this.settings.unhighlight.call(this,elements[i],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 $(this.errorList).map(function(){return this.element;});},showLabel:function(element,message){var label=this.errorsFor(element);if(label.length){label.removeClass().addClass(this.settings.errorClass);label.attr("generated")&&label.html(message);}else{label=$("<"+this.settings.errorElement+"/>").attr({"for":this.idOrName(element),generated:true}).addClass(this.settings.errorClass).html(message||"");if(this.settings.wrapper){label=label.hide().show().wrap("<"+this.settings.wrapper+"/>").parent();}if(!this.labelContainer.append(label).length)this.settings.errorPlacement?this.settings.errorPlacement(label,$(element)):label.insertAfter(element);}if(!message&&this.settings.success){label.text("");typeof this.settings.success=="string"?label.addClass(this.settings.success):this.settings.success(label);}this.toShow=this.toShow.add(label);},errorsFor:function(element){var name=this.idOrName(element);return this.errors().filter(function(){return $(this).attr('for')==name});},idOrName:function(element){return this.groups[element.name]||(this.checkable(element)?element.name:element.id||element.name);},checkable:function(element){return/radio|checkbox/i.test(element.type);},findByName:function(name){var form=this.currentForm;return $(document.getElementsByName(name)).map(function(index,element){return element.form==form&&element.name==name&&element||null;});},getLength:function(value,element){switch(element.nodeName.toLowerCase()){case'select':return $("option:selected",element).length;case'input':if(this.checkable(element))return this.findByName(element.name).filter(':checked').length;}return value.length;},depend:function(param,element){return this.dependTypes[typeof param]?this.dependTypes[typeof param](param,element):true;},dependTypes:{"boolean":function(param,element){return param;},"string":function(param,element){return!!$(param,element.form).length;},"function":function(param,element){return param(element);}},optional:function(element){return!$.validator.methods.required.call(this,$.trim(element.value),element)&&"dependency-mismatch";},startRequest:function(element){if(!this.pending[element.name]){this.pendingRequest++;this.pending[element.name]=true;}},stopRequest:function(element,valid){this.pendingRequest--;if(this.pendingRequest<0)this.pendingRequest=0;delete this.pending[element.name];if(valid&&this.pendingRequest==0&&this.formSubmitted&&this.form()){$(this.currentForm).submit();this.formSubmitted=false;}else if(!valid&&this.pendingRequest==0&&this.formSubmitted){$(this.currentForm).triggerHandler("invalid-form",[this]);this.formSubmitted=false;}},previousValue:function(element){return $.data(element,"previousValue")||$.data(element,"previousValue",{old:null,valid:true,message:this.defaultMessage(element,"remote")});}},classRuleSettings:{required:{required:true},email:{email:true},url:{url:true},date:{date:true},dateISO:{dateISO:true},dateDE:{dateDE:true},number:{number:true},numberDE:{numberDE:true},digits:{digits:true},creditcard:{creditcard:true}},addClassRules:function(className,rules){className.constructor==String?this.classRuleSettings[className]=rules:$.extend(this.classRuleSettings,className);},classRules:function(element){var rules={};var classes=$(element).attr('class');classes&&$.each(classes.split(' '),function(){if(this in $.validator.classRuleSettings){$.extend(rules,$.validator.classRuleSettings[this]);}});return rules;},attributeRules:function(element){var rules={};var $element=$(element);for(method in $.validator.methods){var value=$element.attr(method);if(value){rules[method]=value;}}if(rules.maxlength&&/-1|2147483647|524288/.test(rules.maxlength)){delete rules.maxlength;}return rules;},metadataRules:function(element){if(!$.metadata)return{};var meta=$.data(element.form,'validator').settings.meta;return meta?$(element).metadata()[meta]:$(element).metadata();},staticRules:function(element){var rules={};var validator=$.data(element.form,'validator');if(validator.settings.rules){rules=$.validator.normalizeRule(validator.settings.rules[element.name])||{};}return rules;},normalizeRules:function(rules,element){$.each(rules,function(prop,val){if(val===false){delete rules[prop];return;}if(val.param||val.depends){var keepRule=true;switch(typeof val.depends){case"string":keepRule=!!$(val.depends,element.form).length;break;case"function":keepRule=val.depends.call(element,element);break;}if(keepRule){rules[prop]=val.param!==undefined?val.param:true;}else{delete rules[prop];}}});$.each(rules,function(rule,parameter){rules[rule]=$.isFunction(parameter)?parameter(element):parameter;});$.each(['minlength','maxlength','min','max'],function(){if(rules[this]){rules[this]=Number(rules[this]);}});$.each(['rangelength','range'],function(){if(rules[this]){rules[this]=[Number(rules[this][0]),Number(rules[this][1])];}});if($.validator.autoCreateRanges){if(rules.min&&rules.max){rules.range=[rules.min,rules.max];delete rules.min;delete rules.max;}if(rules.minlength&&rules.maxlength){rules.rangelength=[rules.minlength,rules.maxlength];delete rules.minlength;delete rules.maxlength;}}if(rules.messages){delete rules.messages}return rules;},normalizeRule:function(data){if(typeof data=="string"){var transformed={};$.each(data.split(/\s/),function(){transformed[this]=true;});data=transformed;}return data;},addMethod:function(name,method,message){$.validator.methods[name]=method;$.validator.messages[name]=message!=undefined?message:$.validator.messages[name];if(method.length<3){$.validator.addClassRules(name,$.validator.normalizeRule(name));}},methods:{required:function(value,element,param){if(!this.depend(param,element))return"dependency-mismatch";switch(element.nodeName.toLowerCase()){case'select':var val=$(element).val();return val&&val.length>0;case'input':if(this.checkable(element))return this.getLength(value,element)>0;default:return $.trim(value).length>0;}},remote:function(value,element,param){if(this.optional(element))return"dependency-mismatch";var previous=this.previousValue(element);if(!this.settings.messages[element.name])this.settings.messages[element.name]={};previous.originalMessage=this.settings.messages[element.name].remote;this.settings.messages[element.name].remote=previous.message;param=typeof param=="string"&&{url:param}||param;if(previous.old!==value){previous.old=value;var validator=this;this.startRequest(element);var data={};data[element.name]=value;$.ajax($.extend(true,{url:param,mode:"abort",port:"validate"+element.name,dataType:"json",data:data,success:function(response){validator.settings.messages[element.name].remote=previous.originalMessage;var valid=response===true;if(valid){var submitted=validator.formSubmitted;validator.prepareElement(element);validator.formSubmitted=submitted;validator.successList.push(element);validator.showErrors();}else{var errors={};var message=(previous.message=response||validator.defaultMessage(element,"remote"));errors[element.name]=$.isFunction(message)?message(value):message;validator.showErrors(errors);}previous.valid=valid;validator.stopRequest(element,valid);}},param));return"pending";}else if(this.pending[element.name]){return"pending";}return previous.valid;},minlength:function(value,element,param){return this.optional(element)||this.getLength($.trim(value),element)>=param;},maxlength:function(value,element,param){return this.optional(element)||this.getLength($.trim(value),element)<=param;},rangelength:function(value,element,param){var length=this.getLength($.trim(value),element);return this.optional(element)||(length>=param[0]&&length<=param[1]);},min:function(value,element,param){return this.optional(element)||value>=param;},max:function(value,element,param){return this.optional(element)||value<=param;},range:function(value,element,param){return this.optional(element)||(value>=param[0]&&value<=param[1]);},email:function(value,element){return this.optional(element)||/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([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])))\.?$/i.test(value);},url:function(value,element){return this.optional(element)||/^(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(value);},date:function(value,element){return this.optional(element)||!/Invalid|NaN/.test(new Date(value));},dateISO:function(value,element){return this.optional(element)||/^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value);},number:function(value,element){return this.optional(element)||/^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value);},digits:function(value,element){return this.optional(element)||/^\d+$/.test(value);},creditcard:function(value,element){if(this.optional(element))return"dependency-mismatch";if(/[^0-9-]+/.test(value))return false;var nCheck=0,nDigit=0,bEven=false;value=value.replace(/\D/g,"");for(var n=value.length-1;n>=0;n--){var cDigit=value.charAt(n);var nDigit=parseInt(cDigit,10);if(bEven){if((nDigit*=2)>9)nDigit-=9;}nCheck+=nDigit;bEven=!bEven;}return(nCheck%10)==0;},accept:function(value,element,param){param=typeof param=="string"?param.replace(/,/g,'|'):"png|jpe?g|gif";return this.optional(element)||value.match(new RegExp(".("+param+")$","i"));},equalTo:function(value,element,param){var target=$(param).unbind(".validate-equalTo").bind("blur.validate-equalTo",function(){$(element).valid();});return value==target.val();}}});$.format=$.validator.format;})(jQuery);;(function($){var ajax=$.ajax;var pendingRequests={};$.ajax=function(settings){settings=$.extend(settings,$.extend({},$.ajaxSettings,settings));var port=settings.port;if(settings.mode=="abort"){if(pendingRequests[port]){pendingRequests[port].abort();}return(pendingRequests[port]=ajax.apply(this,arguments));}return ajax.apply(this,arguments);};})(jQuery);;(function($){$.each({focus:'focusin',blur:'focusout'},function(original,fix){$.event.special[fix]={setup:function(){if($.browser.msie)return false;this.addEventListener(original,$.event.special[fix].handler,true);},teardown:function(){if($.browser.msie)return false;this.removeEventListener(original,$.event.special[fix].handler,true);},handler:function(e){arguments[0]=$.event.fix(e);arguments[0].type=fix;return $.event.handle.apply(this,arguments);}};});$.extend($.fn,{delegate:function(type,delegate,handler){return this.bind(type,function(event){var target=$(event.target);if(target.is(delegate)){return handler.apply(target,arguments);}});},triggerEvent:function(type,target){return this.triggerHandler(type,[$.event.fix({type:type,target:target})]);}})})(jQuery); -------------------------------------------------------------------------------- /CQRSGui/Scripts/MicrosoftMvcValidation.debug.js: -------------------------------------------------------------------------------- 1 | //!---------------------------------------------------------- 2 | //! Copyright (C) Microsoft Corporation. All rights reserved. 3 | //!---------------------------------------------------------- 4 | //! MicrosoftMvcValidation.js 5 | 6 | 7 | Type.registerNamespace('Sys.Mvc'); 8 | 9 | //////////////////////////////////////////////////////////////////////////////// 10 | // Sys.Mvc.Validation 11 | 12 | Sys.Mvc.$create_Validation = function Sys_Mvc_Validation() { return {}; } 13 | 14 | 15 | //////////////////////////////////////////////////////////////////////////////// 16 | // Sys.Mvc.JsonValidationField 17 | 18 | Sys.Mvc.$create_JsonValidationField = function Sys_Mvc_JsonValidationField() { return {}; } 19 | 20 | 21 | //////////////////////////////////////////////////////////////////////////////// 22 | // Sys.Mvc.JsonValidationOptions 23 | 24 | Sys.Mvc.$create_JsonValidationOptions = function Sys_Mvc_JsonValidationOptions() { return {}; } 25 | 26 | 27 | //////////////////////////////////////////////////////////////////////////////// 28 | // Sys.Mvc.JsonValidationRule 29 | 30 | Sys.Mvc.$create_JsonValidationRule = function Sys_Mvc_JsonValidationRule() { return {}; } 31 | 32 | 33 | //////////////////////////////////////////////////////////////////////////////// 34 | // Sys.Mvc.ValidationContext 35 | 36 | Sys.Mvc.$create_ValidationContext = function Sys_Mvc_ValidationContext() { return {}; } 37 | 38 | 39 | //////////////////////////////////////////////////////////////////////////////// 40 | // Sys.Mvc.NumberValidator 41 | 42 | Sys.Mvc.NumberValidator = function Sys_Mvc_NumberValidator() { 43 | } 44 | Sys.Mvc.NumberValidator.create = function Sys_Mvc_NumberValidator$create(rule) { 45 | /// 46 | /// 47 | /// 48 | return Function.createDelegate(new Sys.Mvc.NumberValidator(), new Sys.Mvc.NumberValidator().validate); 49 | } 50 | Sys.Mvc.NumberValidator.prototype = { 51 | 52 | validate: function Sys_Mvc_NumberValidator$validate(value, context) { 53 | /// 54 | /// 55 | /// 56 | /// 57 | /// 58 | if (Sys.Mvc._validationUtil.stringIsNullOrEmpty(value)) { 59 | return true; 60 | } 61 | var n = Number.parseLocale(value); 62 | return (!isNaN(n)); 63 | } 64 | } 65 | 66 | 67 | //////////////////////////////////////////////////////////////////////////////// 68 | // Sys.Mvc.FormContext 69 | 70 | Sys.Mvc.FormContext = function Sys_Mvc_FormContext(formElement, validationSummaryElement) { 71 | /// 72 | /// 73 | /// 74 | /// 75 | /// 76 | /// 77 | /// 78 | /// 79 | /// 80 | /// 81 | /// 82 | /// 83 | /// 84 | /// 85 | /// 86 | /// 87 | /// 88 | /// 89 | /// 90 | /// 91 | /// 92 | /// 93 | /// 94 | /// 95 | /// 96 | /// 97 | /// 98 | /// 99 | this._errors = []; 100 | this.fields = new Array(0); 101 | this._formElement = formElement; 102 | this._validationSummaryElement = validationSummaryElement; 103 | formElement[Sys.Mvc.FormContext._formValidationTag] = this; 104 | if (validationSummaryElement) { 105 | var ulElements = validationSummaryElement.getElementsByTagName('ul'); 106 | if (ulElements.length > 0) { 107 | this._validationSummaryULElement = ulElements[0]; 108 | } 109 | } 110 | this._onClickHandler = Function.createDelegate(this, this._form_OnClick); 111 | this._onSubmitHandler = Function.createDelegate(this, this._form_OnSubmit); 112 | } 113 | Sys.Mvc.FormContext._Application_Load = function Sys_Mvc_FormContext$_Application_Load() { 114 | var allFormOptions = window.mvcClientValidationMetadata; 115 | if (allFormOptions) { 116 | while (allFormOptions.length > 0) { 117 | var thisFormOptions = allFormOptions.pop(); 118 | Sys.Mvc.FormContext._parseJsonOptions(thisFormOptions); 119 | } 120 | } 121 | } 122 | Sys.Mvc.FormContext._getFormElementsWithName = function Sys_Mvc_FormContext$_getFormElementsWithName(formElement, name) { 123 | /// 124 | /// 125 | /// 126 | /// 127 | /// 128 | var allElementsWithNameInForm = []; 129 | var allElementsWithName = document.getElementsByName(name); 130 | for (var i = 0; i < allElementsWithName.length; i++) { 131 | var thisElement = allElementsWithName[i]; 132 | if (Sys.Mvc.FormContext._isElementInHierarchy(formElement, thisElement)) { 133 | Array.add(allElementsWithNameInForm, thisElement); 134 | } 135 | } 136 | return allElementsWithNameInForm; 137 | } 138 | Sys.Mvc.FormContext.getValidationForForm = function Sys_Mvc_FormContext$getValidationForForm(formElement) { 139 | /// 140 | /// 141 | /// 142 | return formElement[Sys.Mvc.FormContext._formValidationTag]; 143 | } 144 | Sys.Mvc.FormContext._isElementInHierarchy = function Sys_Mvc_FormContext$_isElementInHierarchy(parent, child) { 145 | /// 146 | /// 147 | /// 148 | /// 149 | /// 150 | while (child) { 151 | if (parent === child) { 152 | return true; 153 | } 154 | child = child.parentNode; 155 | } 156 | return false; 157 | } 158 | Sys.Mvc.FormContext._parseJsonOptions = function Sys_Mvc_FormContext$_parseJsonOptions(options) { 159 | /// 160 | /// 161 | /// 162 | var formElement = $get(options.FormId); 163 | var validationSummaryElement = (!Sys.Mvc._validationUtil.stringIsNullOrEmpty(options.ValidationSummaryId)) ? $get(options.ValidationSummaryId) : null; 164 | var formContext = new Sys.Mvc.FormContext(formElement, validationSummaryElement); 165 | formContext.enableDynamicValidation(); 166 | formContext.replaceValidationSummary = options.ReplaceValidationSummary; 167 | for (var i = 0; i < options.Fields.length; i++) { 168 | var field = options.Fields[i]; 169 | var fieldElements = Sys.Mvc.FormContext._getFormElementsWithName(formElement, field.FieldName); 170 | var validationMessageElement = (!Sys.Mvc._validationUtil.stringIsNullOrEmpty(field.ValidationMessageId)) ? $get(field.ValidationMessageId) : null; 171 | var fieldContext = new Sys.Mvc.FieldContext(formContext); 172 | Array.addRange(fieldContext.elements, fieldElements); 173 | fieldContext.validationMessageElement = validationMessageElement; 174 | fieldContext.replaceValidationMessageContents = field.ReplaceValidationMessageContents; 175 | for (var j = 0; j < field.ValidationRules.length; j++) { 176 | var rule = field.ValidationRules[j]; 177 | var validator = Sys.Mvc.ValidatorRegistry.getValidator(rule); 178 | if (validator) { 179 | var validation = Sys.Mvc.$create_Validation(); 180 | validation.fieldErrorMessage = rule.ErrorMessage; 181 | validation.validator = validator; 182 | Array.add(fieldContext.validations, validation); 183 | } 184 | } 185 | fieldContext.enableDynamicValidation(); 186 | Array.add(formContext.fields, fieldContext); 187 | } 188 | var registeredValidatorCallbacks = formElement.validationCallbacks; 189 | if (!registeredValidatorCallbacks) { 190 | registeredValidatorCallbacks = []; 191 | formElement.validationCallbacks = registeredValidatorCallbacks; 192 | } 193 | registeredValidatorCallbacks.push(Function.createDelegate(null, function() { 194 | return Sys.Mvc._validationUtil.arrayIsNullOrEmpty(formContext.validate('submit')); 195 | })); 196 | return formContext; 197 | } 198 | Sys.Mvc.FormContext.prototype = { 199 | _onClickHandler: null, 200 | _onSubmitHandler: null, 201 | _submitButtonClicked: null, 202 | _validationSummaryElement: null, 203 | _validationSummaryULElement: null, 204 | _formElement: null, 205 | replaceValidationSummary: false, 206 | 207 | addError: function Sys_Mvc_FormContext$addError(message) { 208 | /// 209 | /// 210 | this.addErrors([ message ]); 211 | }, 212 | 213 | addErrors: function Sys_Mvc_FormContext$addErrors(messages) { 214 | /// 215 | /// 216 | if (!Sys.Mvc._validationUtil.arrayIsNullOrEmpty(messages)) { 217 | Array.addRange(this._errors, messages); 218 | this._onErrorCountChanged(); 219 | } 220 | }, 221 | 222 | clearErrors: function Sys_Mvc_FormContext$clearErrors() { 223 | Array.clear(this._errors); 224 | this._onErrorCountChanged(); 225 | }, 226 | 227 | _displayError: function Sys_Mvc_FormContext$_displayError() { 228 | if (this._validationSummaryElement) { 229 | if (this._validationSummaryULElement) { 230 | Sys.Mvc._validationUtil.removeAllChildren(this._validationSummaryULElement); 231 | for (var i = 0; i < this._errors.length; i++) { 232 | var liElement = document.createElement('li'); 233 | Sys.Mvc._validationUtil.setInnerText(liElement, this._errors[i]); 234 | this._validationSummaryULElement.appendChild(liElement); 235 | } 236 | } 237 | Sys.UI.DomElement.removeCssClass(this._validationSummaryElement, Sys.Mvc.FormContext._validationSummaryValidCss); 238 | Sys.UI.DomElement.addCssClass(this._validationSummaryElement, Sys.Mvc.FormContext._validationSummaryErrorCss); 239 | } 240 | }, 241 | 242 | _displaySuccess: function Sys_Mvc_FormContext$_displaySuccess() { 243 | var validationSummaryElement = this._validationSummaryElement; 244 | if (validationSummaryElement) { 245 | var validationSummaryULElement = this._validationSummaryULElement; 246 | if (validationSummaryULElement) { 247 | validationSummaryULElement.innerHTML = ''; 248 | } 249 | Sys.UI.DomElement.removeCssClass(validationSummaryElement, Sys.Mvc.FormContext._validationSummaryErrorCss); 250 | Sys.UI.DomElement.addCssClass(validationSummaryElement, Sys.Mvc.FormContext._validationSummaryValidCss); 251 | } 252 | }, 253 | 254 | enableDynamicValidation: function Sys_Mvc_FormContext$enableDynamicValidation() { 255 | Sys.UI.DomEvent.addHandler(this._formElement, 'click', this._onClickHandler); 256 | Sys.UI.DomEvent.addHandler(this._formElement, 'submit', this._onSubmitHandler); 257 | }, 258 | 259 | _findSubmitButton: function Sys_Mvc_FormContext$_findSubmitButton(element) { 260 | /// 261 | /// 262 | /// 263 | if (element.disabled) { 264 | return null; 265 | } 266 | var tagName = element.tagName.toUpperCase(); 267 | var inputElement = element; 268 | if (tagName === 'INPUT') { 269 | var type = inputElement.type; 270 | if (type === 'submit' || type === 'image') { 271 | return inputElement; 272 | } 273 | } 274 | else if ((tagName === 'BUTTON') && (inputElement.type === 'submit')) { 275 | return inputElement; 276 | } 277 | return null; 278 | }, 279 | 280 | _form_OnClick: function Sys_Mvc_FormContext$_form_OnClick(e) { 281 | /// 282 | /// 283 | this._submitButtonClicked = this._findSubmitButton(e.target); 284 | }, 285 | 286 | _form_OnSubmit: function Sys_Mvc_FormContext$_form_OnSubmit(e) { 287 | /// 288 | /// 289 | var form = e.target; 290 | var submitButton = this._submitButtonClicked; 291 | if (submitButton && submitButton.disableValidation) { 292 | return; 293 | } 294 | var errorMessages = this.validate('submit'); 295 | if (!Sys.Mvc._validationUtil.arrayIsNullOrEmpty(errorMessages)) { 296 | e.preventDefault(); 297 | } 298 | }, 299 | 300 | _onErrorCountChanged: function Sys_Mvc_FormContext$_onErrorCountChanged() { 301 | if (!this._errors.length) { 302 | this._displaySuccess(); 303 | } 304 | else { 305 | this._displayError(); 306 | } 307 | }, 308 | 309 | validate: function Sys_Mvc_FormContext$validate(eventName) { 310 | /// 311 | /// 312 | /// 313 | var fields = this.fields; 314 | var errors = []; 315 | for (var i = 0; i < fields.length; i++) { 316 | var field = fields[i]; 317 | var thisErrors = field.validate(eventName); 318 | if (thisErrors) { 319 | Array.addRange(errors, thisErrors); 320 | } 321 | } 322 | if (this.replaceValidationSummary) { 323 | this.clearErrors(); 324 | this.addErrors(errors); 325 | } 326 | return errors; 327 | } 328 | } 329 | 330 | 331 | //////////////////////////////////////////////////////////////////////////////// 332 | // Sys.Mvc.FieldContext 333 | 334 | Sys.Mvc.FieldContext = function Sys_Mvc_FieldContext(formContext) { 335 | /// 336 | /// 337 | /// 338 | /// 339 | /// 340 | /// 341 | /// 342 | /// 343 | /// 344 | /// 345 | /// 346 | /// 347 | /// 348 | /// 349 | /// 350 | /// 351 | /// 352 | /// 353 | /// 354 | /// 355 | /// 356 | /// 357 | /// 358 | /// 359 | /// 360 | /// 361 | /// 362 | /// 363 | /// 364 | /// 365 | /// 366 | /// 367 | /// 368 | /// 369 | /// 370 | /// 371 | this._errors = []; 372 | this.elements = new Array(0); 373 | this.validations = new Array(0); 374 | this.formContext = formContext; 375 | this._onBlurHandler = Function.createDelegate(this, this._element_OnBlur); 376 | this._onChangeHandler = Function.createDelegate(this, this._element_OnChange); 377 | this._onInputHandler = Function.createDelegate(this, this._element_OnInput); 378 | this._onPropertyChangeHandler = Function.createDelegate(this, this._element_OnPropertyChange); 379 | } 380 | Sys.Mvc.FieldContext.prototype = { 381 | _onBlurHandler: null, 382 | _onChangeHandler: null, 383 | _onInputHandler: null, 384 | _onPropertyChangeHandler: null, 385 | defaultErrorMessage: null, 386 | formContext: null, 387 | replaceValidationMessageContents: false, 388 | validationMessageElement: null, 389 | 390 | addError: function Sys_Mvc_FieldContext$addError(message) { 391 | /// 392 | /// 393 | this.addErrors([ message ]); 394 | }, 395 | 396 | addErrors: function Sys_Mvc_FieldContext$addErrors(messages) { 397 | /// 398 | /// 399 | if (!Sys.Mvc._validationUtil.arrayIsNullOrEmpty(messages)) { 400 | Array.addRange(this._errors, messages); 401 | this._onErrorCountChanged(); 402 | } 403 | }, 404 | 405 | clearErrors: function Sys_Mvc_FieldContext$clearErrors() { 406 | Array.clear(this._errors); 407 | this._onErrorCountChanged(); 408 | }, 409 | 410 | _displayError: function Sys_Mvc_FieldContext$_displayError() { 411 | var validationMessageElement = this.validationMessageElement; 412 | if (validationMessageElement) { 413 | if (this.replaceValidationMessageContents) { 414 | Sys.Mvc._validationUtil.setInnerText(validationMessageElement, this._errors[0]); 415 | } 416 | Sys.UI.DomElement.removeCssClass(validationMessageElement, Sys.Mvc.FieldContext._validationMessageValidCss); 417 | Sys.UI.DomElement.addCssClass(validationMessageElement, Sys.Mvc.FieldContext._validationMessageErrorCss); 418 | } 419 | var elements = this.elements; 420 | for (var i = 0; i < elements.length; i++) { 421 | var element = elements[i]; 422 | Sys.UI.DomElement.removeCssClass(element, Sys.Mvc.FieldContext._inputElementValidCss); 423 | Sys.UI.DomElement.addCssClass(element, Sys.Mvc.FieldContext._inputElementErrorCss); 424 | } 425 | }, 426 | 427 | _displaySuccess: function Sys_Mvc_FieldContext$_displaySuccess() { 428 | var validationMessageElement = this.validationMessageElement; 429 | if (validationMessageElement) { 430 | if (this.replaceValidationMessageContents) { 431 | Sys.Mvc._validationUtil.setInnerText(validationMessageElement, ''); 432 | } 433 | Sys.UI.DomElement.removeCssClass(validationMessageElement, Sys.Mvc.FieldContext._validationMessageErrorCss); 434 | Sys.UI.DomElement.addCssClass(validationMessageElement, Sys.Mvc.FieldContext._validationMessageValidCss); 435 | } 436 | var elements = this.elements; 437 | for (var i = 0; i < elements.length; i++) { 438 | var element = elements[i]; 439 | Sys.UI.DomElement.removeCssClass(element, Sys.Mvc.FieldContext._inputElementErrorCss); 440 | Sys.UI.DomElement.addCssClass(element, Sys.Mvc.FieldContext._inputElementValidCss); 441 | } 442 | }, 443 | 444 | _element_OnBlur: function Sys_Mvc_FieldContext$_element_OnBlur(e) { 445 | /// 446 | /// 447 | if (e.target[Sys.Mvc.FieldContext._hasTextChangedTag] || e.target[Sys.Mvc.FieldContext._hasValidationFiredTag]) { 448 | this.validate('blur'); 449 | } 450 | }, 451 | 452 | _element_OnChange: function Sys_Mvc_FieldContext$_element_OnChange(e) { 453 | /// 454 | /// 455 | e.target[Sys.Mvc.FieldContext._hasTextChangedTag] = true; 456 | }, 457 | 458 | _element_OnInput: function Sys_Mvc_FieldContext$_element_OnInput(e) { 459 | /// 460 | /// 461 | e.target[Sys.Mvc.FieldContext._hasTextChangedTag] = true; 462 | if (e.target[Sys.Mvc.FieldContext._hasValidationFiredTag]) { 463 | this.validate('input'); 464 | } 465 | }, 466 | 467 | _element_OnPropertyChange: function Sys_Mvc_FieldContext$_element_OnPropertyChange(e) { 468 | /// 469 | /// 470 | if (e.rawEvent.propertyName === 'value') { 471 | e.target[Sys.Mvc.FieldContext._hasTextChangedTag] = true; 472 | if (e.target[Sys.Mvc.FieldContext._hasValidationFiredTag]) { 473 | this.validate('input'); 474 | } 475 | } 476 | }, 477 | 478 | enableDynamicValidation: function Sys_Mvc_FieldContext$enableDynamicValidation() { 479 | var elements = this.elements; 480 | for (var i = 0; i < elements.length; i++) { 481 | var element = elements[i]; 482 | if (Sys.Mvc._validationUtil.elementSupportsEvent(element, 'onpropertychange')) { 483 | var compatMode = document.documentMode; 484 | if (compatMode && compatMode >= 8) { 485 | Sys.UI.DomEvent.addHandler(element, 'propertychange', this._onPropertyChangeHandler); 486 | } 487 | } 488 | else { 489 | Sys.UI.DomEvent.addHandler(element, 'input', this._onInputHandler); 490 | } 491 | Sys.UI.DomEvent.addHandler(element, 'change', this._onChangeHandler); 492 | Sys.UI.DomEvent.addHandler(element, 'blur', this._onBlurHandler); 493 | } 494 | }, 495 | 496 | _getErrorString: function Sys_Mvc_FieldContext$_getErrorString(validatorReturnValue, fieldErrorMessage) { 497 | /// 498 | /// 499 | /// 500 | /// 501 | /// 502 | var fallbackErrorMessage = fieldErrorMessage || this.defaultErrorMessage; 503 | if (Boolean.isInstanceOfType(validatorReturnValue)) { 504 | return (validatorReturnValue) ? null : fallbackErrorMessage; 505 | } 506 | if (String.isInstanceOfType(validatorReturnValue)) { 507 | return ((validatorReturnValue).length) ? validatorReturnValue : fallbackErrorMessage; 508 | } 509 | return null; 510 | }, 511 | 512 | _getStringValue: function Sys_Mvc_FieldContext$_getStringValue() { 513 | /// 514 | var elements = this.elements; 515 | return (elements.length > 0) ? elements[0].value : null; 516 | }, 517 | 518 | _markValidationFired: function Sys_Mvc_FieldContext$_markValidationFired() { 519 | var elements = this.elements; 520 | for (var i = 0; i < elements.length; i++) { 521 | var element = elements[i]; 522 | element[Sys.Mvc.FieldContext._hasValidationFiredTag] = true; 523 | } 524 | }, 525 | 526 | _onErrorCountChanged: function Sys_Mvc_FieldContext$_onErrorCountChanged() { 527 | if (!this._errors.length) { 528 | this._displaySuccess(); 529 | } 530 | else { 531 | this._displayError(); 532 | } 533 | }, 534 | 535 | validate: function Sys_Mvc_FieldContext$validate(eventName) { 536 | /// 537 | /// 538 | /// 539 | var validations = this.validations; 540 | var errors = []; 541 | var value = this._getStringValue(); 542 | for (var i = 0; i < validations.length; i++) { 543 | var validation = validations[i]; 544 | var context = Sys.Mvc.$create_ValidationContext(); 545 | context.eventName = eventName; 546 | context.fieldContext = this; 547 | context.validation = validation; 548 | var retVal = validation.validator(value, context); 549 | var errorMessage = this._getErrorString(retVal, validation.fieldErrorMessage); 550 | if (!Sys.Mvc._validationUtil.stringIsNullOrEmpty(errorMessage)) { 551 | Array.add(errors, errorMessage); 552 | } 553 | } 554 | this._markValidationFired(); 555 | this.clearErrors(); 556 | this.addErrors(errors); 557 | return errors; 558 | } 559 | } 560 | 561 | 562 | //////////////////////////////////////////////////////////////////////////////// 563 | // Sys.Mvc.RangeValidator 564 | 565 | Sys.Mvc.RangeValidator = function Sys_Mvc_RangeValidator(minimum, maximum) { 566 | /// 567 | /// 568 | /// 569 | /// 570 | /// 571 | /// 572 | /// 573 | /// 574 | this._minimum = minimum; 575 | this._maximum = maximum; 576 | } 577 | Sys.Mvc.RangeValidator.create = function Sys_Mvc_RangeValidator$create(rule) { 578 | /// 579 | /// 580 | /// 581 | var min = rule.ValidationParameters['minimum']; 582 | var max = rule.ValidationParameters['maximum']; 583 | return Function.createDelegate(new Sys.Mvc.RangeValidator(min, max), new Sys.Mvc.RangeValidator(min, max).validate); 584 | } 585 | Sys.Mvc.RangeValidator.prototype = { 586 | _minimum: null, 587 | _maximum: null, 588 | 589 | validate: function Sys_Mvc_RangeValidator$validate(value, context) { 590 | /// 591 | /// 592 | /// 593 | /// 594 | /// 595 | if (Sys.Mvc._validationUtil.stringIsNullOrEmpty(value)) { 596 | return true; 597 | } 598 | var n = Number.parseLocale(value); 599 | return (!isNaN(n) && this._minimum <= n && n <= this._maximum); 600 | } 601 | } 602 | 603 | 604 | //////////////////////////////////////////////////////////////////////////////// 605 | // Sys.Mvc.RegularExpressionValidator 606 | 607 | Sys.Mvc.RegularExpressionValidator = function Sys_Mvc_RegularExpressionValidator(pattern) { 608 | /// 609 | /// 610 | /// 611 | /// 612 | this._pattern = pattern; 613 | } 614 | Sys.Mvc.RegularExpressionValidator.create = function Sys_Mvc_RegularExpressionValidator$create(rule) { 615 | /// 616 | /// 617 | /// 618 | var pattern = rule.ValidationParameters['pattern']; 619 | return Function.createDelegate(new Sys.Mvc.RegularExpressionValidator(pattern), new Sys.Mvc.RegularExpressionValidator(pattern).validate); 620 | } 621 | Sys.Mvc.RegularExpressionValidator.prototype = { 622 | _pattern: null, 623 | 624 | validate: function Sys_Mvc_RegularExpressionValidator$validate(value, context) { 625 | /// 626 | /// 627 | /// 628 | /// 629 | /// 630 | if (Sys.Mvc._validationUtil.stringIsNullOrEmpty(value)) { 631 | return true; 632 | } 633 | var regExp = new RegExp(this._pattern); 634 | var matches = regExp.exec(value); 635 | return (!Sys.Mvc._validationUtil.arrayIsNullOrEmpty(matches) && matches[0].length === value.length); 636 | } 637 | } 638 | 639 | 640 | //////////////////////////////////////////////////////////////////////////////// 641 | // Sys.Mvc.RequiredValidator 642 | 643 | Sys.Mvc.RequiredValidator = function Sys_Mvc_RequiredValidator() { 644 | } 645 | Sys.Mvc.RequiredValidator.create = function Sys_Mvc_RequiredValidator$create(rule) { 646 | /// 647 | /// 648 | /// 649 | return Function.createDelegate(new Sys.Mvc.RequiredValidator(), new Sys.Mvc.RequiredValidator().validate); 650 | } 651 | Sys.Mvc.RequiredValidator._isRadioInputElement = function Sys_Mvc_RequiredValidator$_isRadioInputElement(element) { 652 | /// 653 | /// 654 | /// 655 | if (element.tagName.toUpperCase() === 'INPUT') { 656 | var inputType = (element.type).toUpperCase(); 657 | if (inputType === 'RADIO') { 658 | return true; 659 | } 660 | } 661 | return false; 662 | } 663 | Sys.Mvc.RequiredValidator._isSelectInputElement = function Sys_Mvc_RequiredValidator$_isSelectInputElement(element) { 664 | /// 665 | /// 666 | /// 667 | if (element.tagName.toUpperCase() === 'SELECT') { 668 | return true; 669 | } 670 | return false; 671 | } 672 | Sys.Mvc.RequiredValidator._isTextualInputElement = function Sys_Mvc_RequiredValidator$_isTextualInputElement(element) { 673 | /// 674 | /// 675 | /// 676 | if (element.tagName.toUpperCase() === 'INPUT') { 677 | var inputType = (element.type).toUpperCase(); 678 | switch (inputType) { 679 | case 'TEXT': 680 | case 'PASSWORD': 681 | case 'FILE': 682 | return true; 683 | } 684 | } 685 | if (element.tagName.toUpperCase() === 'TEXTAREA') { 686 | return true; 687 | } 688 | return false; 689 | } 690 | Sys.Mvc.RequiredValidator._validateRadioInput = function Sys_Mvc_RequiredValidator$_validateRadioInput(elements) { 691 | /// 692 | /// 693 | /// 694 | for (var i = 0; i < elements.length; i++) { 695 | var element = elements[i]; 696 | if (element.checked) { 697 | return true; 698 | } 699 | } 700 | return false; 701 | } 702 | Sys.Mvc.RequiredValidator._validateSelectInput = function Sys_Mvc_RequiredValidator$_validateSelectInput(optionElements) { 703 | /// 704 | /// 705 | /// 706 | for (var i = 0; i < optionElements.length; i++) { 707 | var element = optionElements[i]; 708 | if (element.selected) { 709 | if (!Sys.Mvc._validationUtil.stringIsNullOrEmpty(element.value)) { 710 | return true; 711 | } 712 | } 713 | } 714 | return false; 715 | } 716 | Sys.Mvc.RequiredValidator._validateTextualInput = function Sys_Mvc_RequiredValidator$_validateTextualInput(element) { 717 | /// 718 | /// 719 | /// 720 | return (!Sys.Mvc._validationUtil.stringIsNullOrEmpty(element.value)); 721 | } 722 | Sys.Mvc.RequiredValidator.prototype = { 723 | 724 | validate: function Sys_Mvc_RequiredValidator$validate(value, context) { 725 | /// 726 | /// 727 | /// 728 | /// 729 | /// 730 | var elements = context.fieldContext.elements; 731 | if (!elements.length) { 732 | return true; 733 | } 734 | var sampleElement = elements[0]; 735 | if (Sys.Mvc.RequiredValidator._isTextualInputElement(sampleElement)) { 736 | return Sys.Mvc.RequiredValidator._validateTextualInput(sampleElement); 737 | } 738 | if (Sys.Mvc.RequiredValidator._isRadioInputElement(sampleElement)) { 739 | return Sys.Mvc.RequiredValidator._validateRadioInput(elements); 740 | } 741 | if (Sys.Mvc.RequiredValidator._isSelectInputElement(sampleElement)) { 742 | return Sys.Mvc.RequiredValidator._validateSelectInput((sampleElement).options); 743 | } 744 | return true; 745 | } 746 | } 747 | 748 | 749 | //////////////////////////////////////////////////////////////////////////////// 750 | // Sys.Mvc.StringLengthValidator 751 | 752 | Sys.Mvc.StringLengthValidator = function Sys_Mvc_StringLengthValidator(minLength, maxLength) { 753 | /// 754 | /// 755 | /// 756 | /// 757 | /// 758 | /// 759 | /// 760 | /// 761 | this._minLength = minLength; 762 | this._maxLength = maxLength; 763 | } 764 | Sys.Mvc.StringLengthValidator.create = function Sys_Mvc_StringLengthValidator$create(rule) { 765 | /// 766 | /// 767 | /// 768 | var minLength = rule.ValidationParameters['minimumLength']; 769 | var maxLength = rule.ValidationParameters['maximumLength']; 770 | return Function.createDelegate(new Sys.Mvc.StringLengthValidator(minLength, maxLength), new Sys.Mvc.StringLengthValidator(minLength, maxLength).validate); 771 | } 772 | Sys.Mvc.StringLengthValidator.prototype = { 773 | _maxLength: 0, 774 | _minLength: 0, 775 | 776 | validate: function Sys_Mvc_StringLengthValidator$validate(value, context) { 777 | /// 778 | /// 779 | /// 780 | /// 781 | /// 782 | if (Sys.Mvc._validationUtil.stringIsNullOrEmpty(value)) { 783 | return true; 784 | } 785 | return (this._minLength <= value.length && value.length <= this._maxLength); 786 | } 787 | } 788 | 789 | 790 | //////////////////////////////////////////////////////////////////////////////// 791 | // Sys.Mvc._validationUtil 792 | 793 | Sys.Mvc._validationUtil = function Sys_Mvc__validationUtil() { 794 | } 795 | Sys.Mvc._validationUtil.arrayIsNullOrEmpty = function Sys_Mvc__validationUtil$arrayIsNullOrEmpty(array) { 796 | /// 797 | /// 798 | /// 799 | return (!array || !array.length); 800 | } 801 | Sys.Mvc._validationUtil.stringIsNullOrEmpty = function Sys_Mvc__validationUtil$stringIsNullOrEmpty(value) { 802 | /// 803 | /// 804 | /// 805 | return (!value || !value.length); 806 | } 807 | Sys.Mvc._validationUtil.elementSupportsEvent = function Sys_Mvc__validationUtil$elementSupportsEvent(element, eventAttributeName) { 808 | /// 809 | /// 810 | /// 811 | /// 812 | /// 813 | return (eventAttributeName in element); 814 | } 815 | Sys.Mvc._validationUtil.removeAllChildren = function Sys_Mvc__validationUtil$removeAllChildren(element) { 816 | /// 817 | /// 818 | while (element.firstChild) { 819 | element.removeChild(element.firstChild); 820 | } 821 | } 822 | Sys.Mvc._validationUtil.setInnerText = function Sys_Mvc__validationUtil$setInnerText(element, innerText) { 823 | /// 824 | /// 825 | /// 826 | /// 827 | var textNode = document.createTextNode(innerText); 828 | Sys.Mvc._validationUtil.removeAllChildren(element); 829 | element.appendChild(textNode); 830 | } 831 | 832 | 833 | //////////////////////////////////////////////////////////////////////////////// 834 | // Sys.Mvc.ValidatorRegistry 835 | 836 | Sys.Mvc.ValidatorRegistry = function Sys_Mvc_ValidatorRegistry() { 837 | /// 838 | /// 839 | } 840 | Sys.Mvc.ValidatorRegistry.getValidator = function Sys_Mvc_ValidatorRegistry$getValidator(rule) { 841 | /// 842 | /// 843 | /// 844 | var creator = Sys.Mvc.ValidatorRegistry.validators[rule.ValidationType]; 845 | return (creator) ? creator(rule) : null; 846 | } 847 | Sys.Mvc.ValidatorRegistry._getDefaultValidators = function Sys_Mvc_ValidatorRegistry$_getDefaultValidators() { 848 | /// 849 | return { required: Function.createDelegate(null, Sys.Mvc.RequiredValidator.create), stringLength: Function.createDelegate(null, Sys.Mvc.StringLengthValidator.create), regularExpression: Function.createDelegate(null, Sys.Mvc.RegularExpressionValidator.create), range: Function.createDelegate(null, Sys.Mvc.RangeValidator.create), number: Function.createDelegate(null, Sys.Mvc.NumberValidator.create) }; 850 | } 851 | 852 | 853 | Sys.Mvc.NumberValidator.registerClass('Sys.Mvc.NumberValidator'); 854 | Sys.Mvc.FormContext.registerClass('Sys.Mvc.FormContext'); 855 | Sys.Mvc.FieldContext.registerClass('Sys.Mvc.FieldContext'); 856 | Sys.Mvc.RangeValidator.registerClass('Sys.Mvc.RangeValidator'); 857 | Sys.Mvc.RegularExpressionValidator.registerClass('Sys.Mvc.RegularExpressionValidator'); 858 | Sys.Mvc.RequiredValidator.registerClass('Sys.Mvc.RequiredValidator'); 859 | Sys.Mvc.StringLengthValidator.registerClass('Sys.Mvc.StringLengthValidator'); 860 | Sys.Mvc._validationUtil.registerClass('Sys.Mvc._validationUtil'); 861 | Sys.Mvc.ValidatorRegistry.registerClass('Sys.Mvc.ValidatorRegistry'); 862 | Sys.Mvc.FormContext._validationSummaryErrorCss = 'validation-summary-errors'; 863 | Sys.Mvc.FormContext._validationSummaryValidCss = 'validation-summary-valid'; 864 | Sys.Mvc.FormContext._formValidationTag = '__MVC_FormValidation'; 865 | Sys.Mvc.FieldContext._hasTextChangedTag = '__MVC_HasTextChanged'; 866 | Sys.Mvc.FieldContext._hasValidationFiredTag = '__MVC_HasValidationFired'; 867 | Sys.Mvc.FieldContext._inputElementErrorCss = 'input-validation-error'; 868 | Sys.Mvc.FieldContext._inputElementValidCss = 'input-validation-valid'; 869 | Sys.Mvc.FieldContext._validationMessageErrorCss = 'field-validation-error'; 870 | Sys.Mvc.FieldContext._validationMessageValidCss = 'field-validation-valid'; 871 | Sys.Mvc.ValidatorRegistry.validators = Sys.Mvc.ValidatorRegistry._getDefaultValidators(); 872 | 873 | // ---- Do not remove this footer ---- 874 | // Generated using Script# v0.5.0.0 (http://projects.nikhilk.net) 875 | // ----------------------------------- 876 | 877 | // register validation 878 | Sys.Application.add_load(function() { 879 | Sys.Application.remove_load(arguments.callee); 880 | Sys.Mvc.FormContext._Application_Load(); 881 | }); 882 | --------------------------------------------------------------------------------