├── .gitignore ├── LICENSE ├── QueryEncapsulation ├── QueryEncapsulation.Web │ ├── App_Start │ │ ├── AutoMapperConfig.cs │ │ ├── EFConfig.cs │ │ ├── RouteConfig.cs │ │ ├── SeedData.cs │ │ └── StructureMapConfig.cs │ ├── Controllers │ │ └── HomeController.cs │ ├── Data │ │ ├── AppDbContext.cs │ │ ├── IQuery.cs │ │ ├── PostQueryExtensions.cs │ │ ├── QueryExtension.cs │ │ └── TopPostsQuery.cs │ ├── Domain.cd │ ├── Domain │ │ ├── Comment.cs │ │ └── Post.cs │ ├── Global.asax │ ├── Global.asax.cs │ ├── Models │ │ └── TopPostModel.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── QueryEncapsulation.Web.csproj │ ├── Views │ │ ├── Home │ │ │ └── Index.cshtml │ │ ├── Shared │ │ │ └── _Layout.cshtml │ │ ├── _ViewStart.cshtml │ │ └── web.config │ ├── Web.Debug.config │ ├── Web.Release.config │ ├── Web.config │ └── packages.config ├── QueryEncapsulation.sln └── packages │ └── repositories.config ├── StructureMapDecorator ├── StructureMapDecorator.Sample │ ├── App.config │ ├── Domain │ │ ├── Product.cs │ │ └── User.cs │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Repositories │ │ ├── IProductRepository.cs │ │ ├── InMemoryProductRepository.cs │ │ ├── ProductRepoLogger.cs │ │ ├── ProductSecurityDecorator.cs │ │ └── RudeProductRepoLogger.cs │ ├── Services │ │ ├── IProductAuthorizer.cs │ │ └── ProductAuthorizer.cs │ ├── StructureMapDecorator.Sample.csproj │ └── packages.config └── StructureMapDecorator.sln ├── angularjs ├── AngularPassingData.sln ├── AngularPassingData │ ├── AngularPassingData.csproj │ ├── App_Start │ │ └── RouteConfig.cs │ ├── Controllers │ │ └── HomeController.cs │ ├── Global.asax │ ├── Global.asax.cs │ ├── Helpers │ │ └── JsonHelpers.cs │ ├── Models │ │ └── PersonViewModel.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Views │ │ ├── Home │ │ │ └── Index.cshtml │ │ ├── Shared │ │ │ └── _Layout.cshtml │ │ ├── _ViewStart.cshtml │ │ └── web.config │ ├── Web.Debug.config │ ├── Web.Release.config │ ├── Web.config │ ├── css │ │ └── custom.css │ ├── js │ │ └── app.js │ └── packages.config └── packages │ └── repositories.config └── identity-with-ioc ├── IdentityWithIoc ├── App_Start │ ├── BundleConfig.cs │ ├── FilterConfig.cs │ ├── IdentityConfig.cs │ ├── RouteConfig.cs │ ├── Startup.Auth.cs │ └── StructureMapConfig.cs ├── Content │ ├── Site.css │ ├── bootstrap.css │ └── bootstrap.min.css ├── Controllers │ ├── AccountController.cs │ ├── HomeController.cs │ └── ManageController.cs ├── Global.asax ├── Global.asax.cs ├── Models │ ├── AccountViewModels.cs │ ├── IdentityModels.cs │ └── ManageViewModels.cs ├── Project_Readme.html ├── Properties │ └── AssemblyInfo.cs ├── Scripts │ ├── _references.js │ ├── bootstrap.js │ ├── bootstrap.min.js │ ├── jquery-1.10.2.intellisense.js │ ├── jquery-1.10.2.js │ ├── jquery-1.10.2.min.js │ ├── jquery-1.10.2.min.map │ ├── jquery.validate-vsdoc.js │ ├── jquery.validate.js │ ├── jquery.validate.min.js │ ├── jquery.validate.unobtrusive.js │ ├── jquery.validate.unobtrusive.min.js │ ├── modernizr-2.6.2.js │ ├── respond.js │ └── respond.min.js ├── Startup.cs ├── Views │ ├── Account │ │ ├── ConfirmEmail.cshtml │ │ ├── ExternalLoginConfirmation.cshtml │ │ ├── ExternalLoginFailure.cshtml │ │ ├── ForgotPassword.cshtml │ │ ├── ForgotPasswordConfirmation.cshtml │ │ ├── Login.cshtml │ │ ├── Register.cshtml │ │ ├── ResetPassword.cshtml │ │ ├── ResetPasswordConfirmation.cshtml │ │ ├── SendCode.cshtml │ │ ├── VerifyCode.cshtml │ │ └── _ExternalLoginsListPartial.cshtml │ ├── Home │ │ ├── About.cshtml │ │ ├── Contact.cshtml │ │ └── Index.cshtml │ ├── Manage │ │ ├── AddPhoneNumber.cshtml │ │ ├── ChangePassword.cshtml │ │ ├── Index.cshtml │ │ ├── ManageLogins.cshtml │ │ ├── SetPassword.cshtml │ │ └── VerifyPhoneNumber.cshtml │ ├── Shared │ │ ├── Error.cshtml │ │ ├── Lockout.cshtml │ │ ├── _Layout.cshtml │ │ └── _LoginPartial.cshtml │ ├── Web.config │ └── _ViewStart.cshtml ├── Web.Debug.config ├── Web.Release.config ├── Web.config ├── favicon.ico ├── fonts │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ └── glyphicons-halflings-regular.woff ├── identity-with-ioc.csproj └── packages.config ├── identity-with-ioc.sln └── packages └── repositories.config /.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* 30 | /**/packages/**/ 31 | *.nupkg 32 | **/App_Data/*.ldf 33 | **/App_Data/*.mdf 34 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/App_Start/AutoMapperConfig.cs: -------------------------------------------------------------------------------- 1 | using Heroic.AutoMapper; 2 | 3 | [assembly: WebActivatorEx.PreApplicationStartMethod(typeof(QueryEncapsulation.Web.AutoMapperConfig), "Configure")] 4 | namespace QueryEncapsulation.Web 5 | { 6 | public static class AutoMapperConfig 7 | { 8 | public static void Configure() 9 | { 10 | //NOTE: By default, the current project and all referenced projects will be scanned. 11 | // You can customize this by passing in a lambda to filter the assemblies by name, 12 | // like so: 13 | //HeroicAutoMapperConfigurator.LoadMapsFromCallerAndReferencedAssemblies(x => x.Name.StartsWith("YourPrefix")); 14 | HeroicAutoMapperConfigurator.LoadMapsFromCallerAndReferencedAssemblies(); 15 | } 16 | } 17 | } -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/App_Start/EFConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Entity; 2 | using QueryEncapsulation.Web.Data; 3 | 4 | namespace QueryEncapsulation.Web 5 | { 6 | public static class EFConfig 7 | { 8 | public static void Initialize() 9 | { 10 | Database.SetInitializer(new DropCreateDatabaseAlways()); 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/App_Start/RouteConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | using System.Web.Routing; 7 | 8 | namespace QueryEncapsulation.Web 9 | { 10 | public class RouteConfig 11 | { 12 | public static void RegisterRoutes(RouteCollection routes) 13 | { 14 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 15 | 16 | routes.MapRoute( 17 | name: "Default", 18 | url: "{controller}/{action}/{id}", 19 | defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 20 | ); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/App_Start/SeedData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using QueryEncapsulation.Web.Data; 4 | using QueryEncapsulation.Web.Domain; 5 | 6 | namespace QueryEncapsulation.Web 7 | { 8 | public static class SeedData 9 | { 10 | public static void Init() 11 | { 12 | using (var context = new AppDbContext()) 13 | { 14 | if (!context.Posts.Any()) 15 | { 16 | context.Posts.Add(new Post{PostDate=DateTime.Parse("6/1/2015"), Title = "New Tech Roundup", Body = "", Comments = {new Comment{Email = "zune@microsoft.com"}, new Comment{Email = "dart@google.com"}}}); 17 | context.Posts.Add(new Post{PostDate=DateTime.Parse("6/2/2015"), Title = "Hipsters, and how to spot them", Body = "", Comments = {new Comment{Email = "clippy@microsoft.com"}, new Comment{Email = "polymer@google.com"}, new Comment{Email = "silverlight@microsoft.com"}}}); 18 | context.Posts.Add(new Post{PostDate=DateTime.Parse("6/3/2015"), Title = "Bug or feature?", Body = "", Comments = {new Comment{Email = "vista@microsoft.com"}, new Comment{Email = "angularjs@google.com"}, new Comment{Email = "vs2015@microsoft.com"}}}); 19 | context.Posts.Add(new Post{PostDate=DateTime.Parse("6/4/2015"), Title = "Hot Tech Features", Body = "", Comments = {new Comment{Email = "aurelia@awesome.com"}, new Comment{Email = "angularjs@google.com"}, new Comment{Email = "ps@sony.com"}}}); 20 | 21 | context.SaveChanges(); 22 | } 23 | } 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/App_Start/StructureMapConfig.cs: -------------------------------------------------------------------------------- 1 | using Heroic.Web.IoC; 2 | using System.Web.Http; 3 | using System.Web.Mvc; 4 | using StructureMap; 5 | using StructureMap.Graph; 6 | 7 | [assembly: WebActivatorEx.PreApplicationStartMethod(typeof(QueryEncapsulation.Web.StructureMapConfig), "Configure")] 8 | namespace QueryEncapsulation.Web 9 | { 10 | public static class StructureMapConfig 11 | { 12 | public static void Configure() 13 | { 14 | ObjectFactory.Configure(cfg => 15 | { 16 | cfg.Scan(scan => 17 | { 18 | scan.TheCallingAssembly(); 19 | scan.WithDefaultConventions(); 20 | }); 21 | 22 | cfg.AddRegistry(new ControllerRegistry()); 23 | cfg.AddRegistry(new MvcRegistry()); 24 | cfg.AddRegistry(new ActionFilterRegistry(namespacePrefix: "QueryEncapsulation.Web")); 25 | 26 | //TODO: Add other registries and configure your container! 27 | }); 28 | 29 | var resolver = new StructureMapDependencyResolver(); 30 | DependencyResolver.SetResolver(resolver); 31 | GlobalConfiguration.Configuration.DependencyResolver = resolver; 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Web.Mvc; 4 | using AutoMapper.QueryableExtensions; 5 | using QueryEncapsulation.Web.Data; 6 | using QueryEncapsulation.Web.Models; 7 | 8 | namespace QueryEncapsulation.Web.Controllers 9 | { 10 | public class HomeController : Controller 11 | { 12 | private readonly AppDbContext _context; 13 | 14 | public HomeController(AppDbContext context) 15 | { 16 | _context = context; 17 | } 18 | 19 | public ActionResult Index() 20 | { 21 | var startDate = DateTime.Parse("6/1/2015"); 22 | var endDate = DateTime.Parse("7/1/2015"); 23 | var topPosts = _context 24 | .Posts.Where(x => x.PostDate >= startDate && x.PostDate < endDate && 25 | x.Comments.Count() >= 3 26 | && x.Comments.Any(c => c.Email.Contains("@microsoft"))) 27 | .Select(x => new TopPostModel 28 | { 29 | Title = x.Title, 30 | PostDate = x.PostDate, 31 | CommentCount = x.Comments.Count(), 32 | MicrosoftPosterAddresses = 33 | x.Comments.Where(c => c.Email.Contains("@microsoft.com")).Select(c => c.Email).ToList() 34 | }) 35 | .ToArray(); 36 | 37 | return View(topPosts); 38 | } 39 | 40 | public ActionResult WithAutoMapper() 41 | { 42 | var startDate = DateTime.Parse("6/1/2015"); 43 | var endDate = DateTime.Parse("7/1/2015"); 44 | var topPosts = _context 45 | .Posts.Where(x => x.PostDate >= startDate && x.PostDate < endDate && 46 | x.Comments.Count() >= 3 47 | && x.Comments.Any(c => c.Email.Contains("@microsoft"))) 48 | .Project().To() 49 | .ToArray(); 50 | 51 | return View("Index", topPosts); 52 | } 53 | 54 | public ActionResult WithSingleExtensionMethod() 55 | { 56 | var startDate = DateTime.Parse("6/1/2015"); 57 | var endDate = DateTime.Parse("7/1/2015"); 58 | var topPosts = _context.Posts 59 | .TopPostsForDateRangeWithMSContributors(startDate, endDate) 60 | .Project().To() 61 | .ToArray(); 62 | 63 | return View("Index", topPosts); 64 | } 65 | 66 | public ActionResult WithComposableExtensionMethod() 67 | { 68 | var startDate = DateTime.Parse("6/1/2015"); 69 | var endDate = DateTime.Parse("7/1/2015"); 70 | var topPosts = _context.Posts 71 | .Between(startDate, endDate) 72 | .WithAtLeastXComments(3) 73 | .WithMicrosoftCommenters() 74 | .Project().To() 75 | .ToArray(); 76 | 77 | return View("Index", topPosts); 78 | } 79 | 80 | public ActionResult WithAQueryObject() 81 | { 82 | var startDate = DateTime.Parse("6/1/2015"); 83 | var endDate = DateTime.Parse("7/1/2015"); 84 | var topPosts = _context.Query().Execute(startDate, endDate); 85 | 86 | return View("Index", topPosts); 87 | } 88 | } 89 | } -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/Data/AppDbContext.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Entity; 2 | using QueryEncapsulation.Web.Domain; 3 | 4 | namespace QueryEncapsulation.Web.Data 5 | { 6 | public class AppDbContext : DbContext 7 | { 8 | public IDbSet Posts { get; set; } 9 | } 10 | } -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/Data/IQuery.cs: -------------------------------------------------------------------------------- 1 | namespace QueryEncapsulation.Web.Data 2 | { 3 | public interface IQuery 4 | { 5 | AppDbContext Context { get; set; } 6 | } 7 | } -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/Data/PostQueryExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using QueryEncapsulation.Web.Domain; 4 | 5 | namespace QueryEncapsulation.Web.Data 6 | { 7 | public static class PostQueryExtensions 8 | { 9 | public static IQueryable TopPostsForDateRangeWithMSContributors( 10 | this IQueryable posts, DateTime startDate, DateTime endDate) 11 | { 12 | return posts.Where(x => x.PostDate >= startDate && x.PostDate < endDate && 13 | x.Comments.Count() >= 3 && 14 | x.Comments.Any(c => c.Email.Contains("@microsoft"))); 15 | } 16 | 17 | public static IQueryable Between(this IQueryable posts, DateTime startDate, DateTime endDate) 18 | { 19 | return posts.Where(x => x.PostDate >= startDate && x.PostDate < endDate); 20 | } 21 | 22 | public static IQueryable WithAtLeastXComments(this IQueryable posts, int commentCount) 23 | { 24 | return posts.Where(x => x.Comments.Count() >= commentCount); 25 | } 26 | 27 | public static IQueryable WithMicrosoftCommenters(this IQueryable posts) 28 | { 29 | return posts.Where(x => x.Comments.Any(c => c.Email.Contains("@microsoft"))); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/Data/QueryExtension.cs: -------------------------------------------------------------------------------- 1 | namespace QueryEncapsulation.Web.Data 2 | { 3 | public static class QueryExtension 4 | { 5 | public static TQuery Query(this AppDbContext context) 6 | where TQuery : IQuery, new() 7 | { 8 | var query = new TQuery(); 9 | query.Context = context; 10 | return query; 11 | } 12 | } 13 | } -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/Data/TopPostsQuery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using AutoMapper.QueryableExtensions; 4 | using QueryEncapsulation.Web.Models; 5 | 6 | namespace QueryEncapsulation.Web.Data 7 | { 8 | public class TopPostsQuery : IQuery 9 | { 10 | public AppDbContext Context { get; set; } 11 | 12 | public TopPostModel[] Execute(DateTime startDate, DateTime endDate) 13 | { 14 | return Context.Posts.Where(x => 15 | x.PostDate >= startDate && 16 | x.PostDate < endDate && 17 | x.Comments.Count() >= 3 && 18 | x.Comments.Any(c => c.Email.Contains("@microsoft"))) 19 | .Project().To() 20 | .ToArray(); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/Domain.cd: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | AAACAAAAACAAAAAAAAABAAAACAAAAAAAAAAAAAAAAAA= 7 | Domain\Comment.cs 8 | 9 | 10 | 11 | 12 | 13 | AAACAAAAAAAAAFAAAAABAAAAAAAAAAAAAAAAAAAAIAA= 14 | Domain\Post.cs 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/Domain/Comment.cs: -------------------------------------------------------------------------------- 1 | namespace QueryEncapsulation.Web.Domain 2 | { 3 | public class Comment 4 | { 5 | public int Id { get; set; } 6 | 7 | public string Email { get; set; } 8 | 9 | public string Body { get; set; } 10 | 11 | public Post Post { get; set; } 12 | } 13 | } -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/Domain/Post.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace QueryEncapsulation.Web.Domain 5 | { 6 | public class Post 7 | { 8 | public int Id { get; set; } 9 | 10 | public string Title { get; set; } 11 | 12 | public DateTime PostDate { get; set; } 13 | 14 | public string Body { get; set; } 15 | 16 | public IList Comments { get; set; } 17 | 18 | public Post() 19 | { 20 | Comments = new List(); 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="QueryEncapsulation.Web.MvcApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/Global.asax.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Mvc; 3 | using System.Web.Routing; 4 | 5 | namespace QueryEncapsulation.Web 6 | { 7 | public class MvcApplication : HttpApplication 8 | { 9 | protected void Application_Start() 10 | { 11 | AreaRegistration.RegisterAllAreas(); 12 | RouteConfig.RegisterRoutes(RouteTable.Routes); 13 | EFConfig.Initialize(); 14 | SeedData.Init(); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/Models/TopPostModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using AutoMapper; 5 | using Heroic.AutoMapper; 6 | using QueryEncapsulation.Web.Domain; 7 | 8 | namespace QueryEncapsulation.Web.Models 9 | { 10 | public class TopPostModel : IMapFrom, IHaveCustomMappings 11 | { 12 | public string Title { get; set; } 13 | 14 | public DateTime PostDate { get; set; } 15 | 16 | public int CommentCount { get; set; } 17 | 18 | public IList MicrosoftPosterAddresses { get; set; } 19 | 20 | public void CreateMappings(IConfiguration configuration) 21 | { 22 | configuration.CreateMap() 23 | .ForMember(x => x.CommentCount, opt => opt.MapFrom(x => x.Comments.Count())) 24 | .ForMember(x => x.MicrosoftPosterAddresses, opt => MapFromMicrosoftPosters(opt)); 25 | } 26 | 27 | private void MapFromMicrosoftPosters(IMemberConfigurationExpression opt) 28 | { 29 | opt.MapFrom(x => x.Comments.Where(c => c.Email.Contains("@microsoft.com")).Select(c => c.Email)); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/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("QueryEncapsulation.Web")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("QueryEncapsulation.Web")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 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("ea82dbb9-95e8-414d-8e10-2e054b488165")] 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 | -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/QueryEncapsulation.Web.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | 8 | 9 | 2.0 10 | {2CE863CF-B6E0-423A-8B4E-BD98C125E75E} 11 | {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} 12 | Library 13 | Properties 14 | QueryEncapsulation.Web 15 | QueryEncapsulation.Web 16 | v4.5.1 17 | true 18 | 19 | 20 | 21 | 22 | 23 | 24 | true 25 | full 26 | false 27 | bin\ 28 | DEBUG;TRACE 29 | prompt 30 | 4 31 | 32 | 33 | pdbonly 34 | true 35 | bin\ 36 | TRACE 37 | prompt 38 | 4 39 | 40 | 41 | 42 | ..\packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll 43 | True 44 | 45 | 46 | ..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.dll 47 | True 48 | 49 | 50 | ..\packages\AutoMapper.3.3.1\lib\net40\AutoMapper.Net4.dll 51 | True 52 | 53 | 54 | ..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.dll 55 | True 56 | 57 | 58 | ..\packages\EntityFramework.6.1.3\lib\net45\EntityFramework.SqlServer.dll 59 | True 60 | 61 | 62 | ..\packages\Heroic.AutoMapper.1.0.0-alpha02\lib\net45\Heroic.AutoMapper.dll 63 | True 64 | 65 | 66 | ..\packages\Heroic.Web.IoC.2.3.0\lib\net45\Heroic.Web.IoC.dll 67 | True 68 | 69 | 70 | 71 | ..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll 72 | True 73 | 74 | 75 | ..\packages\structuremap.3.1.5.154\lib\net40\StructureMap.dll 76 | True 77 | 78 | 79 | ..\packages\structuremap.3.1.5.154\lib\net40\StructureMap.Net4.dll 80 | True 81 | 82 | 83 | 84 | ..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll 85 | True 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll 98 | True 99 | 100 | 101 | ..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll 102 | True 103 | 104 | 105 | ..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll 106 | True 107 | 108 | 109 | ..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll 110 | True 111 | 112 | 113 | ..\packages\Microsoft.AspNet.Web.Optimization.1.1.3\lib\net40\System.Web.Optimization.dll 114 | True 115 | 116 | 117 | ..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll 118 | True 119 | 120 | 121 | ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll 122 | True 123 | 124 | 125 | ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll 126 | True 127 | 128 | 129 | ..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll 130 | True 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | ..\packages\WebActivatorEx.2.0.6\lib\net40\WebActivatorEx.dll 141 | True 142 | 143 | 144 | ..\packages\WebGrease.1.6.0\lib\WebGrease.dll 145 | True 146 | 147 | 148 | 149 | 150 | ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | Global.asax 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | Web.config 186 | 187 | 188 | Web.config 189 | 190 | 191 | 192 | 193 | 194 | 195 | 10.0 196 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | True 206 | True 207 | 50723 208 | / 209 | http://localhost:50723/ 210 | False 211 | False 212 | 213 | 214 | False 215 | 216 | 217 | 218 | 219 | 220 | 227 | -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @model QueryEncapsulation.Web.Models.TopPostModel[] 2 | 3 | @{ 4 | ViewBag.Title = "Home"; 5 | } 6 | 7 |

Top Posts

8 |

The output below will be the same regardless of which query method you choose. :)

9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | @foreach (var post in Model) 20 | { 21 | 22 | 23 | 24 | 25 | 26 | 27 | } 28 | 29 |
TitlePost DateNumber of CommentsMicrosoft Posters
@post.Title@post.PostDate.ToShortDateString()@post.CommentCount@string.Join(", ", post.MicrosoftPosterAddresses)
-------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 | @using System.Web.Mvc.Html 2 | 3 | 4 | 5 | 6 | 7 | @ViewBag.Title 8 | 9 | 10 | 15 | 16 | 17 | 39 |
40 | @RenderBody() 41 |
42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "~/Views/Shared/_Layout.cshtml"; 3 | } 4 | -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/Views/web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 |
7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/Web.Debug.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/Web.Release.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/Web.config: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 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 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.Web/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /QueryEncapsulation/QueryEncapsulation.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "QueryEncapsulation.Web", "QueryEncapsulation.Web\QueryEncapsulation.Web.csproj", "{2CE863CF-B6E0-423A-8B4E-BD98C125E75E}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {2CE863CF-B6E0-423A-8B4E-BD98C125E75E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {2CE863CF-B6E0-423A-8B4E-BD98C125E75E}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {2CE863CF-B6E0-423A-8B4E-BD98C125E75E}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {2CE863CF-B6E0-423A-8B4E-BD98C125E75E}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /QueryEncapsulation/packages/repositories.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /StructureMapDecorator/StructureMapDecorator.Sample/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /StructureMapDecorator/StructureMapDecorator.Sample/Domain/Product.cs: -------------------------------------------------------------------------------- 1 | namespace StructureMapDecorator.Sample.Domain 2 | { 3 | public class Product 4 | { 5 | public int ID { get; set; } 6 | 7 | public override string ToString() 8 | { 9 | return "Product " + ID; 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /StructureMapDecorator/StructureMapDecorator.Sample/Domain/User.cs: -------------------------------------------------------------------------------- 1 | namespace StructureMapDecorator.Sample.Domain 2 | { 3 | public class User 4 | { 5 | public string UserName { get; set; } 6 | 7 | public override string ToString() 8 | { 9 | return UserName; 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /StructureMapDecorator/StructureMapDecorator.Sample/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using StructureMap; 3 | using StructureMapDecorator.Sample.Domain; 4 | using StructureMapDecorator.Sample.Repositories; 5 | using StructureMapDecorator.Sample.Services; 6 | 7 | namespace StructureMapDecorator.Sample 8 | { 9 | class Program 10 | { 11 | static void Main(string[] args) 12 | { 13 | User currentUser = GetCurrentUser(); 14 | 15 | var container = new Container(cfg => 16 | { 17 | cfg.For().Use(currentUser); 18 | cfg.For().Use(); 19 | cfg.For().DecorateAllWith(); 20 | cfg.For().DecorateAllWith(); 21 | cfg.For().DecorateAllWith(); 22 | cfg.For().Use(); 23 | }); 24 | 25 | var repo = container.GetInstance(); 26 | 27 | var product = repo.Find(1); 28 | 29 | Console.WriteLine(product); 30 | } 31 | 32 | private static User GetCurrentUser() 33 | { 34 | return new User {UserName = "Admin"}; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /StructureMapDecorator/StructureMapDecorator.Sample/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("TryCatchFail.LearnStructureMap.Lesson4")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("TryCatchFail.LearnStructureMap.Lesson4")] 13 | [assembly: AssemblyCopyright("Copyright © 2012")] 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("ad530c38-ba96-4f35-ac8a-7cc4b1a2d448")] 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 Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /StructureMapDecorator/StructureMapDecorator.Sample/Repositories/IProductRepository.cs: -------------------------------------------------------------------------------- 1 | using StructureMapDecorator.Sample.Domain; 2 | 3 | namespace StructureMapDecorator.Sample.Repositories 4 | { 5 | public interface IProductRepository 6 | { 7 | Product Find(int id); 8 | } 9 | } -------------------------------------------------------------------------------- /StructureMapDecorator/StructureMapDecorator.Sample/Repositories/InMemoryProductRepository.cs: -------------------------------------------------------------------------------- 1 | using StructureMapDecorator.Sample.Domain; 2 | 3 | namespace StructureMapDecorator.Sample.Repositories 4 | { 5 | public class InMemoryProductRepository : IProductRepository 6 | { 7 | public Product Find(int id) 8 | { 9 | return new Product { ID = id }; 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /StructureMapDecorator/StructureMapDecorator.Sample/Repositories/ProductRepoLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using StructureMapDecorator.Sample.Domain; 3 | 4 | namespace StructureMapDecorator.Sample.Repositories 5 | { 6 | public class ProductRepoLogger : IProductRepository 7 | { 8 | private readonly IProductRepository _target; 9 | private readonly User _user; 10 | 11 | public ProductRepoLogger(IProductRepository target, User user) 12 | { 13 | _target = target; 14 | _user = user; 15 | } 16 | 17 | public Product Find(int id) 18 | { 19 | Console.WriteLine("{0} is requesting product {1}.", _user, id); 20 | 21 | return _target.Find(id); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /StructureMapDecorator/StructureMapDecorator.Sample/Repositories/ProductSecurityDecorator.cs: -------------------------------------------------------------------------------- 1 | using System.Security; 2 | using StructureMapDecorator.Sample.Domain; 3 | using StructureMapDecorator.Sample.Services; 4 | 5 | namespace StructureMapDecorator.Sample.Repositories 6 | { 7 | public class ProductSecurityDecorator : IProductRepository 8 | { 9 | private readonly IProductRepository _target; 10 | private readonly IProductAuthorizer _securityService; 11 | private readonly User _currentUser; 12 | 13 | public ProductSecurityDecorator(IProductRepository target, IProductAuthorizer securityService, User currentUser) 14 | { 15 | _target = target; 16 | _securityService = securityService; 17 | _currentUser = currentUser; 18 | } 19 | 20 | public Product Find(int id) 21 | { 22 | if (_securityService.IsUserAuthorizedToAccessProduct(_currentUser, id)) 23 | { 24 | return _target.Find(id); 25 | } 26 | else 27 | { 28 | throw new SecurityException("You are not authorized to access this product!"); 29 | } 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /StructureMapDecorator/StructureMapDecorator.Sample/Repositories/RudeProductRepoLogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using StructureMapDecorator.Sample.Domain; 3 | 4 | namespace StructureMapDecorator.Sample.Repositories 5 | { 6 | public class RudeProductRepoLogger : IProductRepository 7 | { 8 | private readonly IProductRepository _target; 9 | 10 | public RudeProductRepoLogger(IProductRepository target) 11 | { 12 | _target = target; 13 | } 14 | 15 | public Product Find(int id) 16 | { 17 | Console.WriteLine("Hey there, jerk."); 18 | 19 | return _target.Find(id); 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /StructureMapDecorator/StructureMapDecorator.Sample/Services/IProductAuthorizer.cs: -------------------------------------------------------------------------------- 1 | using StructureMapDecorator.Sample.Domain; 2 | 3 | namespace StructureMapDecorator.Sample.Services 4 | { 5 | public interface IProductAuthorizer 6 | { 7 | bool IsUserAuthorizedToAccessProduct(User user, int productID); 8 | } 9 | } -------------------------------------------------------------------------------- /StructureMapDecorator/StructureMapDecorator.Sample/Services/ProductAuthorizer.cs: -------------------------------------------------------------------------------- 1 | using StructureMapDecorator.Sample.Domain; 2 | 3 | namespace StructureMapDecorator.Sample.Services 4 | { 5 | public class ProductAuthorizer : IProductAuthorizer 6 | { 7 | public bool IsUserAuthorizedToAccessProduct(User user, int productID) 8 | { 9 | if (user.UserName == "Admin") 10 | { 11 | return true; 12 | } 13 | else 14 | { 15 | return false; 16 | } 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /StructureMapDecorator/StructureMapDecorator.Sample/StructureMapDecorator.Sample.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {237DE06A-CF7C-4B6B-B1FD-A1D64FA5567C} 8 | Exe 9 | Properties 10 | StructureMapDecorator.Sample 11 | StructureMapDecorator.Sample 12 | v4.5.2 13 | 512 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | ..\packages\structuremap.3.1.5.154\lib\net40\StructureMap.dll 38 | True 39 | 40 | 41 | ..\packages\structuremap.3.1.5.154\lib\net40\StructureMap.Net4.dll 42 | True 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 | 77 | -------------------------------------------------------------------------------- /StructureMapDecorator/StructureMapDecorator.Sample/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /StructureMapDecorator/StructureMapDecorator.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.22823.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StructureMapDecorator.Sample", "StructureMapDecorator.Sample\StructureMapDecorator.Sample.csproj", "{237DE06A-CF7C-4B6B-B1FD-A1D64FA5567C}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {237DE06A-CF7C-4B6B-B1FD-A1D64FA5567C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {237DE06A-CF7C-4B6B-B1FD-A1D64FA5567C}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {237DE06A-CF7C-4B6B-B1FD-A1D64FA5567C}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {237DE06A-CF7C-4B6B-B1FD-A1D64FA5567C}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /angularjs/AngularPassingData.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AngularPassingData", "AngularPassingData\AngularPassingData.csproj", "{DD4CB01B-551F-492A-8994-724E2322F256}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {DD4CB01B-551F-492A-8994-724E2322F256}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {DD4CB01B-551F-492A-8994-724E2322F256}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {DD4CB01B-551F-492A-8994-724E2322F256}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {DD4CB01B-551F-492A-8994-724E2322F256}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /angularjs/AngularPassingData/AngularPassingData.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | 8 | 9 | 2.0 10 | {DD4CB01B-551F-492A-8994-724E2322F256} 11 | {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} 12 | Library 13 | Properties 14 | AngularPassingData 15 | AngularPassingData 16 | v4.5.1 17 | true 18 | 19 | 20 | 21 | 22 | 23 | 24 | true 25 | full 26 | false 27 | bin\ 28 | DEBUG;TRACE 29 | prompt 30 | 4 31 | 32 | 33 | pdbonly 34 | true 35 | bin\ 36 | TRACE 37 | prompt 38 | 4 39 | 40 | 41 | 42 | 43 | False 44 | ..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | ..\packages\Microsoft.AspNet.Razor.3.2.2\lib\net45\System.Web.Razor.dll 66 | 67 | 68 | ..\packages\Microsoft.AspNet.Webpages.3.2.2\lib\net45\System.Web.Webpages.dll 69 | 70 | 71 | ..\packages\Microsoft.AspNet.Webpages.3.2.2\lib\net45\System.Web.Webpages.Deployment.dll 72 | 73 | 74 | ..\packages\Microsoft.AspNet.Webpages.3.2.2\lib\net45\System.Web.Webpages.Razor.dll 75 | 76 | 77 | ..\packages\Microsoft.AspNet.Webpages.3.2.2\lib\net45\System.Web.Helpers.dll 78 | 79 | 80 | ..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll 81 | 82 | 83 | ..\packages\Microsoft.AspNet.Mvc.5.2.2\lib\net45\System.Web.Mvc.dll 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | Global.asax 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | Web.config 110 | 111 | 112 | Web.config 113 | 114 | 115 | 116 | 117 | 118 | 119 | 10.0 120 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | True 130 | True 131 | 59542 132 | / 133 | http://localhost:59430/ 134 | False 135 | False 136 | 137 | 138 | False 139 | 140 | 141 | 142 | 143 | 150 | -------------------------------------------------------------------------------- /angularjs/AngularPassingData/App_Start/RouteConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | using System.Web.Routing; 7 | 8 | namespace AngularPassingData 9 | { 10 | public class RouteConfig 11 | { 12 | public static void RegisterRoutes(RouteCollection routes) 13 | { 14 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 15 | 16 | routes.MapRoute( 17 | name: "Default", 18 | url: "{controller}/{action}/{id}", 19 | defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 20 | ); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /angularjs/AngularPassingData/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | using AngularPassingData.Models; 3 | 4 | namespace AngularPassingData.Controllers 5 | { 6 | public class HomeController : Controller 7 | { 8 | public ActionResult Index() 9 | { 10 | var models = new[] 11 | { 12 | new PersonViewModel 13 | { 14 | Name = "Aragorn", 15 | Occupation = "King of Gondor", 16 | Age = 87 17 | }, 18 | new PersonViewModel 19 | { 20 | Name = "Legolas", 21 | Occupation = "Elf with a Bow", 22 | Age = 2931 23 | }, 24 | new PersonViewModel 25 | { 26 | Name = "Bilbo Baggins", 27 | Occupation = "Burglar", 28 | Age = 111 29 | }, 30 | }; 31 | 32 | return View(models); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /angularjs/AngularPassingData/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="AngularPassingData.MvcApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /angularjs/AngularPassingData/Global.asax.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | using System.Web.Routing; 7 | 8 | namespace AngularPassingData 9 | { 10 | public class MvcApplication : System.Web.HttpApplication 11 | { 12 | protected void Application_Start() 13 | { 14 | AreaRegistration.RegisterAllAreas(); 15 | RouteConfig.RegisterRoutes(RouteTable.Routes); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /angularjs/AngularPassingData/Helpers/JsonHelpers.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Mvc; 3 | using Newtonsoft.Json; 4 | using Newtonsoft.Json.Serialization; 5 | 6 | namespace AngularPassingData.Helpers 7 | { 8 | public static class JsonHelpers 9 | { 10 | public static IHtmlString ToJson(this T obj) 11 | { 12 | var settings = new JsonSerializerSettings 13 | { 14 | ContractResolver = new CamelCasePropertyNamesContractResolver() 15 | }; 16 | return MvcHtmlString.Create(JsonConvert.SerializeObject(obj, settings)); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /angularjs/AngularPassingData/Models/PersonViewModel.cs: -------------------------------------------------------------------------------- 1 | namespace AngularPassingData.Models 2 | { 3 | public class PersonViewModel 4 | { 5 | public string Name { get; set; } 6 | public string Occupation { get; set; } 7 | public int Age { get; set; } 8 | } 9 | } -------------------------------------------------------------------------------- /angularjs/AngularPassingData/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("AngularPassingData")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("AngularPassingData")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 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("fecc373f-1e51-468f-900e-da476cfa7a87")] 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 | -------------------------------------------------------------------------------- /angularjs/AngularPassingData/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @using AngularPassingData.Helpers 2 | @model AngularPassingData.Models.PersonViewModel[] 3 | 4 |

Sample: Passing Data to AngularJS!

5 | 6 |
7 | This sample demonstrates a couple of ways that you can pass data from Razor to AngularJS. For more information, 8 | see this post at try-catch-FAIL. 9 |
10 | 11 |
12 |
13 |

Option 1: Using ngInit

14 |
15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
NameOccupationAge
{{person.name}}{{person.occupation}}{{person.age}}
32 |
33 |
34 | 35 |
36 |
37 |

Option 2: Using a Value Provider (Locally)

38 |
39 |
40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 |
NameOccupationAge
{{person.name}}{{person.occupation}}{{person.age}}
56 |
57 |
58 | 59 | @section Scripts { 60 | 63 | } 64 | 65 |
66 |
67 |

Option 3: Using a Value Provider (Globally)

68 |
69 |
70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 |
NameOccupationAge
{{person.name}}{{person.occupation}}{{person.age}}
86 |
87 |
-------------------------------------------------------------------------------- /angularjs/AngularPassingData/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 | @using AngularPassingData.Helpers 2 | 3 | 4 | 5 | 6 | 7 | AngularJS - Passing Data Sample - Matt Honeycutt 8 | 9 | 10 | 11 | 12 | 13 |
14 | @RenderBody() 15 |
16 | 22 | 23 | 24 | 25 | 26 | @RenderSection("Scripts", required: false) 27 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /angularjs/AngularPassingData/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "~/Views/Shared/_Layout.cshtml"; 3 | } 4 | -------------------------------------------------------------------------------- /angularjs/AngularPassingData/Views/web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 |
7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /angularjs/AngularPassingData/Web.Debug.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /angularjs/AngularPassingData/Web.Release.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | -------------------------------------------------------------------------------- /angularjs/AngularPassingData/Web.config: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 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 | -------------------------------------------------------------------------------- /angularjs/AngularPassingData/css/custom.css: -------------------------------------------------------------------------------- 1 | /* Sticky footer styles 2 | -------------------------------------------------- */ 3 | html { 4 | position: relative; 5 | min-height: 100%; 6 | } 7 | 8 | body { 9 | /* Margin bottom by footer height */ 10 | margin-bottom: 60px; 11 | } 12 | 13 | .footer { 14 | position: absolute; 15 | text-align: center; 16 | bottom: 0; 17 | width: 100%; 18 | /* Set the fixed height of the footer here */ 19 | height: 60px; 20 | padding-top: 1em; 21 | background-color: #4e5d6c; 22 | } 23 | -------------------------------------------------------------------------------- /angularjs/AngularPassingData/js/app.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | window.app = angular.module('sampleApp', []); 3 | 4 | window.app.controller('NgInitSampleController', [NgInitSampleController]); 5 | function NgInitSampleController() { 6 | var vm = this; 7 | vm.people = []; 8 | 9 | vm.init = init; 10 | 11 | function init(people) { 12 | vm.people = people; 13 | } 14 | } 15 | 16 | window.app.controller('LocalValueProviderController', ['peopleData', LocalValueProviderController]); 17 | function LocalValueProviderController(peopleData) { 18 | var vm = this; 19 | vm.people = peopleData; 20 | } 21 | 22 | window.app.controller('GlobalValueProviderController', ['model', GlobalValueProviderController]); 23 | function GlobalValueProviderController(model) { 24 | var vm = this; 25 | vm.people = model; 26 | } 27 | })(); -------------------------------------------------------------------------------- /angularjs/AngularPassingData/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /angularjs/packages/repositories.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/App_Start/BundleConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Optimization; 3 | 4 | namespace identity_with_ioc 5 | { 6 | public class BundleConfig 7 | { 8 | // For more information on bundling, visit http://go.microsoft.com/fwlink/?LinkId=301862 9 | public static void RegisterBundles(BundleCollection bundles) 10 | { 11 | bundles.Add(new ScriptBundle("~/bundles/jquery").Include( 12 | "~/Scripts/jquery-{version}.js")); 13 | 14 | bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include( 15 | "~/Scripts/jquery.validate*")); 16 | 17 | // Use the development version of Modernizr to develop with and learn from. Then, when you're 18 | // ready for production, use the build tool at http://modernizr.com to pick only the tests you need. 19 | bundles.Add(new ScriptBundle("~/bundles/modernizr").Include( 20 | "~/Scripts/modernizr-*")); 21 | 22 | bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include( 23 | "~/Scripts/bootstrap.js", 24 | "~/Scripts/respond.js")); 25 | 26 | bundles.Add(new StyleBundle("~/Content/css").Include( 27 | "~/Content/bootstrap.css", 28 | "~/Content/site.css")); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/App_Start/FilterConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using System.Web.Mvc; 3 | 4 | namespace identity_with_ioc 5 | { 6 | public class FilterConfig 7 | { 8 | public static void RegisterGlobalFilters(GlobalFilterCollection filters) 9 | { 10 | filters.Add(new HandleErrorAttribute()); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/App_Start/IdentityConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data.Entity; 4 | using System.Linq; 5 | using System.Security.Claims; 6 | using System.Threading.Tasks; 7 | using System.Web; 8 | using Microsoft.AspNet.Identity; 9 | using Microsoft.AspNet.Identity.EntityFramework; 10 | using Microsoft.AspNet.Identity.Owin; 11 | using Microsoft.Owin; 12 | using Microsoft.Owin.Security; 13 | using identity_with_ioc.Models; 14 | 15 | namespace identity_with_ioc 16 | { 17 | public class EmailService : IIdentityMessageService 18 | { 19 | public Task SendAsync(IdentityMessage message) 20 | { 21 | // Plug in your email service here to send an email. 22 | return Task.FromResult(0); 23 | } 24 | } 25 | 26 | public class SmsService : IIdentityMessageService 27 | { 28 | public Task SendAsync(IdentityMessage message) 29 | { 30 | // Plug in your SMS service here to send a text message. 31 | return Task.FromResult(0); 32 | } 33 | } 34 | 35 | // Configure the application user manager used in this application. UserManager is defined in ASP.NET Identity and is used by the application. 36 | public class ApplicationUserManager : UserManager 37 | { 38 | public ApplicationUserManager(IUserStore store) 39 | : base(store) 40 | { 41 | } 42 | 43 | public static ApplicationUserManager Create(IdentityFactoryOptions options, IOwinContext context) 44 | { 45 | var manager = new ApplicationUserManager(new UserStore(context.Get())); 46 | // Configure validation logic for usernames 47 | manager.UserValidator = new UserValidator(manager) 48 | { 49 | AllowOnlyAlphanumericUserNames = false, 50 | RequireUniqueEmail = true 51 | }; 52 | 53 | // Configure validation logic for passwords 54 | manager.PasswordValidator = new PasswordValidator 55 | { 56 | RequiredLength = 6, 57 | RequireNonLetterOrDigit = true, 58 | RequireDigit = true, 59 | RequireLowercase = true, 60 | RequireUppercase = true, 61 | }; 62 | 63 | // Configure user lockout defaults 64 | manager.UserLockoutEnabledByDefault = true; 65 | manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5); 66 | manager.MaxFailedAccessAttemptsBeforeLockout = 5; 67 | 68 | // Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user 69 | // You can write your own provider and plug it in here. 70 | manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider 71 | { 72 | MessageFormat = "Your security code is {0}" 73 | }); 74 | manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider 75 | { 76 | Subject = "Security Code", 77 | BodyFormat = "Your security code is {0}" 78 | }); 79 | manager.EmailService = new EmailService(); 80 | manager.SmsService = new SmsService(); 81 | var dataProtectionProvider = options.DataProtectionProvider; 82 | if (dataProtectionProvider != null) 83 | { 84 | manager.UserTokenProvider = 85 | new DataProtectorTokenProvider(dataProtectionProvider.Create("ASP.NET Identity")); 86 | } 87 | return manager; 88 | } 89 | } 90 | 91 | // Configure the application sign-in manager which is used in this application. 92 | public class ApplicationSignInManager : SignInManager 93 | { 94 | public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager) 95 | : base(userManager, authenticationManager) 96 | { 97 | } 98 | 99 | public override Task CreateUserIdentityAsync(ApplicationUser user) 100 | { 101 | return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager); 102 | } 103 | 104 | public static ApplicationSignInManager Create(IdentityFactoryOptions options, IOwinContext context) 105 | { 106 | return new ApplicationSignInManager(context.GetUserManager(), context.Authentication); 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/App_Start/RouteConfig.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | using System.Web.Routing; 7 | 8 | namespace identity_with_ioc 9 | { 10 | public class RouteConfig 11 | { 12 | public static void RegisterRoutes(RouteCollection routes) 13 | { 14 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 15 | 16 | routes.MapRoute( 17 | name: "Default", 18 | url: "{controller}/{action}/{id}", 19 | defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } 20 | ); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/App_Start/Startup.Auth.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.AspNet.Identity; 3 | using Microsoft.AspNet.Identity.Owin; 4 | using Microsoft.Owin; 5 | using Microsoft.Owin.Security.Cookies; 6 | using Microsoft.Owin.Security.Google; 7 | using Owin; 8 | using identity_with_ioc.Models; 9 | 10 | namespace identity_with_ioc 11 | { 12 | public partial class Startup 13 | { 14 | // For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864 15 | public void ConfigureAuth(IAppBuilder app) 16 | { 17 | // Configure the db context, user manager and signin manager to use a single instance per request 18 | app.CreatePerOwinContext(ApplicationDbContext.Create); 19 | app.CreatePerOwinContext(ApplicationUserManager.Create); 20 | app.CreatePerOwinContext(ApplicationSignInManager.Create); 21 | 22 | // Enable the application to use a cookie to store information for the signed in user 23 | // and to use a cookie to temporarily store information about a user logging in with a third party login provider 24 | // Configure the sign in cookie 25 | app.UseCookieAuthentication(new CookieAuthenticationOptions 26 | { 27 | AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie, 28 | LoginPath = new PathString("/Account/Login"), 29 | Provider = new CookieAuthenticationProvider 30 | { 31 | // Enables the application to validate the security stamp when the user logs in. 32 | // This is a security feature which is used when you change a password or add an external login to your account. 33 | OnValidateIdentity = SecurityStampValidator.OnValidateIdentity( 34 | validateInterval: TimeSpan.FromMinutes(30), 35 | regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager)) 36 | } 37 | }); 38 | app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie); 39 | 40 | // Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process. 41 | app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie, TimeSpan.FromMinutes(5)); 42 | 43 | // Enables the application to remember the second login verification factor such as phone or email. 44 | // Once you check this option, your second step of verification during the login process will be remembered on the device where you logged in from. 45 | // This is similar to the RememberMe option when you log in. 46 | app.UseTwoFactorRememberBrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberBrowserCookie); 47 | 48 | // Uncomment the following lines to enable logging in with third party login providers 49 | //app.UseMicrosoftAccountAuthentication( 50 | // clientId: "", 51 | // clientSecret: ""); 52 | 53 | //app.UseTwitterAuthentication( 54 | // consumerKey: "", 55 | // consumerSecret: ""); 56 | 57 | //app.UseFacebookAuthentication( 58 | // appId: "", 59 | // appSecret: ""); 60 | 61 | //app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions() 62 | //{ 63 | // ClientId = "", 64 | // ClientSecret = "" 65 | //}); 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/App_Start/StructureMapConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Entity; 2 | using System.Web; 3 | using Heroic.Web.IoC; 4 | using System.Web.Http; 5 | using System.Web.Mvc; 6 | using identity_with_ioc.Models; 7 | using Microsoft.AspNet.Identity; 8 | using Microsoft.AspNet.Identity.EntityFramework; 9 | using Microsoft.Owin.Security; 10 | using Microsoft.AspNet.Identity.Owin; 11 | using StructureMap; 12 | using StructureMap.Graph; 13 | 14 | [assembly: WebActivatorEx.PreApplicationStartMethod(typeof(identity_with_ioc.StructureMapConfig), "Configure")] 15 | namespace identity_with_ioc 16 | { 17 | public static class StructureMapConfig 18 | { 19 | public static void Configure() 20 | { 21 | ObjectFactory.Configure(cfg => 22 | { 23 | cfg.Scan(scan => 24 | { 25 | scan.TheCallingAssembly(); 26 | scan.WithDefaultConventions(); 27 | }); 28 | 29 | cfg.AddRegistry(new ControllerRegistry()); 30 | cfg.AddRegistry(new MvcRegistry()); 31 | cfg.AddRegistry(new ActionFilterRegistry(namespacePrefix: "identity_with_ioc")); 32 | 33 | //TODO: Add other registries and configure your container! 34 | cfg.For().Use(ctx => 35 | ctx.GetInstance().GetOwinContext().Get()); 36 | cfg.For().Use(ctx => 37 | ctx.GetInstance().GetOwinContext().GetUserManager()); 38 | }); 39 | 40 | var resolver = new StructureMapDependencyResolver(); 41 | DependencyResolver.SetResolver(resolver); 42 | GlobalConfiguration.Configuration.DependencyResolver = resolver; 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Content/Site.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding-top: 50px; 3 | padding-bottom: 20px; 4 | } 5 | 6 | /* Set padding to keep content from hitting the edges */ 7 | .body-content { 8 | padding-left: 15px; 9 | padding-right: 15px; 10 | } 11 | 12 | /* Override the default bootstrap behavior where horizontal description lists 13 | will truncate terms that are too long to fit in the left column 14 | */ 15 | .dl-horizontal dt { 16 | white-space: normal; 17 | } 18 | 19 | /* Set width on the form input elements since they're 100% wide by default */ 20 | input, 21 | select, 22 | textarea { 23 | max-width: 280px; 24 | } 25 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | 7 | namespace identity_with_ioc.Controllers 8 | { 9 | public class HomeController : Controller 10 | { 11 | public ActionResult Index() 12 | { 13 | return View(); 14 | } 15 | 16 | public ActionResult About() 17 | { 18 | ViewBag.Message = "Your application description page."; 19 | 20 | return View(); 21 | } 22 | 23 | public ActionResult Contact() 24 | { 25 | ViewBag.Message = "Your contact page."; 26 | 27 | return View(); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Controllers/ManageController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Threading.Tasks; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | using Microsoft.AspNet.Identity; 7 | using Microsoft.AspNet.Identity.Owin; 8 | using Microsoft.Owin.Security; 9 | using identity_with_ioc.Models; 10 | 11 | namespace identity_with_ioc.Controllers 12 | { 13 | [Authorize] 14 | public class ManageController : Controller 15 | { 16 | private ApplicationSignInManager _signInManager; 17 | private ApplicationUserManager _userManager; 18 | 19 | public ManageController() 20 | { 21 | } 22 | 23 | public ManageController(ApplicationUserManager userManager, ApplicationSignInManager signInManager) 24 | { 25 | UserManager = userManager; 26 | SignInManager = signInManager; 27 | } 28 | 29 | public ApplicationSignInManager SignInManager 30 | { 31 | get 32 | { 33 | return _signInManager ?? HttpContext.GetOwinContext().Get(); 34 | } 35 | private set 36 | { 37 | _signInManager = value; 38 | } 39 | } 40 | 41 | public ApplicationUserManager UserManager 42 | { 43 | get 44 | { 45 | return _userManager ?? HttpContext.GetOwinContext().GetUserManager(); 46 | } 47 | private set 48 | { 49 | _userManager = value; 50 | } 51 | } 52 | 53 | // 54 | // GET: /Manage/Index 55 | public async Task Index(ManageMessageId? message) 56 | { 57 | ViewBag.StatusMessage = 58 | message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed." 59 | : message == ManageMessageId.SetPasswordSuccess ? "Your password has been set." 60 | : message == ManageMessageId.SetTwoFactorSuccess ? "Your two-factor authentication provider has been set." 61 | : message == ManageMessageId.Error ? "An error has occurred." 62 | : message == ManageMessageId.AddPhoneSuccess ? "Your phone number was added." 63 | : message == ManageMessageId.RemovePhoneSuccess ? "Your phone number was removed." 64 | : ""; 65 | 66 | var userId = User.Identity.GetUserId(); 67 | var model = new IndexViewModel 68 | { 69 | HasPassword = HasPassword(), 70 | PhoneNumber = await UserManager.GetPhoneNumberAsync(userId), 71 | TwoFactor = await UserManager.GetTwoFactorEnabledAsync(userId), 72 | Logins = await UserManager.GetLoginsAsync(userId), 73 | BrowserRemembered = await AuthenticationManager.TwoFactorBrowserRememberedAsync(userId) 74 | }; 75 | return View(model); 76 | } 77 | 78 | // 79 | // POST: /Manage/RemoveLogin 80 | [HttpPost] 81 | [ValidateAntiForgeryToken] 82 | public async Task RemoveLogin(string loginProvider, string providerKey) 83 | { 84 | ManageMessageId? message; 85 | var result = await UserManager.RemoveLoginAsync(User.Identity.GetUserId(), new UserLoginInfo(loginProvider, providerKey)); 86 | if (result.Succeeded) 87 | { 88 | var user = await UserManager.FindByIdAsync(User.Identity.GetUserId()); 89 | if (user != null) 90 | { 91 | await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); 92 | } 93 | message = ManageMessageId.RemoveLoginSuccess; 94 | } 95 | else 96 | { 97 | message = ManageMessageId.Error; 98 | } 99 | return RedirectToAction("ManageLogins", new { Message = message }); 100 | } 101 | 102 | // 103 | // GET: /Manage/AddPhoneNumber 104 | public ActionResult AddPhoneNumber() 105 | { 106 | return View(); 107 | } 108 | 109 | // 110 | // POST: /Manage/AddPhoneNumber 111 | [HttpPost] 112 | [ValidateAntiForgeryToken] 113 | public async Task AddPhoneNumber(AddPhoneNumberViewModel model) 114 | { 115 | if (!ModelState.IsValid) 116 | { 117 | return View(model); 118 | } 119 | // Generate the token and send it 120 | var code = await UserManager.GenerateChangePhoneNumberTokenAsync(User.Identity.GetUserId(), model.Number); 121 | if (UserManager.SmsService != null) 122 | { 123 | var message = new IdentityMessage 124 | { 125 | Destination = model.Number, 126 | Body = "Your security code is: " + code 127 | }; 128 | await UserManager.SmsService.SendAsync(message); 129 | } 130 | return RedirectToAction("VerifyPhoneNumber", new { PhoneNumber = model.Number }); 131 | } 132 | 133 | // 134 | // POST: /Manage/EnableTwoFactorAuthentication 135 | [HttpPost] 136 | [ValidateAntiForgeryToken] 137 | public async Task EnableTwoFactorAuthentication() 138 | { 139 | await UserManager.SetTwoFactorEnabledAsync(User.Identity.GetUserId(), true); 140 | var user = await UserManager.FindByIdAsync(User.Identity.GetUserId()); 141 | if (user != null) 142 | { 143 | await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); 144 | } 145 | return RedirectToAction("Index", "Manage"); 146 | } 147 | 148 | // 149 | // POST: /Manage/DisableTwoFactorAuthentication 150 | [HttpPost] 151 | [ValidateAntiForgeryToken] 152 | public async Task DisableTwoFactorAuthentication() 153 | { 154 | await UserManager.SetTwoFactorEnabledAsync(User.Identity.GetUserId(), false); 155 | var user = await UserManager.FindByIdAsync(User.Identity.GetUserId()); 156 | if (user != null) 157 | { 158 | await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); 159 | } 160 | return RedirectToAction("Index", "Manage"); 161 | } 162 | 163 | // 164 | // GET: /Manage/VerifyPhoneNumber 165 | public async Task VerifyPhoneNumber(string phoneNumber) 166 | { 167 | var code = await UserManager.GenerateChangePhoneNumberTokenAsync(User.Identity.GetUserId(), phoneNumber); 168 | // Send an SMS through the SMS provider to verify the phone number 169 | return phoneNumber == null ? View("Error") : View(new VerifyPhoneNumberViewModel { PhoneNumber = phoneNumber }); 170 | } 171 | 172 | // 173 | // POST: /Manage/VerifyPhoneNumber 174 | [HttpPost] 175 | [ValidateAntiForgeryToken] 176 | public async Task VerifyPhoneNumber(VerifyPhoneNumberViewModel model) 177 | { 178 | if (!ModelState.IsValid) 179 | { 180 | return View(model); 181 | } 182 | var result = await UserManager.ChangePhoneNumberAsync(User.Identity.GetUserId(), model.PhoneNumber, model.Code); 183 | if (result.Succeeded) 184 | { 185 | var user = await UserManager.FindByIdAsync(User.Identity.GetUserId()); 186 | if (user != null) 187 | { 188 | await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); 189 | } 190 | return RedirectToAction("Index", new { Message = ManageMessageId.AddPhoneSuccess }); 191 | } 192 | // If we got this far, something failed, redisplay form 193 | ModelState.AddModelError("", "Failed to verify phone"); 194 | return View(model); 195 | } 196 | 197 | // 198 | // GET: /Manage/RemovePhoneNumber 199 | public async Task RemovePhoneNumber() 200 | { 201 | var result = await UserManager.SetPhoneNumberAsync(User.Identity.GetUserId(), null); 202 | if (!result.Succeeded) 203 | { 204 | return RedirectToAction("Index", new { Message = ManageMessageId.Error }); 205 | } 206 | var user = await UserManager.FindByIdAsync(User.Identity.GetUserId()); 207 | if (user != null) 208 | { 209 | await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); 210 | } 211 | return RedirectToAction("Index", new { Message = ManageMessageId.RemovePhoneSuccess }); 212 | } 213 | 214 | // 215 | // GET: /Manage/ChangePassword 216 | public ActionResult ChangePassword() 217 | { 218 | return View(); 219 | } 220 | 221 | // 222 | // POST: /Manage/ChangePassword 223 | [HttpPost] 224 | [ValidateAntiForgeryToken] 225 | public async Task ChangePassword(ChangePasswordViewModel model) 226 | { 227 | if (!ModelState.IsValid) 228 | { 229 | return View(model); 230 | } 231 | var result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword, model.NewPassword); 232 | if (result.Succeeded) 233 | { 234 | var user = await UserManager.FindByIdAsync(User.Identity.GetUserId()); 235 | if (user != null) 236 | { 237 | await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); 238 | } 239 | return RedirectToAction("Index", new { Message = ManageMessageId.ChangePasswordSuccess }); 240 | } 241 | AddErrors(result); 242 | return View(model); 243 | } 244 | 245 | // 246 | // GET: /Manage/SetPassword 247 | public ActionResult SetPassword() 248 | { 249 | return View(); 250 | } 251 | 252 | // 253 | // POST: /Manage/SetPassword 254 | [HttpPost] 255 | [ValidateAntiForgeryToken] 256 | public async Task SetPassword(SetPasswordViewModel model) 257 | { 258 | if (ModelState.IsValid) 259 | { 260 | var result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword); 261 | if (result.Succeeded) 262 | { 263 | var user = await UserManager.FindByIdAsync(User.Identity.GetUserId()); 264 | if (user != null) 265 | { 266 | await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); 267 | } 268 | return RedirectToAction("Index", new { Message = ManageMessageId.SetPasswordSuccess }); 269 | } 270 | AddErrors(result); 271 | } 272 | 273 | // If we got this far, something failed, redisplay form 274 | return View(model); 275 | } 276 | 277 | // 278 | // GET: /Manage/ManageLogins 279 | public async Task ManageLogins(ManageMessageId? message) 280 | { 281 | ViewBag.StatusMessage = 282 | message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed." 283 | : message == ManageMessageId.Error ? "An error has occurred." 284 | : ""; 285 | var user = await UserManager.FindByIdAsync(User.Identity.GetUserId()); 286 | if (user == null) 287 | { 288 | return View("Error"); 289 | } 290 | var userLogins = await UserManager.GetLoginsAsync(User.Identity.GetUserId()); 291 | var otherLogins = AuthenticationManager.GetExternalAuthenticationTypes().Where(auth => userLogins.All(ul => auth.AuthenticationType != ul.LoginProvider)).ToList(); 292 | ViewBag.ShowRemoveButton = user.PasswordHash != null || userLogins.Count > 1; 293 | return View(new ManageLoginsViewModel 294 | { 295 | CurrentLogins = userLogins, 296 | OtherLogins = otherLogins 297 | }); 298 | } 299 | 300 | // 301 | // POST: /Manage/LinkLogin 302 | [HttpPost] 303 | [ValidateAntiForgeryToken] 304 | public ActionResult LinkLogin(string provider) 305 | { 306 | // Request a redirect to the external login provider to link a login for the current user 307 | return new AccountController.ChallengeResult(provider, Url.Action("LinkLoginCallback", "Manage"), User.Identity.GetUserId()); 308 | } 309 | 310 | // 311 | // GET: /Manage/LinkLoginCallback 312 | public async Task LinkLoginCallback() 313 | { 314 | var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(XsrfKey, User.Identity.GetUserId()); 315 | if (loginInfo == null) 316 | { 317 | return RedirectToAction("ManageLogins", new { Message = ManageMessageId.Error }); 318 | } 319 | var result = await UserManager.AddLoginAsync(User.Identity.GetUserId(), loginInfo.Login); 320 | return result.Succeeded ? RedirectToAction("ManageLogins") : RedirectToAction("ManageLogins", new { Message = ManageMessageId.Error }); 321 | } 322 | 323 | protected override void Dispose(bool disposing) 324 | { 325 | if (disposing && _userManager != null) 326 | { 327 | _userManager.Dispose(); 328 | _userManager = null; 329 | } 330 | 331 | base.Dispose(disposing); 332 | } 333 | 334 | #region Helpers 335 | // Used for XSRF protection when adding external logins 336 | private const string XsrfKey = "XsrfId"; 337 | 338 | private IAuthenticationManager AuthenticationManager 339 | { 340 | get 341 | { 342 | return HttpContext.GetOwinContext().Authentication; 343 | } 344 | } 345 | 346 | private void AddErrors(IdentityResult result) 347 | { 348 | foreach (var error in result.Errors) 349 | { 350 | ModelState.AddModelError("", error); 351 | } 352 | } 353 | 354 | private bool HasPassword() 355 | { 356 | var user = UserManager.FindById(User.Identity.GetUserId()); 357 | if (user != null) 358 | { 359 | return user.PasswordHash != null; 360 | } 361 | return false; 362 | } 363 | 364 | private bool HasPhoneNumber() 365 | { 366 | var user = UserManager.FindById(User.Identity.GetUserId()); 367 | if (user != null) 368 | { 369 | return user.PhoneNumber != null; 370 | } 371 | return false; 372 | } 373 | 374 | public enum ManageMessageId 375 | { 376 | AddPhoneSuccess, 377 | ChangePasswordSuccess, 378 | SetTwoFactorSuccess, 379 | SetPasswordSuccess, 380 | RemoveLoginSuccess, 381 | RemovePhoneSuccess, 382 | Error 383 | } 384 | 385 | #endregion 386 | } 387 | } -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="identity_with_ioc.MvcApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Global.asax.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | using System.Web.Mvc; 6 | using System.Web.Optimization; 7 | using System.Web.Routing; 8 | 9 | namespace identity_with_ioc 10 | { 11 | public class MvcApplication : System.Web.HttpApplication 12 | { 13 | protected void Application_Start() 14 | { 15 | AreaRegistration.RegisterAllAreas(); 16 | FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 17 | RouteConfig.RegisterRoutes(RouteTable.Routes); 18 | BundleConfig.RegisterBundles(BundleTable.Bundles); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Models/AccountViewModels.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel.DataAnnotations; 3 | 4 | namespace identity_with_ioc.Models 5 | { 6 | public class ExternalLoginConfirmationViewModel 7 | { 8 | [Required] 9 | [Display(Name = "Email")] 10 | public string Email { get; set; } 11 | } 12 | 13 | public class ExternalLoginListViewModel 14 | { 15 | public string ReturnUrl { get; set; } 16 | } 17 | 18 | public class SendCodeViewModel 19 | { 20 | public string SelectedProvider { get; set; } 21 | public ICollection Providers { get; set; } 22 | public string ReturnUrl { get; set; } 23 | public bool RememberMe { get; set; } 24 | } 25 | 26 | public class VerifyCodeViewModel 27 | { 28 | [Required] 29 | public string Provider { get; set; } 30 | 31 | [Required] 32 | [Display(Name = "Code")] 33 | public string Code { get; set; } 34 | public string ReturnUrl { get; set; } 35 | 36 | [Display(Name = "Remember this browser?")] 37 | public bool RememberBrowser { get; set; } 38 | 39 | public bool RememberMe { get; set; } 40 | } 41 | 42 | public class ForgotViewModel 43 | { 44 | [Required] 45 | [Display(Name = "Email")] 46 | public string Email { get; set; } 47 | } 48 | 49 | public class LoginViewModel 50 | { 51 | [Required] 52 | [Display(Name = "Email")] 53 | [EmailAddress] 54 | public string Email { get; set; } 55 | 56 | [Required] 57 | [DataType(DataType.Password)] 58 | [Display(Name = "Password")] 59 | public string Password { get; set; } 60 | 61 | [Display(Name = "Remember me?")] 62 | public bool RememberMe { get; set; } 63 | } 64 | 65 | public class RegisterViewModel 66 | { 67 | [Required] 68 | [EmailAddress] 69 | [Display(Name = "Email")] 70 | public string Email { get; set; } 71 | 72 | [Required] 73 | [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] 74 | [DataType(DataType.Password)] 75 | [Display(Name = "Password")] 76 | public string Password { get; set; } 77 | 78 | [DataType(DataType.Password)] 79 | [Display(Name = "Confirm password")] 80 | [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] 81 | public string ConfirmPassword { get; set; } 82 | } 83 | 84 | public class ResetPasswordViewModel 85 | { 86 | [Required] 87 | [EmailAddress] 88 | [Display(Name = "Email")] 89 | public string Email { get; set; } 90 | 91 | [Required] 92 | [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] 93 | [DataType(DataType.Password)] 94 | [Display(Name = "Password")] 95 | public string Password { get; set; } 96 | 97 | [DataType(DataType.Password)] 98 | [Display(Name = "Confirm password")] 99 | [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] 100 | public string ConfirmPassword { get; set; } 101 | 102 | public string Code { get; set; } 103 | } 104 | 105 | public class ForgotPasswordViewModel 106 | { 107 | [Required] 108 | [EmailAddress] 109 | [Display(Name = "Email")] 110 | public string Email { get; set; } 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Models/IdentityModels.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Entity; 2 | using System.Security.Claims; 3 | using System.Threading.Tasks; 4 | using Microsoft.AspNet.Identity; 5 | using Microsoft.AspNet.Identity.EntityFramework; 6 | 7 | namespace identity_with_ioc.Models 8 | { 9 | // You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more. 10 | public class ApplicationUser : IdentityUser 11 | { 12 | public async Task GenerateUserIdentityAsync(UserManager manager) 13 | { 14 | // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType 15 | var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); 16 | // Add custom user claims here 17 | return userIdentity; 18 | } 19 | } 20 | 21 | public class ApplicationDbContext : IdentityDbContext 22 | { 23 | public ApplicationDbContext() 24 | : base("DefaultConnection", throwIfV1Schema: false) 25 | { 26 | } 27 | 28 | public static ApplicationDbContext Create() 29 | { 30 | return new ApplicationDbContext(); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Models/ManageViewModels.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.ComponentModel.DataAnnotations; 3 | using Microsoft.AspNet.Identity; 4 | using Microsoft.Owin.Security; 5 | 6 | namespace identity_with_ioc.Models 7 | { 8 | public class IndexViewModel 9 | { 10 | public bool HasPassword { get; set; } 11 | public IList Logins { get; set; } 12 | public string PhoneNumber { get; set; } 13 | public bool TwoFactor { get; set; } 14 | public bool BrowserRemembered { get; set; } 15 | } 16 | 17 | public class ManageLoginsViewModel 18 | { 19 | public IList CurrentLogins { get; set; } 20 | public IList OtherLogins { get; set; } 21 | } 22 | 23 | public class FactorViewModel 24 | { 25 | public string Purpose { get; set; } 26 | } 27 | 28 | public class SetPasswordViewModel 29 | { 30 | [Required] 31 | [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] 32 | [DataType(DataType.Password)] 33 | [Display(Name = "New password")] 34 | public string NewPassword { get; set; } 35 | 36 | [DataType(DataType.Password)] 37 | [Display(Name = "Confirm new password")] 38 | [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")] 39 | public string ConfirmPassword { get; set; } 40 | } 41 | 42 | public class ChangePasswordViewModel 43 | { 44 | [Required] 45 | [DataType(DataType.Password)] 46 | [Display(Name = "Current password")] 47 | public string OldPassword { get; set; } 48 | 49 | [Required] 50 | [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] 51 | [DataType(DataType.Password)] 52 | [Display(Name = "New password")] 53 | public string NewPassword { get; set; } 54 | 55 | [DataType(DataType.Password)] 56 | [Display(Name = "Confirm new password")] 57 | [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")] 58 | public string ConfirmPassword { get; set; } 59 | } 60 | 61 | public class AddPhoneNumberViewModel 62 | { 63 | [Required] 64 | [Phone] 65 | [Display(Name = "Phone Number")] 66 | public string Number { get; set; } 67 | } 68 | 69 | public class VerifyPhoneNumberViewModel 70 | { 71 | [Required] 72 | [Display(Name = "Code")] 73 | public string Code { get; set; } 74 | 75 | [Required] 76 | [Phone] 77 | [Display(Name = "Phone Number")] 78 | public string PhoneNumber { get; set; } 79 | } 80 | 81 | public class ConfigureTwoFactorViewModel 82 | { 83 | public string SelectedProvider { get; set; } 84 | public ICollection Providers { get; set; } 85 | } 86 | } -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Project_Readme.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Your ASP.NET application 6 | 95 | 96 | 97 | 98 | 102 | 103 |
104 |
105 |

This application consists of:

106 |
    107 |
  • Sample pages showing basic nav between Home, About, and Contact
  • 108 |
  • Theming using Bootstrap
  • 109 |
  • Authentication, if selected, shows how to register and sign in
  • 110 |
  • ASP.NET features managed using NuGet
  • 111 |
112 |
113 | 114 | 131 | 132 |
133 |

Deploy

134 | 139 |
140 | 141 |
142 |

Get help

143 | 147 |
148 |
149 | 150 | 151 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/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("identity_with_ioc")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("identity_with_ioc")] 13 | [assembly: AssemblyCopyright("Copyright © 2015")] 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("8613b833-2291-4b19-a136-e46554095be5")] 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 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Scripts/_references.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattHoneycutt/asp.net-samples/961dd2fd8f1de672e4950f4f1167f7b6a323ddc6/identity-with-ioc/IdentityWithIoc/Scripts/_references.js -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Scripts/jquery.validate.unobtrusive.min.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | /* 16 | ** Unobtrusive validation support library for jQuery and jQuery Validate 17 | ** Copyright (C) Microsoft Corporation. All rights reserved. 18 | */ 19 | (function(a){var d=a.validator,b,e="unobtrusiveValidation";function c(a,b,c){a.rules[b]=c;if(a.message)a.messages[b]=a.message}function j(a){return a.replace(/^\s+|\s+$/g,"").split(/\s*,\s*/g)}function f(a){return a.replace(/([!"#$%&'()*+,./:;<=>?@\[\\\]^`{|}~])/g,"\\$1")}function h(a){return a.substr(0,a.lastIndexOf(".")+1)}function g(a,b){if(a.indexOf("*.")===0)a=a.replace("*.",b);return a}function m(c,e){var b=a(this).find("[data-valmsg-for='"+f(e[0].name)+"']"),d=b.attr("data-valmsg-replace"),g=d?a.parseJSON(d)!==false:null;b.removeClass("field-validation-valid").addClass("field-validation-error");c.data("unobtrusiveContainer",b);if(g){b.empty();c.removeClass("input-validation-error").appendTo(b)}else c.hide()}function l(e,d){var c=a(this).find("[data-valmsg-summary=true]"),b=c.find("ul");if(b&&b.length&&d.errorList.length){b.empty();c.addClass("validation-summary-errors").removeClass("validation-summary-valid");a.each(d.errorList,function(){a("
  • ").html(this.message).appendTo(b)})}}function k(d){var b=d.data("unobtrusiveContainer"),c=b.attr("data-valmsg-replace"),e=c?a.parseJSON(c):null;if(b){b.addClass("field-validation-valid").removeClass("field-validation-error");d.removeData("unobtrusiveContainer");e&&b.empty()}}function n(){var b=a(this);b.data("validator").resetForm();b.find(".validation-summary-errors").addClass("validation-summary-valid").removeClass("validation-summary-errors");b.find(".field-validation-error").addClass("field-validation-valid").removeClass("field-validation-error").removeData("unobtrusiveContainer").find(">*").removeData("unobtrusiveContainer")}function i(b){var c=a(b),f=c.data(e),i=a.proxy(n,b),g=d.unobtrusive.options||{},h=function(e,d){var c=g[e];c&&a.isFunction(c)&&c.apply(b,d)};if(!f){f={options:{errorClass:g.errorClass||"input-validation-error",errorElement:g.errorElement||"span",errorPlacement:function(){m.apply(b,arguments);h("errorPlacement",arguments)},invalidHandler:function(){l.apply(b,arguments);h("invalidHandler",arguments)},messages:{},rules:{},success:function(){k.apply(b,arguments);h("success",arguments)}},attachValidation:function(){c.off("reset."+e,i).on("reset."+e,i).validate(this.options)},validate:function(){c.validate();return c.valid()}};c.data(e,f)}return f}d.unobtrusive={adapters:[],parseElement:function(b,h){var d=a(b),f=d.parents("form")[0],c,e,g;if(!f)return;c=i(f);c.options.rules[b.name]=e={};c.options.messages[b.name]=g={};a.each(this.adapters,function(){var c="data-val-"+this.name,i=d.attr(c),h={};if(i!==undefined){c+="-";a.each(this.params,function(){h[this]=d.attr(c+this)});this.adapt({element:b,form:f,message:i,params:h,rules:e,messages:g})}});a.extend(e,{__dummy__:true});!h&&c.attachValidation()},parse:function(c){var b=a(c),e=b.parents().addBack().filter("form").add(b.find("form")).has("[data-val=true]");b.find("[data-val=true]").each(function(){d.unobtrusive.parseElement(this,true)});e.each(function(){var a=i(this);a&&a.attachValidation()})}};b=d.unobtrusive.adapters;b.add=function(c,a,b){if(!b){b=a;a=[]}this.push({name:c,params:a,adapt:b});return this};b.addBool=function(a,b){return this.add(a,function(d){c(d,b||a,true)})};b.addMinMax=function(e,g,f,a,d,b){return this.add(e,[d||"min",b||"max"],function(b){var e=b.params.min,d=b.params.max;if(e&&d)c(b,a,[e,d]);else if(e)c(b,g,e);else d&&c(b,f,d)})};b.addSingleVal=function(a,b,d){return this.add(a,[b||"val"],function(e){c(e,d||a,e.params[b])})};d.addMethod("__dummy__",function(){return true});d.addMethod("regex",function(b,c,d){var a;if(this.optional(c))return true;a=(new RegExp(d)).exec(b);return a&&a.index===0&&a[0].length===b.length});d.addMethod("nonalphamin",function(c,d,b){var a;if(b){a=c.match(/\W/g);a=a&&a.length>=b}return a});if(d.methods.extension){b.addSingleVal("accept","mimtype");b.addSingleVal("extension","extension")}else b.addSingleVal("extension","extension","accept");b.addSingleVal("regex","pattern");b.addBool("creditcard").addBool("date").addBool("digits").addBool("email").addBool("number").addBool("url");b.addMinMax("length","minlength","maxlength","rangelength").addMinMax("range","min","max","range");b.addMinMax("minlength","minlength").addMinMax("maxlength","minlength","maxlength");b.add("equalto",["other"],function(b){var i=h(b.element.name),j=b.params.other,d=g(j,i),e=a(b.form).find(":input").filter("[name='"+f(d)+"']")[0];c(b,"equalTo",e)});b.add("required",function(a){(a.element.tagName.toUpperCase()!=="INPUT"||a.element.type.toUpperCase()!=="CHECKBOX")&&c(a,"required",true)});b.add("remote",["url","type","additionalfields"],function(b){var d={url:b.params.url,type:b.params.type||"GET",data:{}},e=h(b.element.name);a.each(j(b.params.additionalfields||b.element.name),function(i,h){var c=g(h,e);d.data[c]=function(){return a(b.form).find(":input").filter("[name='"+f(c)+"']").val()}});c(b,"remote",d)});b.add("password",["min","nonalphamin","regex"],function(a){a.params.min&&c(a,"minlength",a.params.min);a.params.nonalphamin&&c(a,"nonalphamin",a.params.nonalphamin);a.params.regex&&c(a,"regex",a.params.regex)});a(function(){d.unobtrusive.parse(document)})})(jQuery); -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Scripts/respond.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | /*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */ 16 | /*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */ 17 | window.matchMedia = window.matchMedia || (function(doc, undefined){ 18 | 19 | var bool, 20 | docElem = doc.documentElement, 21 | refNode = docElem.firstElementChild || docElem.firstChild, 22 | // fakeBody required for 23 | fakeBody = doc.createElement('body'), 24 | div = doc.createElement('div'); 25 | 26 | div.id = 'mq-test-1'; 27 | div.style.cssText = "position:absolute;top:-100em"; 28 | fakeBody.style.background = "none"; 29 | fakeBody.appendChild(div); 30 | 31 | return function(q){ 32 | 33 | div.innerHTML = '­'; 34 | 35 | docElem.insertBefore(fakeBody, refNode); 36 | bool = div.offsetWidth == 42; 37 | docElem.removeChild(fakeBody); 38 | 39 | return { matches: bool, media: q }; 40 | }; 41 | 42 | })(document); 43 | 44 | 45 | 46 | 47 | /*! Respond.js v1.2.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */ 48 | (function( win ){ 49 | //exposed namespace 50 | win.respond = {}; 51 | 52 | //define update even in native-mq-supporting browsers, to avoid errors 53 | respond.update = function(){}; 54 | 55 | //expose media query support flag for external use 56 | respond.mediaQueriesSupported = win.matchMedia && win.matchMedia( "only all" ).matches; 57 | 58 | //if media queries are supported, exit here 59 | if( respond.mediaQueriesSupported ){ return; } 60 | 61 | //define vars 62 | var doc = win.document, 63 | docElem = doc.documentElement, 64 | mediastyles = [], 65 | rules = [], 66 | appendedEls = [], 67 | parsedSheets = {}, 68 | resizeThrottle = 30, 69 | head = doc.getElementsByTagName( "head" )[0] || docElem, 70 | base = doc.getElementsByTagName( "base" )[0], 71 | links = head.getElementsByTagName( "link" ), 72 | requestQueue = [], 73 | 74 | //loop stylesheets, send text content to translate 75 | ripCSS = function(){ 76 | var sheets = links, 77 | sl = sheets.length, 78 | i = 0, 79 | //vars for loop: 80 | sheet, href, media, isCSS; 81 | 82 | for( ; i < sl; i++ ){ 83 | sheet = sheets[ i ], 84 | href = sheet.href, 85 | media = sheet.media, 86 | isCSS = sheet.rel && sheet.rel.toLowerCase() === "stylesheet"; 87 | 88 | //only links plz and prevent re-parsing 89 | if( !!href && isCSS && !parsedSheets[ href ] ){ 90 | // selectivizr exposes css through the rawCssText expando 91 | if (sheet.styleSheet && sheet.styleSheet.rawCssText) { 92 | translate( sheet.styleSheet.rawCssText, href, media ); 93 | parsedSheets[ href ] = true; 94 | } else { 95 | if( (!/^([a-zA-Z:]*\/\/)/.test( href ) && !base) 96 | || href.replace( RegExp.$1, "" ).split( "/" )[0] === win.location.host ){ 97 | requestQueue.push( { 98 | href: href, 99 | media: media 100 | } ); 101 | } 102 | } 103 | } 104 | } 105 | makeRequests(); 106 | }, 107 | 108 | //recurse through request queue, get css text 109 | makeRequests = function(){ 110 | if( requestQueue.length ){ 111 | var thisRequest = requestQueue.shift(); 112 | 113 | ajax( thisRequest.href, function( styles ){ 114 | translate( styles, thisRequest.href, thisRequest.media ); 115 | parsedSheets[ thisRequest.href ] = true; 116 | makeRequests(); 117 | } ); 118 | } 119 | }, 120 | 121 | //find media blocks in css text, convert to style blocks 122 | translate = function( styles, href, media ){ 123 | var qs = styles.match( /@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi ), 124 | ql = qs && qs.length || 0, 125 | //try to get CSS path 126 | href = href.substring( 0, href.lastIndexOf( "/" )), 127 | repUrls = function( css ){ 128 | return css.replace( /(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g, "$1" + href + "$2$3" ); 129 | }, 130 | useMedia = !ql && media, 131 | //vars used in loop 132 | i = 0, 133 | j, fullq, thisq, eachq, eql; 134 | 135 | //if path exists, tack on trailing slash 136 | if( href.length ){ href += "/"; } 137 | 138 | //if no internal queries exist, but media attr does, use that 139 | //note: this currently lacks support for situations where a media attr is specified on a link AND 140 | //its associated stylesheet has internal CSS media queries. 141 | //In those cases, the media attribute will currently be ignored. 142 | if( useMedia ){ 143 | ql = 1; 144 | } 145 | 146 | 147 | for( ; i < ql; i++ ){ 148 | j = 0; 149 | 150 | //media attr 151 | if( useMedia ){ 152 | fullq = media; 153 | rules.push( repUrls( styles ) ); 154 | } 155 | //parse for styles 156 | else{ 157 | fullq = qs[ i ].match( /@media *([^\{]+)\{([\S\s]+?)$/ ) && RegExp.$1; 158 | rules.push( RegExp.$2 && repUrls( RegExp.$2 ) ); 159 | } 160 | 161 | eachq = fullq.split( "," ); 162 | eql = eachq.length; 163 | 164 | for( ; j < eql; j++ ){ 165 | thisq = eachq[ j ]; 166 | mediastyles.push( { 167 | media : thisq.split( "(" )[ 0 ].match( /(only\s+)?([a-zA-Z]+)\s?/ ) && RegExp.$2 || "all", 168 | rules : rules.length - 1, 169 | hasquery: thisq.indexOf("(") > -1, 170 | minw : thisq.match( /\(min\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/ ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" ), 171 | maxw : thisq.match( /\(max\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/ ) && parseFloat( RegExp.$1 ) + ( RegExp.$2 || "" ) 172 | } ); 173 | } 174 | } 175 | 176 | applyMedia(); 177 | }, 178 | 179 | lastCall, 180 | 181 | resizeDefer, 182 | 183 | // returns the value of 1em in pixels 184 | getEmValue = function() { 185 | var ret, 186 | div = doc.createElement('div'), 187 | body = doc.body, 188 | fakeUsed = false; 189 | 190 | div.style.cssText = "position:absolute;font-size:1em;width:1em"; 191 | 192 | if( !body ){ 193 | body = fakeUsed = doc.createElement( "body" ); 194 | body.style.background = "none"; 195 | } 196 | 197 | body.appendChild( div ); 198 | 199 | docElem.insertBefore( body, docElem.firstChild ); 200 | 201 | ret = div.offsetWidth; 202 | 203 | if( fakeUsed ){ 204 | docElem.removeChild( body ); 205 | } 206 | else { 207 | body.removeChild( div ); 208 | } 209 | 210 | //also update eminpx before returning 211 | ret = eminpx = parseFloat(ret); 212 | 213 | return ret; 214 | }, 215 | 216 | //cached container for 1em value, populated the first time it's needed 217 | eminpx, 218 | 219 | //enable/disable styles 220 | applyMedia = function( fromResize ){ 221 | var name = "clientWidth", 222 | docElemProp = docElem[ name ], 223 | currWidth = doc.compatMode === "CSS1Compat" && docElemProp || doc.body[ name ] || docElemProp, 224 | styleBlocks = {}, 225 | lastLink = links[ links.length-1 ], 226 | now = (new Date()).getTime(); 227 | 228 | //throttle resize calls 229 | if( fromResize && lastCall && now - lastCall < resizeThrottle ){ 230 | clearTimeout( resizeDefer ); 231 | resizeDefer = setTimeout( applyMedia, resizeThrottle ); 232 | return; 233 | } 234 | else { 235 | lastCall = now; 236 | } 237 | 238 | for( var i in mediastyles ){ 239 | var thisstyle = mediastyles[ i ], 240 | min = thisstyle.minw, 241 | max = thisstyle.maxw, 242 | minnull = min === null, 243 | maxnull = max === null, 244 | em = "em"; 245 | 246 | if( !!min ){ 247 | min = parseFloat( min ) * ( min.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 ); 248 | } 249 | if( !!max ){ 250 | max = parseFloat( max ) * ( max.indexOf( em ) > -1 ? ( eminpx || getEmValue() ) : 1 ); 251 | } 252 | 253 | // if there's no media query at all (the () part), or min or max is not null, and if either is present, they're true 254 | if( !thisstyle.hasquery || ( !minnull || !maxnull ) && ( minnull || currWidth >= min ) && ( maxnull || currWidth <= max ) ){ 255 | if( !styleBlocks[ thisstyle.media ] ){ 256 | styleBlocks[ thisstyle.media ] = []; 257 | } 258 | styleBlocks[ thisstyle.media ].push( rules[ thisstyle.rules ] ); 259 | } 260 | } 261 | 262 | //remove any existing respond style element(s) 263 | for( var i in appendedEls ){ 264 | if( appendedEls[ i ] && appendedEls[ i ].parentNode === head ){ 265 | head.removeChild( appendedEls[ i ] ); 266 | } 267 | } 268 | 269 | //inject active styles, grouped by media type 270 | for( var i in styleBlocks ){ 271 | var ss = doc.createElement( "style" ), 272 | css = styleBlocks[ i ].join( "\n" ); 273 | 274 | ss.type = "text/css"; 275 | ss.media = i; 276 | 277 | //originally, ss was appended to a documentFragment and sheets were appended in bulk. 278 | //this caused crashes in IE in a number of circumstances, such as when the HTML element had a bg image set, so appending beforehand seems best. Thanks to @dvelyk for the initial research on this one! 279 | head.insertBefore( ss, lastLink.nextSibling ); 280 | 281 | if ( ss.styleSheet ){ 282 | ss.styleSheet.cssText = css; 283 | } 284 | else { 285 | ss.appendChild( doc.createTextNode( css ) ); 286 | } 287 | 288 | //push to appendedEls to track for later removal 289 | appendedEls.push( ss ); 290 | } 291 | }, 292 | //tweaked Ajax functions from Quirksmode 293 | ajax = function( url, callback ) { 294 | var req = xmlHttp(); 295 | if (!req){ 296 | return; 297 | } 298 | req.open( "GET", url, true ); 299 | req.onreadystatechange = function () { 300 | if ( req.readyState != 4 || req.status != 200 && req.status != 304 ){ 301 | return; 302 | } 303 | callback( req.responseText ); 304 | } 305 | if ( req.readyState == 4 ){ 306 | return; 307 | } 308 | req.send( null ); 309 | }, 310 | //define ajax obj 311 | xmlHttp = (function() { 312 | var xmlhttpmethod = false; 313 | try { 314 | xmlhttpmethod = new XMLHttpRequest(); 315 | } 316 | catch( e ){ 317 | xmlhttpmethod = new ActiveXObject( "Microsoft.XMLHTTP" ); 318 | } 319 | return function(){ 320 | return xmlhttpmethod; 321 | }; 322 | })(); 323 | 324 | //translate CSS 325 | ripCSS(); 326 | 327 | //expose update for re-running respond later on 328 | respond.update = ripCSS; 329 | 330 | //adjust on resize 331 | function callMedia(){ 332 | applyMedia( true ); 333 | } 334 | if( win.addEventListener ){ 335 | win.addEventListener( "resize", callMedia, false ); 336 | } 337 | else if( win.attachEvent ){ 338 | win.attachEvent( "onresize", callMedia ); 339 | } 340 | })(this); 341 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Scripts/respond.min.js: -------------------------------------------------------------------------------- 1 | /* NUGET: BEGIN LICENSE TEXT 2 | * 3 | * Microsoft grants you the right to use these script files for the sole 4 | * purpose of either: (i) interacting through your browser with the Microsoft 5 | * website or online service, subject to the applicable licensing or use 6 | * terms; or (ii) using the files as included with a Microsoft product subject 7 | * to that product's license terms. Microsoft reserves all other rights to the 8 | * files not expressly granted by Microsoft, whether by implication, estoppel 9 | * or otherwise. Insofar as a script file is dual licensed under GPL, 10 | * Microsoft neither took the code under GPL nor distributes it thereunder but 11 | * under the terms set out in this paragraph. All notices and licenses 12 | * below are for informational purposes only. 13 | * 14 | * NUGET: END LICENSE TEXT */ 15 | /*! matchMedia() polyfill - Test a CSS media type/query in JS. Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas. Dual MIT/BSD license */ 16 | /*! NOTE: If you're already including a window.matchMedia polyfill via Modernizr or otherwise, you don't need this part */ 17 | window.matchMedia=window.matchMedia||(function(e,f){var c,a=e.documentElement,b=a.firstElementChild||a.firstChild,d=e.createElement("body"),g=e.createElement("div");g.id="mq-test-1";g.style.cssText="position:absolute;top:-100em";d.style.background="none";d.appendChild(g);return function(h){g.innerHTML='­';a.insertBefore(d,b);c=g.offsetWidth==42;a.removeChild(d);return{matches:c,media:h}}})(document); 18 | 19 | /*! Respond.js v1.2.0: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */ 20 | (function(e){e.respond={};respond.update=function(){};respond.mediaQueriesSupported=e.matchMedia&&e.matchMedia("only all").matches;if(respond.mediaQueriesSupported){return}var w=e.document,s=w.documentElement,i=[],k=[],q=[],o={},h=30,f=w.getElementsByTagName("head")[0]||s,g=w.getElementsByTagName("base")[0],b=f.getElementsByTagName("link"),d=[],a=function(){var D=b,y=D.length,B=0,A,z,C,x;for(;B-1,minw:F.match(/\(min\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:F.match(/\(max\-width:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}}j()},l,r,v=function(){var z,A=w.createElement("div"),x=w.body,y=false;A.style.cssText="position:absolute;font-size:1em;width:1em";if(!x){x=y=w.createElement("body");x.style.background="none"}x.appendChild(A);s.insertBefore(x,s.firstChild);z=A.offsetWidth;if(y){s.removeChild(x)}else{x.removeChild(A)}z=p=parseFloat(z);return z},p,j=function(I){var x="clientWidth",B=s[x],H=w.compatMode==="CSS1Compat"&&B||w.body[x]||B,D={},G=b[b.length-1],z=(new Date()).getTime();if(I&&l&&z-l-1?(p||v()):1)}if(!!J){J=parseFloat(J)*(J.indexOf(y)>-1?(p||v()):1)}if(!K.hasquery||(!A||!L)&&(A||H>=C)&&(L||H<=J)){if(!D[K.media]){D[K.media]=[]}D[K.media].push(k[K.rules])}}for(var E in q){if(q[E]&&q[E].parentNode===f){f.removeChild(q[E])}}for(var E in D){var M=w.createElement("style"),F=D[E].join("\n");M.type="text/css";M.media=E;f.insertBefore(M,G.nextSibling);if(M.styleSheet){M.styleSheet.cssText=F}else{M.appendChild(w.createTextNode(F))}q.push(M)}},n=function(x,z){var y=c();if(!y){return}y.open("GET",x,true);y.onreadystatechange=function(){if(y.readyState!=4||y.status!=200&&y.status!=304){return}z(y.responseText)};if(y.readyState==4){return}y.send(null)},c=(function(){var x=false;try{x=new XMLHttpRequest()}catch(y){x=new ActiveXObject("Microsoft.XMLHTTP")}return function(){return x}})();a();respond.update=a;function t(){j(true)}if(e.addEventListener){e.addEventListener("resize",t,false)}else{if(e.attachEvent){e.attachEvent("onresize",t)}}})(this); -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Startup.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Owin; 2 | using Owin; 3 | 4 | [assembly: OwinStartupAttribute(typeof(identity_with_ioc.Startup))] 5 | namespace identity_with_ioc 6 | { 7 | public partial class Startup 8 | { 9 | public void Configuration(IAppBuilder app) 10 | { 11 | ConfigureAuth(app); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/Account/ConfirmEmail.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Confirm Email"; 3 | } 4 | 5 |

    @ViewBag.Title.

    6 |
    7 |

    8 | Thank you for confirming your email. Please @Html.ActionLink("Click here to Log in", "Login", "Account", routeValues: null, htmlAttributes: new { id = "loginLink" }) 9 |

    10 |
    11 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/Account/ExternalLoginConfirmation.cshtml: -------------------------------------------------------------------------------- 1 | @model identity_with_ioc.Models.ExternalLoginConfirmationViewModel 2 | @{ 3 | ViewBag.Title = "Register"; 4 | } 5 |

    @ViewBag.Title.

    6 |

    Associate your @ViewBag.LoginProvider account.

    7 | 8 | @using (Html.BeginForm("ExternalLoginConfirmation", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 9 | { 10 | @Html.AntiForgeryToken() 11 | 12 |

    Association Form

    13 |
    14 | @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 15 |

    16 | You've successfully authenticated with @ViewBag.LoginProvider. 17 | Please enter a user name for this site below and click the Register button to finish 18 | logging in. 19 |

    20 |
    21 | @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" }) 22 |
    23 | @Html.TextBoxFor(m => m.Email, new { @class = "form-control" }) 24 | @Html.ValidationMessageFor(m => m.Email, "", new { @class = "text-danger" }) 25 |
    26 |
    27 |
    28 |
    29 | 30 |
    31 |
    32 | } 33 | 34 | @section Scripts { 35 | @Scripts.Render("~/bundles/jqueryval") 36 | } 37 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/Account/ExternalLoginFailure.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Login Failure"; 3 | } 4 | 5 |
    6 |

    @ViewBag.Title.

    7 |

    Unsuccessful login with service.

    8 |
    9 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/Account/ForgotPassword.cshtml: -------------------------------------------------------------------------------- 1 | @model identity_with_ioc.Models.ForgotPasswordViewModel 2 | @{ 3 | ViewBag.Title = "Forgot your password?"; 4 | } 5 | 6 |

    @ViewBag.Title.

    7 | 8 | @using (Html.BeginForm("ForgotPassword", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 9 | { 10 | @Html.AntiForgeryToken() 11 |

    Enter your email.

    12 |
    13 | @Html.ValidationSummary("", new { @class = "text-danger" }) 14 |
    15 | @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" }) 16 |
    17 | @Html.TextBoxFor(m => m.Email, new { @class = "form-control" }) 18 |
    19 |
    20 |
    21 |
    22 | 23 |
    24 |
    25 | } 26 | 27 | @section Scripts { 28 | @Scripts.Render("~/bundles/jqueryval") 29 | } 30 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/Account/ForgotPasswordConfirmation.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Forgot Password Confirmation"; 3 | } 4 | 5 |
    6 |

    @ViewBag.Title.

    7 |
    8 |
    9 |

    10 | Please check your email to reset your password. 11 |

    12 |
    13 | 14 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/Account/Login.cshtml: -------------------------------------------------------------------------------- 1 | @using identity_with_ioc.Models 2 | @model LoginViewModel 3 | @{ 4 | ViewBag.Title = "Log in"; 5 | } 6 | 7 |

    @ViewBag.Title.

    8 |
    9 |
    10 |
    11 | @using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 12 | { 13 | @Html.AntiForgeryToken() 14 |

    Use a local account to log in.

    15 |
    16 | @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 17 |
    18 | @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" }) 19 |
    20 | @Html.TextBoxFor(m => m.Email, new { @class = "form-control" }) 21 | @Html.ValidationMessageFor(m => m.Email, "", new { @class = "text-danger" }) 22 |
    23 |
    24 |
    25 | @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" }) 26 |
    27 | @Html.PasswordFor(m => m.Password, new { @class = "form-control" }) 28 | @Html.ValidationMessageFor(m => m.Password, "", new { @class = "text-danger" }) 29 |
    30 |
    31 |
    32 |
    33 |
    34 | @Html.CheckBoxFor(m => m.RememberMe) 35 | @Html.LabelFor(m => m.RememberMe) 36 |
    37 |
    38 |
    39 |
    40 |
    41 | 42 |
    43 |
    44 |

    45 | @Html.ActionLink("Register as a new user", "Register") 46 |

    47 | @* Enable this once you have account confirmation enabled for password reset functionality 48 |

    49 | @Html.ActionLink("Forgot your password?", "ForgotPassword") 50 |

    *@ 51 | } 52 |
    53 |
    54 |
    55 |
    56 | @Html.Partial("_ExternalLoginsListPartial", new ExternalLoginListViewModel { ReturnUrl = ViewBag.ReturnUrl }) 57 |
    58 |
    59 |
    60 | 61 | @section Scripts { 62 | @Scripts.Render("~/bundles/jqueryval") 63 | } -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/Account/Register.cshtml: -------------------------------------------------------------------------------- 1 | @model identity_with_ioc.Models.RegisterViewModel 2 | @{ 3 | ViewBag.Title = "Register"; 4 | } 5 | 6 |

    @ViewBag.Title.

    7 | 8 | @using (Html.BeginForm("Register", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 9 | { 10 | @Html.AntiForgeryToken() 11 |

    Create a new account.

    12 |
    13 | @Html.ValidationSummary("", new { @class = "text-danger" }) 14 |
    15 | @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" }) 16 |
    17 | @Html.TextBoxFor(m => m.Email, new { @class = "form-control" }) 18 |
    19 |
    20 |
    21 | @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" }) 22 |
    23 | @Html.PasswordFor(m => m.Password, new { @class = "form-control" }) 24 |
    25 |
    26 |
    27 | @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" }) 28 |
    29 | @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" }) 30 |
    31 |
    32 |
    33 |
    34 | 35 |
    36 |
    37 | } 38 | 39 | @section Scripts { 40 | @Scripts.Render("~/bundles/jqueryval") 41 | } 42 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/Account/ResetPassword.cshtml: -------------------------------------------------------------------------------- 1 | @model identity_with_ioc.Models.ResetPasswordViewModel 2 | @{ 3 | ViewBag.Title = "Reset password"; 4 | } 5 | 6 |

    @ViewBag.Title.

    7 | 8 | @using (Html.BeginForm("ResetPassword", "Account", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 9 | { 10 | @Html.AntiForgeryToken() 11 |

    Reset your password.

    12 |
    13 | @Html.ValidationSummary("", new { @class = "text-danger" }) 14 | @Html.HiddenFor(model => model.Code) 15 |
    16 | @Html.LabelFor(m => m.Email, new { @class = "col-md-2 control-label" }) 17 |
    18 | @Html.TextBoxFor(m => m.Email, new { @class = "form-control" }) 19 |
    20 |
    21 |
    22 | @Html.LabelFor(m => m.Password, new { @class = "col-md-2 control-label" }) 23 |
    24 | @Html.PasswordFor(m => m.Password, new { @class = "form-control" }) 25 |
    26 |
    27 |
    28 | @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" }) 29 |
    30 | @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" }) 31 |
    32 |
    33 |
    34 |
    35 | 36 |
    37 |
    38 | } 39 | 40 | @section Scripts { 41 | @Scripts.Render("~/bundles/jqueryval") 42 | } 43 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/Account/ResetPasswordConfirmation.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Reset password confirmation"; 3 | } 4 | 5 |
    6 |

    @ViewBag.Title.

    7 |
    8 |
    9 |

    10 | Your password has been reset. Please @Html.ActionLink("click here to log in", "Login", "Account", routeValues: null, htmlAttributes: new { id = "loginLink" }) 11 |

    12 |
    13 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/Account/SendCode.cshtml: -------------------------------------------------------------------------------- 1 | @model identity_with_ioc.Models.SendCodeViewModel 2 | @{ 3 | ViewBag.Title = "Send"; 4 | } 5 | 6 |

    @ViewBag.Title.

    7 | 8 | @using (Html.BeginForm("SendCode", "Account", new { ReturnUrl = Model.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" })) { 9 | @Html.AntiForgeryToken() 10 | @Html.Hidden("rememberMe", @Model.RememberMe) 11 |

    Send verification code

    12 |
    13 |
    14 |
    15 | Select Two-Factor Authentication Provider: 16 | @Html.DropDownListFor(model => model.SelectedProvider, Model.Providers) 17 | 18 |
    19 |
    20 | } 21 | 22 | @section Scripts { 23 | @Scripts.Render("~/bundles/jqueryval") 24 | } 25 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/Account/VerifyCode.cshtml: -------------------------------------------------------------------------------- 1 | @model identity_with_ioc.Models.VerifyCodeViewModel 2 | @{ 3 | ViewBag.Title = "Verify"; 4 | } 5 | 6 |

    @ViewBag.Title.

    7 | 8 | @using (Html.BeginForm("VerifyCode", "Account", new { ReturnUrl = Model.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" })) { 9 | @Html.AntiForgeryToken() 10 | @Html.Hidden("provider", @Model.Provider) 11 | @Html.Hidden("rememberMe", @Model.RememberMe) 12 |

    Enter verification code

    13 |
    14 | @Html.ValidationSummary("", new { @class = "text-danger" }) 15 |
    16 | @Html.LabelFor(m => m.Code, new { @class = "col-md-2 control-label" }) 17 |
    18 | @Html.TextBoxFor(m => m.Code, new { @class = "form-control" }) 19 |
    20 |
    21 |
    22 |
    23 |
    24 | @Html.CheckBoxFor(m => m.RememberBrowser) 25 | @Html.LabelFor(m => m.RememberBrowser) 26 |
    27 |
    28 |
    29 |
    30 |
    31 | 32 |
    33 |
    34 | } 35 | 36 | @section Scripts { 37 | @Scripts.Render("~/bundles/jqueryval") 38 | } 39 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/Account/_ExternalLoginsListPartial.cshtml: -------------------------------------------------------------------------------- 1 | @model identity_with_ioc.Models.ExternalLoginListViewModel 2 | @using Microsoft.Owin.Security 3 | 4 |

    Use another service to log in.

    5 |
    6 | @{ 7 | var loginProviders = Context.GetOwinContext().Authentication.GetExternalAuthenticationTypes(); 8 | if (loginProviders.Count() == 0) { 9 |
    10 |

    11 | There are no external authentication services configured. See this article 12 | for details on setting up this ASP.NET application to support logging in via external services. 13 |

    14 |
    15 | } 16 | else { 17 | using (Html.BeginForm("ExternalLogin", "Account", new { ReturnUrl = Model.ReturnUrl })) { 18 | @Html.AntiForgeryToken() 19 |
    20 |

    21 | @foreach (AuthenticationDescription p in loginProviders) { 22 | 23 | } 24 |

    25 |
    26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/Home/About.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "About"; 3 | } 4 |

    @ViewBag.Title.

    5 |

    @ViewBag.Message

    6 | 7 |

    Use this area to provide additional information.

    8 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/Home/Contact.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Contact"; 3 | } 4 |

    @ViewBag.Title.

    5 |

    @ViewBag.Message

    6 | 7 |
    8 | One Microsoft Way
    9 | Redmond, WA 98052-6399
    10 | P: 11 | 425.555.0100 12 |
    13 | 14 |
    15 | Support: Support@example.com
    16 | Marketing: Marketing@example.com 17 |
    -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Home Page"; 3 | } 4 | 5 |
    6 |

    ASP.NET

    7 |

    ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS and JavaScript.

    8 |

    Learn more »

    9 |
    10 | 11 |
    12 |
    13 |

    Getting started

    14 |

    15 | ASP.NET MVC gives you a powerful, patterns-based way to build dynamic websites that 16 | enables a clean separation of concerns and gives you full control over markup 17 | for enjoyable, agile development. 18 |

    19 |

    Learn more »

    20 |
    21 |
    22 |

    Get more libraries

    23 |

    NuGet is a free Visual Studio extension that makes it easy to add, remove, and update libraries and tools in Visual Studio projects.

    24 |

    Learn more »

    25 |
    26 |
    27 |

    Web Hosting

    28 |

    You can easily find a web hosting company that offers the right mix of features and price for your applications.

    29 |

    Learn more »

    30 |
    31 |
    -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/Manage/AddPhoneNumber.cshtml: -------------------------------------------------------------------------------- 1 | @model identity_with_ioc.Models.AddPhoneNumberViewModel 2 | @{ 3 | ViewBag.Title = "Phone Number"; 4 | } 5 | 6 |

    @ViewBag.Title.

    7 | 8 | @using (Html.BeginForm("AddPhoneNumber", "Manage", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 9 | { 10 | @Html.AntiForgeryToken() 11 |

    Add a phone number

    12 |
    13 | @Html.ValidationSummary("", new { @class = "text-danger" }) 14 |
    15 | @Html.LabelFor(m => m.Number, new { @class = "col-md-2 control-label" }) 16 |
    17 | @Html.TextBoxFor(m => m.Number, new { @class = "form-control" }) 18 |
    19 |
    20 |
    21 |
    22 | 23 |
    24 |
    25 | } 26 | 27 | @section Scripts { 28 | @Scripts.Render("~/bundles/jqueryval") 29 | } 30 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/Manage/ChangePassword.cshtml: -------------------------------------------------------------------------------- 1 | @model identity_with_ioc.Models.ChangePasswordViewModel 2 | @{ 3 | ViewBag.Title = "Change Password"; 4 | } 5 | 6 |

    @ViewBag.Title.

    7 | 8 | @using (Html.BeginForm("ChangePassword", "Manage", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 9 | { 10 | @Html.AntiForgeryToken() 11 |

    Change Password Form

    12 |
    13 | @Html.ValidationSummary("", new { @class = "text-danger" }) 14 |
    15 | @Html.LabelFor(m => m.OldPassword, new { @class = "col-md-2 control-label" }) 16 |
    17 | @Html.PasswordFor(m => m.OldPassword, new { @class = "form-control" }) 18 |
    19 |
    20 |
    21 | @Html.LabelFor(m => m.NewPassword, new { @class = "col-md-2 control-label" }) 22 |
    23 | @Html.PasswordFor(m => m.NewPassword, new { @class = "form-control" }) 24 |
    25 |
    26 |
    27 | @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" }) 28 |
    29 | @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" }) 30 |
    31 |
    32 |
    33 |
    34 | 35 |
    36 |
    37 | } 38 | @section Scripts { 39 | @Scripts.Render("~/bundles/jqueryval") 40 | } -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/Manage/Index.cshtml: -------------------------------------------------------------------------------- 1 | @model identity_with_ioc.Models.IndexViewModel 2 | @{ 3 | ViewBag.Title = "Manage"; 4 | } 5 | 6 |

    @ViewBag.Title.

    7 | 8 |

    @ViewBag.StatusMessage

    9 |
    10 |

    Change your account settings

    11 |
    12 |
    13 |
    Password:
    14 |
    15 | [ 16 | @if (Model.HasPassword) 17 | { 18 | @Html.ActionLink("Change your password", "ChangePassword") 19 | } 20 | else 21 | { 22 | @Html.ActionLink("Create", "SetPassword") 23 | } 24 | ] 25 |
    26 |
    External Logins:
    27 |
    28 | @Model.Logins.Count [ 29 | @Html.ActionLink("Manage", "ManageLogins") ] 30 |
    31 | @* 32 | Phone Numbers can used as a second factor of verification in a two-factor authentication system. 33 | 34 | See this article 35 | for details on setting up this ASP.NET application to support two-factor authentication using SMS. 36 | 37 | Uncomment the following block after you have set up two-factor authentication 38 | *@ 39 | @* 40 |
    Phone Number:
    41 |
    42 | @(Model.PhoneNumber ?? "None") [ 43 | @if (Model.PhoneNumber != null) 44 | { 45 | @Html.ActionLink("Change", "AddPhoneNumber") 46 | @:  |  47 | @Html.ActionLink("Remove", "RemovePhoneNumber") 48 | } 49 | else 50 | { 51 | @Html.ActionLink("Add", "AddPhoneNumber") 52 | } 53 | ] 54 |
    55 | *@ 56 |
    Two-Factor Authentication:
    57 |
    58 |

    59 | There are no two-factor authentication providers configured. See this article 60 | for details on setting up this ASP.NET application to support two-factor authentication. 61 |

    62 | @*@if (Model.TwoFactor) 63 | { 64 | using (Html.BeginForm("DisableTwoFactorAuthentication", "Manage", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 65 | { 66 | @Html.AntiForgeryToken() 67 | Enabled 68 | 69 | 70 | } 71 | } 72 | else 73 | { 74 | using (Html.BeginForm("EnableTwoFactorAuthentication", "Manage", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 75 | { 76 | @Html.AntiForgeryToken() 77 | Disabled 78 | 79 | 80 | } 81 | }*@ 82 |
    83 |
    84 |
    85 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/Manage/ManageLogins.cshtml: -------------------------------------------------------------------------------- 1 | @model identity_with_ioc.Models.ManageLoginsViewModel 2 | @using Microsoft.Owin.Security 3 | @{ 4 | ViewBag.Title = "Manage your external logins"; 5 | } 6 | 7 |

    @ViewBag.Title.

    8 | 9 |

    @ViewBag.StatusMessage

    10 | @{ 11 | var loginProviders = Context.GetOwinContext().Authentication.GetExternalAuthenticationTypes(); 12 | if (loginProviders.Count() == 0) { 13 |
    14 |

    15 | There are no external authentication services configured. See this article 16 | for details on setting up this ASP.NET application to support logging in via external services. 17 |

    18 |
    19 | } 20 | else 21 | { 22 | if (Model.CurrentLogins.Count > 0) 23 | { 24 |

    Registered Logins

    25 | 26 | 27 | @foreach (var account in Model.CurrentLogins) 28 | { 29 | 30 | 31 | 49 | 50 | } 51 | 52 |
    @account.LoginProvider 32 | @if (ViewBag.ShowRemoveButton) 33 | { 34 | using (Html.BeginForm("RemoveLogin", "Manage")) 35 | { 36 | @Html.AntiForgeryToken() 37 |
    38 | @Html.Hidden("loginProvider", account.LoginProvider) 39 | @Html.Hidden("providerKey", account.ProviderKey) 40 | 41 |
    42 | } 43 | } 44 | else 45 | { 46 | @:   47 | } 48 |
    53 | } 54 | if (Model.OtherLogins.Count > 0) 55 | { 56 | using (Html.BeginForm("LinkLogin", "Manage")) 57 | { 58 | @Html.AntiForgeryToken() 59 |
    60 |

    61 | @foreach (AuthenticationDescription p in Model.OtherLogins) 62 | { 63 | 64 | } 65 |

    66 |
    67 | } 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/Manage/SetPassword.cshtml: -------------------------------------------------------------------------------- 1 | @model identity_with_ioc.Models.SetPasswordViewModel 2 | @{ 3 | ViewBag.Title = "Create Password"; 4 | } 5 | 6 |

    @ViewBag.Title.

    7 |

    8 | You do not have a local username/password for this site. Add a local 9 | account so you can log in without an external login. 10 |

    11 | 12 | @using (Html.BeginForm("SetPassword", "Manage", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 13 | { 14 | @Html.AntiForgeryToken() 15 | 16 |

    Create Local Login

    17 |
    18 | @Html.ValidationSummary("", new { @class = "text-danger" }) 19 |
    20 | @Html.LabelFor(m => m.NewPassword, new { @class = "col-md-2 control-label" }) 21 |
    22 | @Html.PasswordFor(m => m.NewPassword, new { @class = "form-control" }) 23 |
    24 |
    25 |
    26 | @Html.LabelFor(m => m.ConfirmPassword, new { @class = "col-md-2 control-label" }) 27 |
    28 | @Html.PasswordFor(m => m.ConfirmPassword, new { @class = "form-control" }) 29 |
    30 |
    31 |
    32 |
    33 | 34 |
    35 |
    36 | } 37 | @section Scripts { 38 | @Scripts.Render("~/bundles/jqueryval") 39 | } -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/Manage/VerifyPhoneNumber.cshtml: -------------------------------------------------------------------------------- 1 | @model identity_with_ioc.Models.VerifyPhoneNumberViewModel 2 | @{ 3 | ViewBag.Title = "Verify Phone Number"; 4 | } 5 | 6 |

    @ViewBag.Title.

    7 | 8 | @using (Html.BeginForm("VerifyPhoneNumber", "Manage", FormMethod.Post, new { @class = "form-horizontal", role = "form" })) 9 | { 10 | @Html.AntiForgeryToken() 11 | @Html.Hidden("phoneNumber", @Model.PhoneNumber) 12 |

    Enter verification code

    13 |
    @ViewBag.Status
    14 |
    15 | @Html.ValidationSummary("", new { @class = "text-danger" }) 16 |
    17 | @Html.LabelFor(m => m.Code, new { @class = "col-md-2 control-label" }) 18 |
    19 | @Html.TextBoxFor(m => m.Code, new { @class = "form-control" }) 20 |
    21 |
    22 |
    23 |
    24 | 25 |
    26 |
    27 | } 28 | 29 | @section Scripts { 30 | @Scripts.Render("~/bundles/jqueryval") 31 | } 32 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @model System.Web.Mvc.HandleErrorInfo 2 | 3 | @{ 4 | ViewBag.Title = "Error"; 5 | } 6 | 7 |

    Error.

    8 |

    An error occurred while processing your request.

    9 | 10 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/Shared/Lockout.cshtml: -------------------------------------------------------------------------------- 1 | @model System.Web.Mvc.HandleErrorInfo 2 | 3 | @{ 4 | ViewBag.Title = "Locked Out"; 5 | } 6 | 7 |
    8 |

    Locked out.

    9 |

    This account has been locked out, please try again later.

    10 |
    11 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | @ViewBag.Title - My ASP.NET Application 7 | @Styles.Render("~/Content/css") 8 | @Scripts.Render("~/bundles/modernizr") 9 | 10 | 11 | 12 | 32 |
    33 | @RenderBody() 34 |
    35 |
    36 |

    © @DateTime.Now.Year - My ASP.NET Application

    37 |
    38 |
    39 | 40 | @Scripts.Render("~/bundles/jquery") 41 | @Scripts.Render("~/bundles/bootstrap") 42 | @RenderSection("scripts", required: false) 43 | 44 | 45 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/Shared/_LoginPartial.cshtml: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNet.Identity 2 | @if (Request.IsAuthenticated) 3 | { 4 | using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm", @class = "navbar-right" })) 5 | { 6 | @Html.AntiForgeryToken() 7 | 8 | 14 | } 15 | } 16 | else 17 | { 18 | 22 | } 23 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/Web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 |
    7 |
    8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "~/Views/Shared/_Layout.cshtml"; 3 | } 4 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Web.Debug.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Web.Release.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/Web.config: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | 9 |
    10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 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 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattHoneycutt/asp.net-samples/961dd2fd8f1de672e4950f4f1167f7b6a323ddc6/identity-with-ioc/IdentityWithIoc/favicon.ico -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattHoneycutt/asp.net-samples/961dd2fd8f1de672e4950f4f1167f7b6a323ddc6/identity-with-ioc/IdentityWithIoc/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattHoneycutt/asp.net-samples/961dd2fd8f1de672e4950f4f1167f7b6a323ddc6/identity-with-ioc/IdentityWithIoc/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MattHoneycutt/asp.net-samples/961dd2fd8f1de672e4950f4f1167f7b6a323ddc6/identity-with-ioc/IdentityWithIoc/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /identity-with-ioc/IdentityWithIoc/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /identity-with-ioc/identity-with-ioc.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.31101.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "identity-with-ioc", "IdentityWithIoc\identity-with-ioc.csproj", "{7A8ABD71-3867-450E-9D7C-54B2ECE86F0B}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {7A8ABD71-3867-450E-9D7C-54B2ECE86F0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {7A8ABD71-3867-450E-9D7C-54B2ECE86F0B}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {7A8ABD71-3867-450E-9D7C-54B2ECE86F0B}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {7A8ABD71-3867-450E-9D7C-54B2ECE86F0B}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /identity-with-ioc/packages/repositories.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | --------------------------------------------------------------------------------