├── .gitattributes ├── .gitignore ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── build-packages.bat └── src ├── .nuget ├── NuGet.Config ├── NuGet.exe └── NuGet.targets ├── AddressInfo.cs ├── AspNetHaack.DemoWeb ├── App_Start │ └── FormsAuthenticationConfig.cs ├── AspNetHaack.DemoWeb.csproj ├── Content │ └── Site.css ├── Controllers │ ├── AccountController.cs │ └── HomeController.cs ├── Global.asax ├── Global.asax.cs ├── Models │ └── AccountModels.cs ├── Properties │ └── AssemblyInfo.cs ├── Scripts │ ├── jquery-1.6.4-vsdoc.js │ ├── jquery-1.6.4.js │ ├── jquery-1.6.4.min.js │ ├── jquery.unobtrusive-ajax.js │ ├── jquery.unobtrusive-ajax.min.js │ ├── jquery.validate.unobtrusive.js │ └── jquery.validate.unobtrusive.min.js ├── Views │ ├── Account │ │ ├── LogOn.cshtml │ │ └── Register.cshtml │ ├── Home │ │ └── Index.cshtml │ ├── Shared │ │ ├── Error.cshtml │ │ ├── _Layout.cshtml │ │ └── _LogOnPartial.cshtml │ ├── Web.config │ └── _ViewStart.cshtml ├── Web.Debug.config ├── Web.Release.config ├── Web.config └── packages.config ├── AspNetHaack ├── App_Start │ └── FormsAuthenticationConfig.cs.pp ├── AspNetHaack.csproj ├── AspNetHaack.nuspec ├── Properties │ └── AssemblyInfo.cs ├── SuppressFormsAuthenticationRedirectModule.cs └── packages.config ├── CodeHaacks.sln ├── CodeHaacks.sln.DotSettings ├── ControllerInspectorTests ├── ControllerInspectorTests.csproj ├── ControllerValidatorTests.cs ├── Properties │ └── AssemblyInfo.cs └── packages.config ├── JsonHijackDemo ├── Content │ └── Site.css ├── Controllers │ ├── AccountController.cs │ └── HomeController.cs ├── Global.asax ├── Global.asax.cs ├── JsonHijackDemo.csproj ├── Models │ └── AccountModels.cs ├── Properties │ └── AssemblyInfo.cs ├── Views │ ├── Account │ │ ├── ChangePassword.cshtml │ │ ├── ChangePasswordSuccess.cshtml │ │ ├── LogOn.cshtml │ │ └── Register.cshtml │ ├── Home │ │ └── Index.cshtml │ ├── Shared │ │ ├── Error.cshtml │ │ ├── _Layout.cshtml │ │ └── _LogOnPartial.cshtml │ ├── Web.config │ └── _ViewStart.cshtml ├── Web.config └── html │ ├── JsonAttack.html │ └── README.md ├── ListModelBindingDemo ├── ListModelBindingDemo.sln └── ListModelBindingWeb │ ├── Content │ └── Site.css │ ├── Controllers │ └── HomeController.cs │ ├── Global.asax │ ├── Global.asax.cs │ ├── Helpers │ └── ListModelBindingExtensions.cs │ ├── ListModelBindingWeb.csproj │ ├── Models │ ├── Book.cs │ └── BookEditModel.cs │ ├── Properties │ └── AssemblyInfo.cs │ ├── Scripts │ ├── highlightFade.js │ └── jquery-1.4.2.js │ ├── Views │ ├── Home │ │ ├── EditorFor.aspx │ │ ├── EditorTemplate.aspx │ │ ├── Index.aspx │ │ ├── NonSequential.aspx │ │ └── Sequential.aspx │ ├── Shared │ │ ├── EditorTemplates │ │ │ └── Book.ascx │ │ └── Site.Master │ └── Web.config │ └── Web.config ├── MiscUtils ├── AttributeExtensions.cs ├── Ensure.cs ├── MiscUtils.csproj ├── PathString.cs ├── Properties │ └── AssemblyInfo.cs └── StringEquivalent.cs ├── MiscUtilsTests ├── AttributeExtensionsTests.cs ├── MiscUtilsTests.csproj ├── PathStringTests.cs ├── Properties │ └── AssemblyInfo.cs └── packages.config ├── MvcHaack.Ajax.DemoWeb ├── App_Start │ ├── AjaxDemoAppStart.cs │ └── EntityFramework.SqlServerCompact.cs ├── Areas │ └── MvcAjaxDemo │ │ ├── AjaxDemoAreaRegistration.cs │ │ ├── Content │ │ └── Site.css │ │ ├── Controllers │ │ ├── ComicsController.cs │ │ ├── ComicsDemoController.cs │ │ ├── HomeController.cs │ │ └── PublishersController.cs │ │ ├── Models │ │ ├── ComicBook.cs │ │ ├── ComicContext.cs │ │ └── Publisher.cs │ │ └── Views │ │ ├── Home │ │ ├── ComicsDemo.cshtml │ │ ├── ComicsPostDemo.cshtml │ │ ├── Index.cshtml │ │ ├── KnockoutDemo.cshtml │ │ └── SecureComicsPostDemo.cshtml │ │ ├── Shared │ │ └── _Layout.cshtml │ │ ├── Web.config │ │ └── _ViewStart.cshtml ├── Global.asax ├── Global.asax.cs ├── MvcHaack.Ajax.DemoWeb.csproj ├── Properties │ └── AssemblyInfo.cs ├── Scripts │ ├── comicsdemo.js │ ├── jQuery.tmpl.js │ ├── jQuery.tmpl.min.js │ ├── jquery-1.6.2-vsdoc.js │ ├── jquery-1.6.2.js │ ├── jquery-1.6.2.min.js │ ├── knockout-1.2.1.debug.js │ └── knockout-1.2.1.js ├── Web.Debug.config ├── Web.Release.config ├── Web.config ├── _bin_deployableAssemblies │ ├── Microsoft.Web.Infrastructure.dll │ ├── System.Web.Helpers.dll │ ├── System.Web.Mvc.dll │ ├── System.Web.Razor.dll │ ├── System.Web.WebPages.Deployment.dll │ ├── System.Web.WebPages.Razor.dll │ └── System.Web.WebPages.dll ├── default.html └── packages.config ├── MvcHaack.Ajax.V2 ├── JsonActionInvoker.cs ├── JsonController.cs ├── JsonRoute.cs ├── MvcHaack.Ajax.V2.csproj ├── MvcHaack.Ajax.V2.nuspec ├── Properties │ └── AssemblyInfo.cs ├── ValidateJsonAntiForgeryTokenAttribute.cs └── packages.config ├── MvcHaack.Ajax ├── JsonActionInvoker.cs ├── JsonController.cs ├── JsonRoute.cs ├── MvcHaack.Ajax.csproj ├── MvcHaack.Ajax.csproj.orig ├── MvcHaack.Ajax.nuspec ├── Properties │ └── AssemblyInfo.cs └── ValidateJsonAntiForgeryTokenAttribute.cs ├── MvcHaack.ControllerInspector.DemoWeb ├── Content │ └── Site.css ├── Controllers │ ├── HomeController.cs │ ├── MistakeController.cs │ └── TypoControler.cs ├── Global.asax ├── Global.asax.cs ├── MvcHaack.ControllerInspector.DemoWeb.csproj ├── MvcHaack.ControllerInspector.DemoWeb.csproj.orig ├── Properties │ └── AssemblyInfo.cs ├── Views │ ├── Home │ │ └── Index.cshtml │ ├── Shared │ │ ├── Error.cshtml │ │ └── _Layout.cshtml │ ├── Web.config │ └── _ViewStart.cshtml ├── Web.Debug.config ├── Web.Release.config └── Web.config ├── MvcHaack.ControllerInspector ├── AppStart.cs ├── ControllerDetailer.cs ├── ControllerDetails.cshtml ├── ControllerDetails.generated.cs ├── ControllerValidator.cs ├── InspectorActionInvoker.cs ├── InspectorControllerFactory.cs ├── MvcHaack.ControllerInspector.csproj ├── MvcHaack.ControllerInspector.nuspec ├── Properties │ └── AssemblyInfo.cs └── packages.config ├── MvcHaack.ViewMobilizer ├── MvcHaack.ViewMobilizer.csproj ├── MvcHaack.ViewMobilizer.nuspec ├── MvcHaack.ViewMobilizer.zip ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ └── Resources.resx ├── Resources │ └── ViewMobilizer.ico ├── ViewMobilizerForm.Designer.cs ├── ViewMobilizerForm.cs ├── ViewMobilizerForm.resx ├── ViewMobilizerModel.cs ├── ViewMobilizerRecipe.cs └── packages.config ├── ViewMobilizerTests ├── Properties │ └── AssemblyInfo.cs ├── ViewMobilizerModelTests.cs ├── ViewMobilizerTests.csproj └── packages.config ├── WebApiHaack.DemoWeb ├── Api │ └── CommentsApi.cs ├── AppStart │ └── CommentsConfiguration.cs ├── Global.asax ├── Global.asax.cs ├── Models │ └── Comment.cs ├── Properties │ └── AssemblyInfo.cs ├── Web.Debug.config ├── Web.Release.config ├── Web.config ├── WebApiHaack.DemoWeb.csproj ├── default.htm ├── logon.htm └── packages.config ├── WebApiHaack ├── ConfigExtensions.cs ├── OperationHandlers │ └── AuthOperationHandler.cs ├── Properties │ └── AssemblyInfo.cs ├── RequireAuthorizationAttribute.cs ├── WebApiHaack.csproj └── packages.config └── WindowPlacementRxDemo ├── App.xaml ├── App.xaml.cs ├── MainWindow.xaml ├── MainWindow.xaml.cs ├── Properties ├── AssemblyInfo.cs ├── Resources.Designer.cs ├── Resources.resx ├── Settings.Designer.cs └── Settings.settings ├── WindowPlacement.cs ├── WindowPlacementRxDemo.csproj ├── app.config └── packages.config /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | *.sln merge=union 7 | *.csproj merge=union 8 | *.vbproj merge=union 9 | *.fsproj merge=union 10 | *.dbproj merge=union 11 | 12 | # Standard to msysgit 13 | *.doc diff=astextplain 14 | *.DOC diff=astextplain 15 | *.docx diff=astextplain 16 | *.DOCX diff=astextplain 17 | *.dot diff=astextplain 18 | *.DOT diff=astextplain 19 | *.pdf diff=astextplain 20 | *.PDF diff=astextplain 21 | *.rtf diff=astextplain 22 | *.RTF diff=astextplain 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.suo 2 | *.user 3 | *.FileListAbsolute.txt 4 | bin/ 5 | obj/ 6 | *.ncb 7 | *.nlb 8 | *.aps 9 | *.clw 10 | *.pdb 11 | *.obj 12 | *.exe 13 | *.pch 14 | *.vspscc 15 | *_i.c 16 | *_p.c 17 | *.tlb 18 | *.tlh 19 | *.bak 20 | *.[Cc]ache 21 | *.ilk 22 | *.log 23 | *.lib 24 | *.sbr 25 | *.scc 26 | *.sig 27 | _ReSharper*/ 28 | *.orig 29 | src/packages/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) Phil Haack 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Description 2 | 3 | CodeHaacks is a collection of prototypes, samples, proof-of-concepts. None of this is meant to be 4 | used in production code, but you can take any of the ideas you like and try them out in your own 5 | projects. 6 | 7 | See the following URLs for more details: 8 | 9 | * http://haacked.com/archive/2011/08/18/calling-asp-net-mvc-action-methods-from-javascript.aspx 10 | * http://haacked.com/archive/2011/08/10/writing-an-asp-net-mvc-controller-inspector.aspx 11 | -------------------------------------------------------------------------------- /build-packages.bat: -------------------------------------------------------------------------------- 1 | src\.nuget\nuget pack src\AspNetHaack\AspNetHaack.csproj -Symbols 2 | src\.nuget\nuget pack src\MvcHaack.ControllerInspector\MvcHaack.ControllerInspector.csproj -Symbols 3 | src\.nuget\nuget pack src\MvcHaack.Ajax\MvcHaack.Ajax.csproj -Symbols 4 | src\.nuget\nuget pack src\MvcHaack.Ajax.V2\MvcHaack.Ajax.V2.csproj -Symbols 5 | src\.nuget\nuget pack src\MvcHaack.ViewMobilizer\MvcHaack.ViewMobilizer.nuspec -Symbols -------------------------------------------------------------------------------- /src/.nuget/NuGet.Config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/.nuget/NuGet.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haacked/CodeHaacks/9d6dd8b6c9498d5cfca38580667c05ca2321b8de/src/.nuget/NuGet.exe -------------------------------------------------------------------------------- /src/.nuget/NuGet.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildProjectDirectory)\..\ 5 | $([System.IO.Path]::Combine($(SolutionDir), ".nuget")) 6 | $(NuGetToolsPath)\nuget.exe 7 | $([System.IO.Path]::Combine($(ProjectDir), "packages.config")) 8 | $([System.IO.Path]::Combine($(SolutionDir), "packages")) 9 | $(TargetDir.Trim('\\')) 10 | 11 | 12 | "" 13 | 14 | 15 | false 16 | 17 | 18 | false 19 | 20 | 21 | "$(NuGetExePath)" install "$(PackagesConfig)" -source $(PackageSources) -o "$(PackagesDir)" 22 | "$(NuGetExePath)" pack "$(ProjectPath)" -p Configuration=$(Configuration) -o "$(PackageOutputDir)" -symbols 23 | 24 | 25 | 26 | RestorePackages; 27 | $(BuildDependsOn); 28 | 29 | 30 | 31 | 32 | $(BuildDependsOn); 33 | BuildPackage; 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 46 | 47 | 48 | 49 | 51 | 52 | -------------------------------------------------------------------------------- /src/AspNetHaack.DemoWeb/App_Start/FormsAuthenticationConfig.cs: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using AspNetHaack.DemoWeb.App_Start; 3 | using Microsoft.Web.Infrastructure.DynamicModuleHelper; 4 | 5 | [assembly: PreApplicationStartMethod(typeof(FormsAuthenticationConfig), "Register")] 6 | namespace AspNetHaack.DemoWeb.App_Start { 7 | public static class FormsAuthenticationConfig { 8 | public static void Register() { 9 | DynamicModuleUtility.RegisterModule(typeof(SuppressFormsAuthenticationRedirectModule)); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/AspNetHaack.DemoWeb/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | 3 | namespace AspNetHaack.DemoWeb.Controllers { 4 | public class HomeController : Controller { 5 | public ActionResult Index() { 6 | ViewBag.Message = "Welcome to ASP.NET MVC!"; 7 | 8 | return View(); 9 | } 10 | 11 | [Authorize] 12 | public ActionResult About() { 13 | return Json(new { some = "thing" }); 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/AspNetHaack.DemoWeb/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="AspNetHaack.DemoWeb.MvcApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /src/AspNetHaack.DemoWeb/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 AspNetHaack.DemoWeb { 9 | // Note: For instructions on enabling IIS6 or IIS7 classic mode, 10 | // visit http://go.microsoft.com/?LinkId=9394801 11 | 12 | public class MvcApplication : System.Web.HttpApplication { 13 | public static void RegisterGlobalFilters(GlobalFilterCollection filters) { 14 | filters.Add(new HandleErrorAttribute()); 15 | } 16 | 17 | public static void RegisterRoutes(RouteCollection routes) { 18 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 19 | 20 | routes.MapRoute( 21 | "Default", // Route name 22 | "{controller}/{action}/{id}", // URL with parameters 23 | new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults 24 | ); 25 | 26 | } 27 | 28 | protected void Application_Start() { 29 | AreaRegistration.RegisterAllAreas(); 30 | 31 | RegisterGlobalFilters(GlobalFilters.Filters); 32 | RegisterRoutes(RouteTable.Routes); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/AspNetHaack.DemoWeb/Models/AccountModels.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Globalization; 5 | using System.Web.Mvc; 6 | using System.Web.Security; 7 | 8 | namespace AspNetHaack.DemoWeb.Models { 9 | 10 | public class ChangePasswordModel { 11 | [Required] 12 | [DataType(DataType.Password)] 13 | [Display(Name = "Current password")] 14 | public string OldPassword { get; set; } 15 | 16 | [Required] 17 | [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] 18 | [DataType(DataType.Password)] 19 | [Display(Name = "New password")] 20 | public string NewPassword { get; set; } 21 | 22 | [DataType(DataType.Password)] 23 | [Display(Name = "Confirm new password")] 24 | [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")] 25 | public string ConfirmPassword { get; set; } 26 | } 27 | 28 | public class LogOnModel { 29 | [Required] 30 | [Display(Name = "User name")] 31 | public string UserName { get; set; } 32 | 33 | [Required] 34 | [DataType(DataType.Password)] 35 | [Display(Name = "Password")] 36 | public string Password { get; set; } 37 | 38 | [Display(Name = "Remember me?")] 39 | public bool RememberMe { get; set; } 40 | } 41 | 42 | public class RegisterModel { 43 | [Required] 44 | [Display(Name = "User name")] 45 | public string UserName { get; set; } 46 | 47 | [Required] 48 | [DataType(DataType.EmailAddress)] 49 | [Display(Name = "Email address")] 50 | public string Email { get; set; } 51 | 52 | [Required] 53 | [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] 54 | [DataType(DataType.Password)] 55 | [Display(Name = "Password")] 56 | public string Password { get; set; } 57 | 58 | [DataType(DataType.Password)] 59 | [Display(Name = "Confirm password")] 60 | [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] 61 | public string ConfirmPassword { get; set; } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/AspNetHaack.DemoWeb/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("AspNetHaack.DemoWeb")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("AspNetHaack.DemoWeb")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2011")] 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("3d721406-cb3e-496e-99d7-1dd62cf0b17c")] 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 | -------------------------------------------------------------------------------- /src/AspNetHaack.DemoWeb/Scripts/jquery.unobtrusive-ajax.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | ** Unobtrusive Ajax support library for jQuery 3 | ** Copyright (C) Microsoft Corporation. All rights reserved. 4 | */ 5 | (function(a){var b="unobtrusiveAjaxClick",g="unobtrusiveValidation";function c(d,b){var a=window,c=(d||"").split(".");while(a&&c.length)a=a[c.shift()];if(typeof a==="function")return a;b.push(d);return Function.constructor.apply(null,b)}function d(a){return a==="GET"||a==="POST"}function f(b,a){!d(a)&&b.setRequestHeader("X-HTTP-Method-Override",a)}function h(c,b,e){var d;if(e.indexOf("application/x-javascript")!==-1)return;d=(c.getAttribute("data-ajax-mode")||"").toUpperCase();a(c.getAttribute("data-ajax-update")).each(function(f,c){var e;switch(d){case"BEFORE":e=c.firstChild;a("
").html(b).contents().each(function(){c.insertBefore(this,e)});break;case"AFTER":a("
").html(b).contents().each(function(){c.appendChild(this)});break;default:a(c).html(b)}})}function e(b,e){var j,k,g,i;j=b.getAttribute("data-ajax-confirm");if(j&&!window.confirm(j))return;k=a(b.getAttribute("data-ajax-loading"));i=b.getAttribute("data-ajax-loading-duration")||0;a.extend(e,{type:b.getAttribute("data-ajax-method")||undefined,url:b.getAttribute("data-ajax-url")||undefined,beforeSend:function(d){var a;f(d,g);a=c(b.getAttribute("data-ajax-begin"),["xhr"]).apply(this,arguments);a!==false&&k.show(i);return a},complete:function(){k.hide(i);c(b.getAttribute("data-ajax-complete"),["xhr","status"]).apply(this,arguments)},success:function(a,e,d){h(b,a,d.getResponseHeader("Content-Type")||"text/html");c(b.getAttribute("data-ajax-success"),["data","status","xhr"]).apply(this,arguments)},error:c(b.getAttribute("data-ajax-failure"),["xhr","status","error"])});e.data.push({name:"X-Requested-With",value:"XMLHttpRequest"});g=e.type.toUpperCase();if(!d(g)){e.type="POST";e.data.push({name:"X-HTTP-Method-Override",value:g})}a.ajax(e)}function i(c){var b=a(c).data(g);return!b||!b.validate||b.validate()}a("a[data-ajax=true]").live("click",function(a){a.preventDefault();e(this,{url:this.href,type:"GET",data:[]})});a("form[data-ajax=true] input[type=image]").live("click",function(c){var g=c.target.name,d=a(c.target),f=d.parents("form")[0],e=d.offset();a(f).data(b,[{name:g+".x",value:Math.round(c.pageX-e.left)},{name:g+".y",value:Math.round(c.pageY-e.top)}]);setTimeout(function(){a(f).removeData(b)},0)});a("form[data-ajax=true] :submit").live("click",function(c){var e=c.target.name,d=a(c.target).parents("form")[0];a(d).data(b,e?[{name:e,value:c.target.value}]:[]);setTimeout(function(){a(d).removeData(b)},0)});a("form[data-ajax=true]").live("submit",function(d){var c=a(this).data(b)||[];d.preventDefault();if(!i(this))return;e(this,{url:this.action,type:this.method||"GET",data:c.concat(a(this).serializeArray())})})})(jQuery); -------------------------------------------------------------------------------- /src/AspNetHaack.DemoWeb/Views/Account/LogOn.cshtml: -------------------------------------------------------------------------------- 1 | @model AspNetHaack.DemoWeb.Models.LogOnModel 2 | 3 | @{ 4 | ViewBag.Title = "Log On"; 5 | } 6 | 7 |

8 | You've been redirected to the login page. 9 |

-------------------------------------------------------------------------------- /src/AspNetHaack.DemoWeb/Views/Account/Register.cshtml: -------------------------------------------------------------------------------- 1 | @model AspNetHaack.DemoWeb.Models.RegisterModel 2 | 3 | @{ 4 | ViewBag.Title = "Register"; 5 | } 6 | 7 |

Create a New Account

8 |

9 | Use the form below to create a new account. 10 |

11 |

12 | Passwords are required to be a minimum of @Membership.MinRequiredPasswordLength characters in length. 13 |

14 | 15 | @using (Html.BeginForm()) { 16 | @Html.ValidationSummary(true, "Account creation was unsuccessful. Please correct the errors and try again.") 17 |
18 |
19 | Account Information 20 | 21 |
22 | @Html.LabelFor(m => m.UserName) 23 |
24 |
25 | @Html.TextBoxFor(m => m.UserName) 26 | @Html.ValidationMessageFor(m => m.UserName) 27 |
28 | 29 |
30 | @Html.LabelFor(m => m.Email) 31 |
32 |
33 | @Html.TextBoxFor(m => m.Email) 34 | @Html.ValidationMessageFor(m => m.Email) 35 |
36 | 37 |
38 | @Html.LabelFor(m => m.Password) 39 |
40 |
41 | @Html.PasswordFor(m => m.Password) 42 | @Html.ValidationMessageFor(m => m.Password) 43 |
44 | 45 |
46 | @Html.LabelFor(m => m.ConfirmPassword) 47 |
48 |
49 | @Html.PasswordFor(m => m.ConfirmPassword) 50 | @Html.ValidationMessageFor(m => m.ConfirmPassword) 51 |
52 | 53 |

54 | 55 |

56 |
57 |
58 | } 59 | -------------------------------------------------------------------------------- /src/AspNetHaack.DemoWeb/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Home Page"; 3 | } 4 | 5 |

6 | 7 | 25 | 26 |
<script type="text/javascript">
27 |   $(function () {
28 |     $.ajax({
29 |       url: '/home/about',
30 |       cache: false,
31 |       type: 'POST',
32 |       contentType: 'application/json; charset=utf-8',
33 |       statusCode: {
34 |         200: function (data) {
35 |           $('#message').html('Fail! HTTP 200 response');
36 |         },
37 |         401: function (data) {
38 |           $('#message').html('Success! HTTP 401 response!');
39 |         }
40 |       }
41 |     });
42 |   });
43 | </script>
44 | -------------------------------------------------------------------------------- /src/AspNetHaack.DemoWeb/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @model System.Web.Mvc.HandleErrorInfo 2 | 3 | @{ 4 | ViewBag.Title = "Error"; 5 | } 6 | 7 |

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

10 | -------------------------------------------------------------------------------- /src/AspNetHaack.DemoWeb/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | @ViewBag.Title 6 | 7 | 8 | 9 | 10 |
11 |
12 |
13 |

My MVC Application

14 |
15 |
16 | @Html.Partial("_LogOnPartial") 17 |
18 | 24 |
25 |
26 | @RenderBody() 27 |
28 |
29 |
30 |
31 | 32 | 33 | -------------------------------------------------------------------------------- /src/AspNetHaack.DemoWeb/Views/Shared/_LogOnPartial.cshtml: -------------------------------------------------------------------------------- 1 | @if(Request.IsAuthenticated) { 2 | Welcome @User.Identity.Name! 3 | [ @Html.ActionLink("Log Off", "LogOff", "Account") ] 4 | } 5 | else { 6 | @:[ @Html.ActionLink("Log On", "LogOn", "Account") ] 7 | } 8 | -------------------------------------------------------------------------------- /src/AspNetHaack.DemoWeb/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 | 39 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/AspNetHaack.DemoWeb/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "~/Views/Shared/_Layout.cshtml"; 3 | } -------------------------------------------------------------------------------- /src/AspNetHaack.DemoWeb/Web.Debug.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /src/AspNetHaack.DemoWeb/Web.Release.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | -------------------------------------------------------------------------------- /src/AspNetHaack.DemoWeb/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/AspNetHaack/App_Start/FormsAuthenticationConfig.cs.pp: -------------------------------------------------------------------------------- 1 | using System.Web; 2 | using $rootnamespace$.App_Start; 3 | using Microsoft.Web.Infrastructure.DynamicModuleHelper; 4 | 5 | [assembly: PreApplicationStartMethod(typeof(FormsAuthenticationConfig), "Register")] 6 | namespace $rootnamespace$.App_Start { 7 | public static class FormsAuthenticationConfig { 8 | public static void Register() { 9 | DynamicModuleUtility.RegisterModule(typeof(SuppressFormsAuthenticationRedirectModule)); 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/AspNetHaack/AspNetHaack.nuspec: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $id$ 5 | $version$ 6 | $author$ 7 | $author$ 8 | http://www.opensource.org/licenses/mit-license.php 9 | https://github.com/Haacked/CodeHaacks 10 | http://haacked.com/images/Inspector-120x120.png 11 | false 12 | $description$ 13 | aspnetmvc asp.net aspnet asp.net-mvc membership formsauth forms-authentication webapi 14 | 15 | -------------------------------------------------------------------------------- /src/AspNetHaack/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("AspNetHaack")] 8 | [assembly: AssemblyDescription("A collection of extensions to core ASP.NET including a way to suppress login page redirects caused by the forms authentication module")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("Phil Haack")] 11 | [assembly: AssemblyProduct("AspNetHaack")] 12 | [assembly: AssemblyCopyright("Copyright © Phil Haack 2011")] 13 | 14 | // Setting ComVisible to false makes the types in this assembly not visible 15 | // to COM components. If you need to access a type in this assembly from 16 | // COM, set the ComVisible attribute to true on that type. 17 | [assembly: ComVisible(false)] 18 | 19 | // The following GUID is for the ID of the typelib if this project is exposed to COM 20 | [assembly: Guid("e77bac1b-301e-406e-8123-951e8b62d28f")] 21 | 22 | // Version information for an assembly consists of the following four values: 23 | // 24 | // Major Version 25 | // Minor Version 26 | // Build Number 27 | // Revision 28 | // 29 | // You can specify all the values or you can default the Build and Revision Numbers 30 | // by using the '*' as shown below: 31 | // [assembly: AssemblyVersion("1.0.*")]i 32 | [assembly: AssemblyVersion("0.0.1.0")] 33 | [assembly: AssemblyFileVersion("0.0.1.0")] 34 | -------------------------------------------------------------------------------- /src/AspNetHaack/SuppressFormsAuthenticationRedirectModule.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Web; 3 | 4 | namespace AspNetHaack { 5 | public class SuppressFormsAuthenticationRedirectModule : IHttpModule { 6 | private static readonly object SuppressAuthenticationKey = new Object(); 7 | 8 | public static void SuppressAuthenticationRedirect(HttpContext context) { 9 | context.Items[SuppressAuthenticationKey] = true; 10 | } 11 | 12 | public static void SuppressAuthenticationRedirect(HttpContextBase context) { 13 | context.Items[SuppressAuthenticationKey] = true; 14 | } 15 | 16 | public void Init(HttpApplication context) { 17 | context.PostReleaseRequestState += OnPostReleaseRequestState; 18 | context.EndRequest += OnEndRequest; 19 | } 20 | 21 | private void OnPostReleaseRequestState(object source, EventArgs args) { 22 | var context = (HttpApplication)source; 23 | var response = context.Response; 24 | var request = context.Request; 25 | 26 | if (response.StatusCode == 401 && request.Headers["X-Requested-With"] == "XMLHttpRequest") { 27 | SuppressAuthenticationRedirect(context.Context); 28 | } 29 | } 30 | 31 | private void OnEndRequest(object source, EventArgs args) { 32 | var context = (HttpApplication)source; 33 | var response = context.Response; 34 | 35 | if (context.Context.Items.Contains(SuppressAuthenticationKey)) { 36 | response.TrySkipIisCustomErrors = true; 37 | response.ClearContent(); 38 | response.StatusCode = 401; 39 | response.RedirectLocation = null; 40 | } 41 | } 42 | 43 | public void Dispose() { 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/AspNetHaack/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/CodeHaacks.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | NEXT_LINE 3 | NEXT_LINE 4 | NEXT_LINE 5 | False 6 | False -------------------------------------------------------------------------------- /src/ControllerInspectorTests/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("ControllerInspectorTests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("ControllerInspectorTests")] 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("b48d9290-0473-4cca-bf06-12cae3686d88")] 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 | -------------------------------------------------------------------------------- /src/ControllerInspectorTests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /src/JsonHijackDemo/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | 3 | namespace JsonHijackDemo.Controllers 4 | { 5 | public class HomeController : Controller 6 | { 7 | public ActionResult Index() 8 | { 9 | ViewBag.Message = "JSON Hijack Demo"; 10 | 11 | return View(); 12 | } 13 | 14 | [Authorize] 15 | public JsonResult AdminBalances() 16 | { 17 | var balances = new[] 18 | { 19 | new {Id = 1, Balance = 3.14}, 20 | new {Id = 2, Balance = 2.72}, 21 | new {Id = 3, Balance = 1.62} 22 | }; 23 | return Json(balances, JsonRequestBehavior.AllowGet); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/JsonHijackDemo/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="JsonHijackDemo.MvcApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /src/JsonHijackDemo/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 JsonHijackDemo 9 | { 10 | // Note: For instructions on enabling IIS6 or IIS7 classic mode, 11 | // visit http://go.microsoft.com/?LinkId=9394801 12 | 13 | public class MvcApplication : System.Web.HttpApplication 14 | { 15 | public static void RegisterGlobalFilters(GlobalFilterCollection filters) 16 | { 17 | filters.Add(new HandleErrorAttribute()); 18 | } 19 | 20 | public static void RegisterRoutes(RouteCollection routes) 21 | { 22 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 23 | 24 | routes.MapRoute( 25 | "Default", // Route name 26 | "{controller}/{action}/{id}", // URL with parameters 27 | new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults 28 | ); 29 | 30 | } 31 | 32 | protected void Application_Start() 33 | { 34 | AreaRegistration.RegisterAllAreas(); 35 | 36 | RegisterGlobalFilters(GlobalFilters.Filters); 37 | RegisterRoutes(RouteTable.Routes); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /src/JsonHijackDemo/Models/AccountModels.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Globalization; 5 | using System.Web.Mvc; 6 | using System.Web.Security; 7 | 8 | namespace JsonHijackDemo.Models 9 | { 10 | 11 | public class ChangePasswordModel 12 | { 13 | [Required] 14 | [DataType(DataType.Password)] 15 | [Display(Name = "Current password")] 16 | public string OldPassword { get; set; } 17 | 18 | [Required] 19 | [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] 20 | [DataType(DataType.Password)] 21 | [Display(Name = "New password")] 22 | public string NewPassword { get; set; } 23 | 24 | [DataType(DataType.Password)] 25 | [Display(Name = "Confirm new password")] 26 | [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")] 27 | public string ConfirmPassword { get; set; } 28 | } 29 | 30 | public class LogOnModel 31 | { 32 | [Required] 33 | [Display(Name = "User name")] 34 | public string UserName { get; set; } 35 | 36 | [Required] 37 | [DataType(DataType.Password)] 38 | [Display(Name = "Password")] 39 | public string Password { get; set; } 40 | 41 | [Display(Name = "Remember me?")] 42 | public bool RememberMe { get; set; } 43 | } 44 | 45 | public class RegisterModel 46 | { 47 | [Required] 48 | [Display(Name = "User name")] 49 | public string UserName { get; set; } 50 | 51 | [Required] 52 | [DataType(DataType.EmailAddress)] 53 | [Display(Name = "Email address")] 54 | public string Email { get; set; } 55 | 56 | [Required] 57 | [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)] 58 | [DataType(DataType.Password)] 59 | [Display(Name = "Password")] 60 | public string Password { get; set; } 61 | 62 | [DataType(DataType.Password)] 63 | [Display(Name = "Confirm password")] 64 | [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] 65 | public string ConfirmPassword { get; set; } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/JsonHijackDemo/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("JsonHijackDemo")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("JsonHijackDemo")] 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("cc453b96-3c56-4133-a0aa-ded07b465398")] 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 | -------------------------------------------------------------------------------- /src/JsonHijackDemo/Views/Account/ChangePassword.cshtml: -------------------------------------------------------------------------------- 1 | @model JsonHijackDemo.Models.ChangePasswordModel 2 | 3 | @{ 4 | ViewBag.Title = "Change Password"; 5 | } 6 | 7 |

Change Password

8 |

9 | Use the form below to change your password. 10 |

11 |

12 | New passwords are required to be a minimum of @Membership.MinRequiredPasswordLength characters in length. 13 |

14 | 15 | 16 | 17 | 18 | @using (Html.BeginForm()) { 19 | @Html.ValidationSummary(true, "Password change was unsuccessful. Please correct the errors and try again.") 20 |
21 |
22 | Account Information 23 | 24 |
25 | @Html.LabelFor(m => m.OldPassword) 26 |
27 |
28 | @Html.PasswordFor(m => m.OldPassword) 29 | @Html.ValidationMessageFor(m => m.OldPassword) 30 |
31 | 32 |
33 | @Html.LabelFor(m => m.NewPassword) 34 |
35 |
36 | @Html.PasswordFor(m => m.NewPassword) 37 | @Html.ValidationMessageFor(m => m.NewPassword) 38 |
39 | 40 |
41 | @Html.LabelFor(m => m.ConfirmPassword) 42 |
43 |
44 | @Html.PasswordFor(m => m.ConfirmPassword) 45 | @Html.ValidationMessageFor(m => m.ConfirmPassword) 46 |
47 | 48 |

49 | 50 |

51 |
52 |
53 | } 54 | -------------------------------------------------------------------------------- /src/JsonHijackDemo/Views/Account/ChangePasswordSuccess.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Change Password"; 3 | } 4 | 5 |

Change Password

6 |

7 | Your password has been changed successfully. 8 |

9 | -------------------------------------------------------------------------------- /src/JsonHijackDemo/Views/Account/LogOn.cshtml: -------------------------------------------------------------------------------- 1 | @model JsonHijackDemo.Models.LogOnModel 2 | 3 | @{ 4 | ViewBag.Title = "Log On"; 5 | } 6 | 7 |

Log On

8 |

9 | Please enter your user name and password. @Html.ActionLink("Register", "Register") if you don't have an account. 10 |

11 | 12 | 13 | 14 | 15 | @Html.ValidationSummary(true, "Login was unsuccessful. Please correct the errors and try again.") 16 | 17 | @using (Html.BeginForm()) { 18 |
19 |
20 | Account Information 21 | 22 |
23 | @Html.LabelFor(m => m.UserName) 24 |
25 |
26 | @Html.TextBoxFor(m => m.UserName) 27 | @Html.ValidationMessageFor(m => m.UserName) 28 |
29 | 30 |
31 | @Html.LabelFor(m => m.Password) 32 |
33 |
34 | @Html.PasswordFor(m => m.Password) 35 | @Html.ValidationMessageFor(m => m.Password) 36 |
37 | 38 |
39 | @Html.CheckBoxFor(m => m.RememberMe) 40 | @Html.LabelFor(m => m.RememberMe) 41 |
42 | 43 |

44 | 45 |

46 |
47 |
48 | } 49 | -------------------------------------------------------------------------------- /src/JsonHijackDemo/Views/Account/Register.cshtml: -------------------------------------------------------------------------------- 1 | @model JsonHijackDemo.Models.RegisterModel 2 | 3 | @{ 4 | ViewBag.Title = "Register"; 5 | } 6 | 7 |

Create a New Account

8 |

9 | Use the form below to create a new account. 10 |

11 |

12 | Passwords are required to be a minimum of @Membership.MinRequiredPasswordLength characters in length. 13 |

14 | 15 | 16 | 17 | 18 | @using (Html.BeginForm()) { 19 | @Html.ValidationSummary(true, "Account creation was unsuccessful. Please correct the errors and try again.") 20 |
21 |
22 | Account Information 23 | 24 |
25 | @Html.LabelFor(m => m.UserName) 26 |
27 |
28 | @Html.TextBoxFor(m => m.UserName) 29 | @Html.ValidationMessageFor(m => m.UserName) 30 |
31 | 32 |
33 | @Html.LabelFor(m => m.Email) 34 |
35 |
36 | @Html.TextBoxFor(m => m.Email) 37 | @Html.ValidationMessageFor(m => m.Email) 38 |
39 | 40 |
41 | @Html.LabelFor(m => m.Password) 42 |
43 |
44 | @Html.PasswordFor(m => m.Password) 45 | @Html.ValidationMessageFor(m => m.Password) 46 |
47 | 48 |
49 | @Html.LabelFor(m => m.ConfirmPassword) 50 |
51 |
52 | @Html.PasswordFor(m => m.ConfirmPassword) 53 | @Html.ValidationMessageFor(m => m.ConfirmPassword) 54 |
55 | 56 |

57 | 58 |

59 |
60 |
61 | } 62 | -------------------------------------------------------------------------------- /src/JsonHijackDemo/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Security Demos"; 3 | } 4 | 5 |

@ViewBag.Message

6 |

7 | 8 | This site is a sample used to demonstrate a JSON Hijacking Attack as described in 9 | this blog post. 10 |

11 | 12 |

13 | To see the attack in action, 14 | @if (!Request.IsAuthenticated) { 15 | @Html.ActionLink("first log in", "LogOn", "Account") @:(you might need to @Html.ActionLink("Register", "Register", "Account") first), and then 16 | } 17 | visit http://demo.haacked.com/security/JsonAttack.html. 18 | If nothing happens, your browser is safe from this specific attack. 19 |

20 | -------------------------------------------------------------------------------- /src/JsonHijackDemo/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @model System.Web.Mvc.HandleErrorInfo 2 | 3 | @{ 4 | ViewBag.Title = "Error"; 5 | } 6 | 7 |

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

10 | -------------------------------------------------------------------------------- /src/JsonHijackDemo/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | @ViewBag.Title 5 | 6 | 7 | 8 |
9 | 22 |
23 | @RenderBody() 24 |
25 | 27 |
28 | 29 | 30 | -------------------------------------------------------------------------------- /src/JsonHijackDemo/Views/Shared/_LogOnPartial.cshtml: -------------------------------------------------------------------------------- 1 | @if(Request.IsAuthenticated) { 2 | Welcome @User.Identity.Name! 3 | [ @Html.ActionLink("Log Off", "LogOff", "Account") ] 4 | } 5 | else { 6 | @:[ @Html.ActionLink("Log On", "LogOn", "Account") ] 7 | } 8 | -------------------------------------------------------------------------------- /src/JsonHijackDemo/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 | 39 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/JsonHijackDemo/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "~/Views/Shared/_Layout.cshtml"; 3 | } -------------------------------------------------------------------------------- /src/JsonHijackDemo/html/JsonAttack.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Json Hijack Demo 5 | 6 | 7 | 8 |

Your browser appears to be immune to this specific attack.

9 |

Your browser is succeptible to this attack and gave away some sensitive information. Doh!

10 |
IDs
11 |
Balances
12 | 13 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /src/JsonHijackDemo/html/README.md: -------------------------------------------------------------------------------- 1 | # Security Demos HTML files 2 | 3 | The `JsonAttack.html` file needs to be hosted on a separate server in order to demonstrate these security attacks. 4 | 5 | Currently, this is hosted at [http://demo.haacked.com/security/JsonAttack.html](http://demo.haacked.com/security/JsonAttack.html) -------------------------------------------------------------------------------- /src/ListModelBindingDemo/ListModelBindingDemo.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ListModelBindingWeb", "ListModelBindingWeb\ListModelBindingWeb.csproj", "{E4BD3AA8-2010-4C35-A7B7-8AE8072CAC74}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Any CPU = Debug|Any CPU 9 | Release|Any CPU = Release|Any CPU 10 | EndGlobalSection 11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 12 | {E4BD3AA8-2010-4C35-A7B7-8AE8072CAC74}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 13 | {E4BD3AA8-2010-4C35-A7B7-8AE8072CAC74}.Debug|Any CPU.Build.0 = Debug|Any CPU 14 | {E4BD3AA8-2010-4C35-A7B7-8AE8072CAC74}.Release|Any CPU.ActiveCfg = Release|Any CPU 15 | {E4BD3AA8-2010-4C35-A7B7-8AE8072CAC74}.Release|Any CPU.Build.0 = Release|Any CPU 16 | EndGlobalSection 17 | GlobalSection(SolutionProperties) = preSolution 18 | HideSolutionNode = FALSE 19 | EndGlobalSection 20 | EndGlobal 21 | -------------------------------------------------------------------------------- /src/ListModelBindingDemo/ListModelBindingWeb/Content/Site.css: -------------------------------------------------------------------------------- 1 | body 2 | { 3 | font-family: Verdana, Arial, Sans-Serif; 4 | font-size: 0.9em; 5 | } 6 | 7 | h1 8 | { 9 | font-family: Georgia, Times New Roman, Serif; 10 | } 11 | 12 | #main 13 | { 14 | width: 600px; 15 | margin: auto; 16 | } 17 | 18 | label 19 | { 20 | display: block; 21 | margin-top: 10px; 22 | margin-bottom: 4px; 23 | } 24 | 25 | textarea.source 26 | { 27 | width: 400px; 28 | height: 100px; 29 | } 30 | 31 | div.preview { 32 | width: 400px; 33 | min-height: 200px; 34 | border: solid 1px #000; 35 | background-color: #ffffec; 36 | padding: 5px; 37 | } 38 | 39 | /* Styles for validation helpers 40 | -----------------------------------------------------------*/ 41 | .field-validation-error 42 | { 43 | color: #ff0000; 44 | } 45 | 46 | .field-validation-valid 47 | { 48 | display: none; 49 | } 50 | 51 | .input-validation-error 52 | { 53 | border: 1px solid #ff0000; 54 | background-color: #ffeeee; 55 | } 56 | 57 | .validation-summary-errors 58 | { 59 | font-weight: bold; 60 | color: #ff0000; 61 | } 62 | 63 | .validation-summary-valid 64 | { 65 | display: none; 66 | } 67 | 68 | table th 69 | { 70 | text-align: left; 71 | } 72 | 73 | /* Styles for code formatting */ 74 | .csharpcode,.csharpcode pre{font-size:small;color:black;font-family:Consolas,"Courier New",Courier,Monospace;background-color:#fff;}.csharpcode pre{margin:0;}.csharpcode .rem{color:#008000;}.csharpcode .kwrd{color:#00f;}.csharpcode .str{color:#006080;}.csharpcode .op{color:#0000c0;}.csharpcode .preproc{color:#c63;}.csharpcode .asp{background-color:#ff0;}.csharpcode .html{color:#800000;}.csharpcode .attr{color:#f00;}.csharpcode .alt{background-color:#f4f4f4;width:100%;margin:0;}.csharpcode .lnum{color:#606060;} -------------------------------------------------------------------------------- /src/ListModelBindingDemo/ListModelBindingWeb/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 | using ListModelBindingWeb.Models; 7 | 8 | namespace ListModelBindingWeb.Controllers 9 | { 10 | public class HomeController : Controller 11 | { 12 | // Demo 1 13 | public ActionResult Index() 14 | { 15 | return View(); 16 | } 17 | 18 | [HttpPost] 19 | public ActionResult Index(ICollection numbers) { 20 | return View(numbers); 21 | } 22 | 23 | // Demo 2 24 | public ActionResult Sequential() 25 | { 26 | return View(); 27 | } 28 | 29 | [HttpPost] 30 | public ActionResult Sequential(ICollection books) 31 | { 32 | return View(books); 33 | } 34 | 35 | // Demo 3 36 | public ActionResult NonSequential() 37 | { 38 | return View(); 39 | } 40 | 41 | [HttpPost] 42 | public ActionResult NonSequential(ICollection books) 43 | { 44 | return View(books); 45 | } 46 | 47 | // Demo 4 48 | public ActionResult EditorTemplate() 49 | { 50 | var books = new Book[] { 51 | new Book {Title = "Curious George", Author = "H.A. Rey", DatePublished = DateTime.Parse("1973/2/23")}, 52 | new Book {Title = "Code Complete", Author = "H.A. Rey", DatePublished = DateTime.Parse("2004/6/9")}, 53 | new Book {Title = "The Two Towers", Author = "H.A. Rey", DatePublished = DateTime.Parse("2005/6/1")}, 54 | new Book {Title = "Homeland", Author = "RA Salvatore", DatePublished = DateTime.Parse("1990/9/19")}, 55 | new Book {Title = "Moby Dick", Author = "Herman Melville", DatePublished = DateTime.Parse("2008/1/1")} 56 | }; 57 | var model = new BookEditModel { Books = books.ToList() }; 58 | 59 | return View(model); 60 | } 61 | 62 | [HttpPost] 63 | public ActionResult EditorTemplate(BookEditModel model) 64 | { 65 | return View(model); 66 | } 67 | 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/ListModelBindingDemo/ListModelBindingWeb/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="ListModelBindingWeb.MvcApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /src/ListModelBindingDemo/ListModelBindingWeb/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 ListModelBindingWeb 9 | { 10 | // Note: For instructions on enabling IIS6 or IIS7 classic mode, 11 | // visit http://go.microsoft.com/?LinkId=9394801 12 | 13 | public class MvcApplication : System.Web.HttpApplication 14 | { 15 | public static void RegisterRoutes(RouteCollection routes) 16 | { 17 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 18 | 19 | routes.MapRoute( 20 | "Default", // Route name 21 | "{controller}/{action}/{id}", // URL with parameters 22 | new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults 23 | ); 24 | 25 | } 26 | 27 | protected void Application_Start() 28 | { 29 | AreaRegistration.RegisterAllAreas(); 30 | 31 | RegisterRoutes(RouteTable.Routes); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /src/ListModelBindingDemo/ListModelBindingWeb/Helpers/ListModelBindingExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Text.RegularExpressions; 3 | using System.Web.Mvc; 4 | 5 | namespace ListModelBindingWeb.Helpers 6 | { 7 | public static class ListModelBindingExtensions 8 | { 9 | static Regex _stripIndexerRegex = new Regex(@"\[(?\d+)\]", RegexOptions.Compiled); 10 | 11 | public static string GetIndexerFieldName(this TemplateInfo templateInfo) { 12 | string fieldName = templateInfo.GetFullHtmlFieldName("Index"); 13 | fieldName = _stripIndexerRegex.Replace(fieldName, string.Empty); 14 | if (fieldName.StartsWith(".")) { 15 | fieldName = fieldName.Substring(1); 16 | } 17 | return fieldName; 18 | } 19 | 20 | public static int GetIndex(this TemplateInfo templateInfo) 21 | { 22 | string fieldName = templateInfo.GetFullHtmlFieldName("Index"); 23 | var match = _stripIndexerRegex.Match(fieldName); 24 | if (match.Success) { 25 | return int.Parse(match.Groups["index"].Value); 26 | } 27 | return 0; 28 | } 29 | 30 | public static MvcHtmlString HiddenIndexerInputForModel(this HtmlHelper html) { 31 | string name = html.ViewData.TemplateInfo.GetIndexerFieldName(); 32 | object value = html.ViewData.TemplateInfo.GetIndex(); 33 | string markup = String.Format(@"", name, value); 34 | return MvcHtmlString.Create(markup); 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /src/ListModelBindingDemo/ListModelBindingWeb/Models/Book.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace ListModelBindingWeb.Models 4 | { 5 | public class Book 6 | { 7 | public string Title { get; set; } 8 | public string Author { get; set; } 9 | public DateTime DatePublished { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /src/ListModelBindingDemo/ListModelBindingWeb/Models/BookEditModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Web; 5 | 6 | namespace ListModelBindingWeb.Models 7 | { 8 | public class BookEditModel 9 | { 10 | public List Books {get; set;} 11 | } 12 | } -------------------------------------------------------------------------------- /src/ListModelBindingDemo/ListModelBindingWeb/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("ListModelBindingWeb")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("ListModelBindingWeb")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2010")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("94c952bf-d607-4fb4-b1be-e61df9cfd9fc")] 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 | -------------------------------------------------------------------------------- /src/ListModelBindingDemo/ListModelBindingWeb/Views/Home/EditorFor.aspx: -------------------------------------------------------------------------------- 1 | <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage>" %> 2 | 3 | 4 | Create 5 | 6 | 7 | 8 | 9 |

Unbroken Index with EditorFor

10 |

11 | This example shows the format where the indices for the form elements 12 | must form an unbroken chain of indices starting from 0 and increasing 13 | by 1. 14 |

15 | 16 | <% using (Html.BeginForm()) { %> 17 | <%: Html.ValidationSummary(true) %> 18 | 19 | 20 | 21 | 22 | 23 | 24 | <% for (int i = 0; i < 4; i++) { %> 25 | 26 | <%: Html.EditorFor(m = m[i]) %> 27 | 28 | <% } %> 29 |
TitleAuthorDate Published
30 |

31 | 32 |

33 | <% } //endusing%> 34 | 35 |
36 | 37 | -------------------------------------------------------------------------------- /src/ListModelBindingDemo/ListModelBindingWeb/Views/Home/Index.aspx: -------------------------------------------------------------------------------- 1 | <%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage>" %> 2 | 3 | 4 | Index 5 | 6 | 7 | 8 |

Binding to a list of numbers

9 | 10 |

11 | This shows the simple example of binding to a list of numbers. 12 | Notice that each form input simply has the same name. 13 |

14 | 15 | 16 | <% using (Html.BeginForm()) { %> 17 | 18 |
19 |
20 |
21 |
22 | 23 | 24 | 25 | <% } %> 26 | 27 |

The resulting markup

28 | 29 |
<form method="post" action="/Home/Index"> 
30 | 
31 |   <input type="text" name="ints" value="1" /> 
32 |   <input type="text" name="ints" value="4" /> 
33 |   <input type="text" name="ints" value="2" /> 
34 |   <input type="text" name="ints" value="8" /> 
35 |   
36 |   <input type="submit" /> 
37 | 
38 | </form>
39 | 40 | <% if (Model != null) { %> 41 |
42 |

The submitted values.

43 |
    44 | <% foreach(var number in Model) { %> 45 |
  • <%: number %>
  • 46 | <% } %> 47 |
48 | <% } %> 49 |
50 | -------------------------------------------------------------------------------- /src/ListModelBindingDemo/ListModelBindingWeb/Views/Shared/EditorTemplates/Book.ascx: -------------------------------------------------------------------------------- 1 | <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> 2 | 3 | 4 | 5 | <%: Html.TextBoxFor(m => m.Title) %> 6 | <%: Html.ValidationMessageFor(m => m.Title) %> 7 | 8 | 9 | <%: Html.TextBoxFor(m => m.Author) %> 10 | <%: Html.ValidationMessageFor(m => m.Author) %> 11 | 12 | 13 | <%: Html.TextBoxFor(m => m.DatePublished) %> 14 | <%: Html.ValidationMessageFor(m => m.DatePublished) %> 15 | 16 | 17 | 18 | <%: Html.HiddenIndexerInputForModel() %> 19 | Delete 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/ListModelBindingDemo/ListModelBindingWeb/Views/Shared/Site.Master: -------------------------------------------------------------------------------- 1 | <%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %> 2 | 3 | 4 | 5 | 6 | 7 | <asp:ContentPlaceHolder ID="TitleContent" runat="server" /> 8 | 9 | 10 | 11 | 12 | 24 | 25 | 26 | 27 |
28 |

Model Binding To A List Demos

29 |

30 | Primitives | Complex Objects (Sequential) | Complex Objects (Non-Sequential) | Editor Template with ViewModel 31 |

32 | 33 | 34 | 35 | 36 | 37 |
38 | 39 | 40 | -------------------------------------------------------------------------------- /src/ListModelBindingDemo/ListModelBindingWeb/Views/Web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 16 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/ListModelBindingDemo/ListModelBindingWeb/Web.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 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 | -------------------------------------------------------------------------------- /src/MiscUtils/Ensure.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MiscUtils 4 | { 5 | /// 6 | /// Ensure input parameters 7 | /// 8 | public static class Ensure 9 | { 10 | public static void ArgumentNotNull([ValidatedNotNull] object value, string name) 11 | { 12 | if (value != null) return; 13 | 14 | throw new ArgumentNullException(name); 15 | } 16 | 17 | public static void ArgumentNonNegative(int value, string name) 18 | { 19 | if (value > -1) return; 20 | 21 | throw new ArgumentException("The argument must be non-negative", name); 22 | } 23 | 24 | public static void ArgumentNotNullOrEmptyString([ValidatedNotNull] string value, string name) 25 | { 26 | ArgumentNotNull(value, name); 27 | if (!string.IsNullOrWhiteSpace(value)) return; 28 | 29 | throw new ArgumentException("String cannot be empty", name); 30 | } 31 | } 32 | 33 | // Tells CodeAnalysis that this argument is being validated 34 | // to be not null. Great for guard methods. 35 | [AttributeUsage(AttributeTargets.Parameter)] 36 | internal sealed class ValidatedNotNullAttribute : Attribute 37 | { 38 | // Internal so it doesn't conflict with the potential billion 39 | // other implementations of this attribute. 40 | } 41 | } -------------------------------------------------------------------------------- /src/MiscUtils/MiscUtils.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {52D341CE-48CE-4C0C-98E7-9935B300EB2C} 9 | Library 10 | Properties 11 | MiscUtils 12 | MiscUtils 13 | v4.0 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 57 | -------------------------------------------------------------------------------- /src/MiscUtils/PathString.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using System.Linq; 4 | using System.Runtime.Serialization; 5 | 6 | namespace MiscUtils 7 | { 8 | [Serializable] 9 | public class PathString : StringEquivalent 10 | { 11 | public PathString(string pathString) : base(NormalizePath(pathString)) 12 | { 13 | } 14 | 15 | protected PathString(SerializationInfo info, StreamingContext context) : base(info) 16 | { 17 | } 18 | 19 | // So the XmlSerializer can create this. 20 | protected PathString() 21 | { 22 | } 23 | 24 | public override PathString Combine(string path) 25 | { 26 | Ensure.ArgumentNotNull(path, "path"); 27 | 28 | if (path.StartsWith(@"\", StringComparison.Ordinal)) 29 | { 30 | path = path.Substring(1); 31 | } 32 | 33 | try 34 | { 35 | return Path.Combine(Value, path); 36 | } 37 | catch (ArgumentException) 38 | { 39 | return AppendPath(Value, path); 40 | } 41 | } 42 | 43 | private static string AppendPath(string source, string addition) 44 | { 45 | if (source.Last() != Path.DirectorySeparatorChar) source += "/"; 46 | if (addition.First() == '/') addition = addition.Substring(1); 47 | return source + addition; 48 | } 49 | 50 | public static implicit operator PathString(string value) 51 | { 52 | return value == null ? null : new PathString(value); 53 | } 54 | 55 | public static implicit operator string(PathString path) 56 | { 57 | return path == null ? null : path.Value; 58 | } 59 | 60 | private static string NormalizePath(string path) 61 | { 62 | return path == null ? null : path.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar); 63 | } 64 | 65 | public override bool Equals(string other) 66 | { 67 | return other != null && Value.Equals(other, StringComparison.OrdinalIgnoreCase); 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /src/MiscUtils/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("MiscUtils")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("MiscUtils")] 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("18bb8ed0-6334-4eb0-b796-c5c12dae80a8")] 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 | -------------------------------------------------------------------------------- /src/MiscUtils/StringEquivalent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Runtime.Serialization; 3 | using System.Xml; 4 | using System.Xml.Schema; 5 | using System.Xml.Serialization; 6 | 7 | namespace MiscUtils 8 | { 9 | [Serializable] 10 | public abstract class StringEquivalent : ISerializable, IXmlSerializable where T : StringEquivalent 11 | { 12 | protected string Value; 13 | 14 | protected StringEquivalent(string value) 15 | { 16 | Ensure.ArgumentNotNull(value, "value"); 17 | Value = value; 18 | } 19 | 20 | protected StringEquivalent() 21 | { 22 | } 23 | 24 | public abstract T Combine(string addition); 25 | 26 | public static T operator +(StringEquivalent a, string b) 27 | { 28 | return a.Combine(b); 29 | } 30 | 31 | public static bool operator ==(StringEquivalent a, StringEquivalent b) 32 | { 33 | // If both are null, or both are same instance, return true. 34 | if (ReferenceEquals(a, b)) 35 | { 36 | return true; 37 | } 38 | 39 | // If one is null, but not both, return false. 40 | if (((object)a == null) || ((object)b == null)) 41 | { 42 | return false; 43 | } 44 | 45 | // Return true if the fields match: 46 | return a.Value.Equals(b.Value, StringComparison.OrdinalIgnoreCase); 47 | } 48 | 49 | public static bool operator !=(StringEquivalent a, StringEquivalent b) 50 | { 51 | return !(a == b); 52 | } 53 | 54 | public override bool Equals(Object obj) 55 | { 56 | return obj != null && Equals(obj as T) || Equals(obj as string); 57 | } 58 | 59 | public bool Equals(T stringEquivalent) 60 | { 61 | return this == stringEquivalent; 62 | } 63 | 64 | public override int GetHashCode() 65 | { 66 | return (Value ?? "").GetHashCode(); 67 | } 68 | 69 | public virtual bool Equals(string other) 70 | { 71 | return other != null && Value == other; 72 | } 73 | 74 | public override string ToString() 75 | { 76 | return Value; 77 | } 78 | 79 | protected StringEquivalent(SerializationInfo info) : this(info.GetValue("Value", typeof (string)) as string) 80 | { 81 | } 82 | 83 | public virtual void GetObjectData(SerializationInfo info, StreamingContext context) 84 | { 85 | info.AddValue("Value", Value); 86 | } 87 | 88 | public XmlSchema GetSchema() 89 | { 90 | return null; 91 | } 92 | 93 | public void ReadXml(XmlReader reader) 94 | { 95 | Value = reader.ReadString(); 96 | } 97 | 98 | public void WriteXml(XmlWriter writer) 99 | { 100 | writer.WriteString(Value); 101 | } 102 | } 103 | } -------------------------------------------------------------------------------- /src/MiscUtilsTests/AttributeExtensionsTests.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using MiscUtils; 4 | using Xunit; 5 | 6 | namespace MiscUtilsTests 7 | { 8 | public class AttributeExtensionsTests 9 | { 10 | [Fact] 11 | public void CanCopyAttribute() 12 | { 13 | var attributes = typeof (Character).GetCustomAttributesCopy() 14 | .Cast() 15 | .OrderBy(x => x.NamedField) 16 | .ToArray(); 17 | 18 | Assert.Equal("ROVal1", attributes[0].ReadOnlyProperty); 19 | Assert.Equal("_x0", attributes[0].ReadOnlyArray[0]); 20 | Assert.Equal("_x1", attributes[0].ReadOnlyArray[1]); 21 | Assert.Equal("NVal1", attributes[0].NamedProperty); 22 | Assert.Equal("Val1", attributes[0].NamedField); 23 | Assert.Equal("x0", attributes[0].NamedArray[0]); 24 | Assert.Equal("x1", attributes[0].NamedArray[1]); 25 | Assert.Equal("ROVal2", attributes[1].ReadOnlyProperty); 26 | Assert.Equal("_y0", attributes[1].ReadOnlyArray[0]); 27 | Assert.Equal("_y1", attributes[1].ReadOnlyArray[1]); 28 | Assert.Equal("NVal2", attributes[1].NamedProperty); 29 | Assert.Equal("Val2", attributes[1].NamedField); 30 | Assert.Equal("y0", attributes[1].NamedArray[0]); 31 | Assert.Equal("y1", attributes[1].NamedArray[1]); 32 | } 33 | 34 | [Something("ROVal1", 35 | new[] {"_x0", "_x1"}, 36 | NamedProperty = "NVal1", 37 | NamedField = "Val1", 38 | NamedArray = new[] {"x0", "x1"})] 39 | [Something("ROVal2", 40 | new[] {"_y0", "_y1"}, 41 | NamedProperty = "NVal2", 42 | NamedField = "Val2", 43 | NamedArray = new[] {"y0", "y1"})] 44 | public class Character 45 | { 46 | } 47 | 48 | [AttributeUsage(AttributeTargets.All, AllowMultiple = true)] 49 | public class SomethingAttribute : Attribute 50 | { 51 | public string NamedField; 52 | 53 | public SomethingAttribute(string readOnlyProperty, string[] readOnlyArray) 54 | { 55 | ReadOnlyProperty = readOnlyProperty; 56 | ReadOnlyArray = readOnlyArray; 57 | } 58 | 59 | public string ReadOnlyProperty { get; private set; } 60 | public string NamedProperty { get; set; } 61 | public string[] NamedArray { get; set; } 62 | public string[] ReadOnlyArray { get; set; } 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /src/MiscUtilsTests/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("MiscUtilsTests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("MiscUtilsTests")] 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("786ddb12-dfd5-451f-a324-6c4ae91bee81")] 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 | -------------------------------------------------------------------------------- /src/MiscUtilsTests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/App_Start/AjaxDemoAppStart.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Entity; 2 | using MvcHaack.Ajax.Sample.Models; 3 | 4 | [assembly: WebActivator.PreApplicationStartMethod(typeof(MvcHaack.Ajax.Sample.App_Start.AjaxDemoAppStart), "Start")] 5 | 6 | namespace MvcHaack.Ajax.Sample.App_Start 7 | { 8 | public static class AjaxDemoAppStart 9 | { 10 | public static void Start() 11 | { 12 | Database.SetInitializer(new MyDropCreateDatabaseIfModelChanges()); 13 | } 14 | } 15 | 16 | public class MyDropCreateDatabaseIfModelChanges : DropCreateDatabaseIfModelChanges 17 | { 18 | protected override void Seed(ComicContext context) 19 | { 20 | var darkHorse = new Publisher { Name = "Dark Horse" }; 21 | context.Publishers.Add(darkHorse); 22 | var marvel = new Publisher { Name = "Marvel" }; 23 | context.Publishers.Add(marvel); 24 | var dc = new Publisher { Name = "DC" }; 25 | context.Publishers.Add(dc); 26 | 27 | context.ComicBooks.Add(new ComicBook { Title = "Groo", Publisher = darkHorse }); 28 | context.ComicBooks.Add(new ComicBook { Title = "Spiderman", Publisher = marvel }); 29 | context.ComicBooks.Add(new ComicBook { Title = "Superman", Publisher = dc }); 30 | context.ComicBooks.Add(new ComicBook { Title = "Batman", Publisher = dc }); 31 | 32 | context.SaveChanges(); 33 | } 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/App_Start/EntityFramework.SqlServerCompact.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Entity; 2 | using System.Data.Entity.Infrastructure; 3 | 4 | [assembly: WebActivator.PreApplicationStartMethod(typeof(MvcHaack.Ajax.Sample.App_Start.EntityFramework_SqlServerCompact), "Start")] 5 | 6 | namespace MvcHaack.Ajax.Sample.App_Start 7 | { 8 | public static class EntityFramework_SqlServerCompact 9 | { 10 | public static void Start() 11 | { 12 | Database.DefaultConnectionFactory = new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0"); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/Areas/MvcAjaxDemo/AjaxDemoAreaRegistration.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | 3 | namespace MvcHaack.Ajax.Sample.Areas.AjaxDemo 4 | { 5 | public class AjaxDemoAreaRegistration : AreaRegistration 6 | { 7 | public override string AreaName 8 | { 9 | get 10 | { 11 | return "MvcAjaxDemo"; 12 | } 13 | } 14 | 15 | public override void RegisterArea(AreaRegistrationContext context) 16 | { 17 | context.Routes.Add(new JsonRoute("json/{controller}")); 18 | 19 | context.MapRoute( 20 | "AjaxDemo_default", 21 | "AjaxDemo/{controller}/{action}/{id}", 22 | new { action = "Index", id = UrlParameter.Optional } 23 | ); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/Areas/MvcAjaxDemo/Content/Site.css: -------------------------------------------------------------------------------- 1 | body 2 | { 3 | font-size: .85em; 4 | font-family: "Trebuchet MS", Verdana, Helvetica, Sans-Serif; 5 | color: #232323; 6 | background-color: #fff; 7 | } 8 | 9 | header, 10 | footer, 11 | nav, 12 | section { 13 | display: block; 14 | } 15 | 16 | /* Styles for basic forms 17 | -----------------------------------------------------------*/ 18 | 19 | fieldset 20 | { 21 | border:1px solid #ddd; 22 | padding:0 1.4em 1.4em 1.4em; 23 | margin:0 0 1.5em 0; 24 | } 25 | 26 | legend 27 | { 28 | font-size:1.2em; 29 | font-weight: bold; 30 | } 31 | 32 | textarea 33 | { 34 | min-height: 75px; 35 | } 36 | 37 | .editor-label 38 | { 39 | margin: 1em 0 0 0; 40 | } 41 | 42 | .editor-field 43 | { 44 | margin:0.5em 0 0 0; 45 | } 46 | 47 | 48 | /* Styles for validation helpers 49 | -----------------------------------------------------------*/ 50 | .field-validation-error 51 | { 52 | color: #ff0000; 53 | } 54 | 55 | .field-validation-valid 56 | { 57 | display: none; 58 | } 59 | 60 | .input-validation-error 61 | { 62 | border: 1px solid #ff0000; 63 | background-color: #ffeeee; 64 | } 65 | 66 | .validation-summary-errors 67 | { 68 | font-weight: bold; 69 | color: #ff0000; 70 | } 71 | 72 | .validation-summary-valid 73 | { 74 | display: none; 75 | } 76 | 77 | 78 | div.comic 79 | { 80 | border: solid 1px; 81 | width: 200px; 82 | float: left; 83 | margin: 5px; 84 | padding: 10px; 85 | display: inline-block; 86 | } 87 | 88 | #comicForm 89 | { 90 | clear: left; 91 | } 92 | 93 | .csharpcode, .csharpcode pre 94 | { 95 | font-size: small; 96 | color: black; 97 | font-family: consolas, "Courier New", courier, monospace; 98 | background-color: #ffffff; 99 | /*white-space: pre;*/ 100 | } 101 | .csharpcode pre { margin: 0em; } 102 | .csharpcode .rem { color: #008000; } 103 | .csharpcode .kwrd { color: #0000ff; } 104 | .csharpcode .str { color: #006080; } 105 | .csharpcode .op { color: #0000c0; } 106 | .csharpcode .preproc { color: #cc6633; } 107 | .csharpcode .asp { background-color: #ffff00; } 108 | .csharpcode .html { color: #800000; } 109 | .csharpcode .attr { color: #ff0000; } 110 | .csharpcode .alt 111 | { 112 | background-color: #f4f4f4; 113 | width: 100%; 114 | margin: 0em; 115 | } 116 | .csharpcode .lnum { color: #606060; } 117 | 118 | fieldset.code 119 | { 120 | border: solid 2px; 121 | padding: 10px; 122 | margin: 8px; 123 | } 124 | 125 | p {width: 600px;} -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/Areas/MvcAjaxDemo/Controllers/ComicsController.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data; 3 | using System.Linq; 4 | using System.Web.Mvc; 5 | using MvcHaack.Ajax.Sample.Models; 6 | 7 | namespace MvcHaack.Ajax.Sample.Areas.AjaxDemo.Controllers 8 | { 9 | public class ComicsController : JsonController 10 | { 11 | private ComicContext db = new ComicContext(); 12 | 13 | public IEnumerable List() 14 | { 15 | return db.ComicBooks.ToList(); 16 | } 17 | 18 | [HttpPost] 19 | public ComicBook Create(ComicBook comicbook) 20 | { 21 | if (ModelState.IsValid) 22 | { 23 | db.ComicBooks.Add(comicbook); 24 | db.SaveChanges(); 25 | } 26 | return comicbook; 27 | } 28 | 29 | [HttpPost] 30 | public void Edit(ComicBook comicbook) 31 | { 32 | if (ModelState.IsValid) 33 | { 34 | db.Entry(comicbook).State = EntityState.Modified; 35 | db.SaveChanges(); 36 | } 37 | } 38 | 39 | [HttpPost] 40 | public void Delete(int id) 41 | { 42 | ComicBook comicbook = db.ComicBooks.Find(id); 43 | db.ComicBooks.Remove(comicbook); 44 | db.SaveChanges(); 45 | } 46 | 47 | protected override void Dispose(bool disposing) 48 | { 49 | db.Dispose(); 50 | base.Dispose(disposing); 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/Areas/MvcAjaxDemo/Controllers/ComicsDemoController.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using MvcHaack.Ajax.Sample.Models; 3 | 4 | namespace MvcHaack.Ajax.Sample.Areas.AjaxDemo.Controllers 5 | { 6 | public class ComicsDemoController : JsonController 7 | { 8 | public IEnumerable List() 9 | { 10 | return new[] { 11 | new {Id = 1, Title = "Groo"}, 12 | new {Id = 1, Title = "Batman"}, 13 | new {Id = 1, Title = "Spiderman"} 14 | }; 15 | } 16 | 17 | public object Save(ComicBook book) 18 | { 19 | return new { message = "Saved!", comic = book }; 20 | } 21 | 22 | [ValidateJsonAntiForgeryToken] 23 | public object SaveSecure(ComicBook book) 24 | { 25 | return new { message = "Saved!", comic = book }; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/Areas/MvcAjaxDemo/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | 3 | namespace MvcHaack.Ajax.Sample.Areas.AjaxDemo.Controllers 4 | { 5 | public class HomeController : Controller 6 | { 7 | public ActionResult Index() 8 | { 9 | return View(); 10 | } 11 | 12 | public ActionResult ComicsDemo() 13 | { 14 | return View(); 15 | } 16 | 17 | public ActionResult ComicsPostDemo() 18 | { 19 | return View(); 20 | } 21 | 22 | public ActionResult SecureComicsPostDemo() 23 | { 24 | return View(); 25 | } 26 | 27 | public ActionResult KnockoutDemo() 28 | { 29 | return View(); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/Areas/MvcAjaxDemo/Controllers/PublishersController.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Data; 3 | using System.Linq; 4 | using System.Web.Mvc; 5 | using MvcHaack.Ajax.Sample.Models; 6 | 7 | namespace MvcHaack.Ajax.Sample.Areas.AjaxDemo.Controllers 8 | { 9 | public class PublishersController : JsonController 10 | { 11 | private readonly ComicContext db = new ComicContext(); 12 | 13 | public IEnumerable List() 14 | { 15 | return from p in db.Publishers.ToList() 16 | select new Publisher { Id = p.Id, Name = p.Name }; 17 | } 18 | 19 | 20 | public ViewResult Details(int id) 21 | { 22 | Publisher publisher = db.Publishers.Find(id); 23 | return View(publisher); 24 | } 25 | 26 | [HttpPost] 27 | public bool Create(Publisher publisher) 28 | { 29 | if (ModelState.IsValid) 30 | { 31 | db.Publishers.Add(publisher); 32 | db.SaveChanges(); 33 | } 34 | 35 | return true; 36 | } 37 | 38 | // 39 | // GET: /Publishers/Edit/5 40 | 41 | public ActionResult Edit(int id) 42 | { 43 | Publisher publisher = db.Publishers.Find(id); 44 | return View(publisher); 45 | } 46 | 47 | // 48 | // POST: /Publishers/Edit/5 49 | 50 | [HttpPost] 51 | public ActionResult Edit(Publisher publisher) 52 | { 53 | if (ModelState.IsValid) 54 | { 55 | db.Entry(publisher).State = EntityState.Modified; 56 | db.SaveChanges(); 57 | return RedirectToAction("Index"); 58 | } 59 | return View(publisher); 60 | } 61 | 62 | // 63 | // GET: /Publishers/Delete/5 64 | 65 | public ActionResult Delete(int id) 66 | { 67 | Publisher publisher = db.Publishers.Find(id); 68 | return View(publisher); 69 | } 70 | 71 | // 72 | // POST: /Publishers/Delete/5 73 | 74 | [HttpPost, ActionName("Delete")] 75 | public ActionResult DeleteConfirmed(int id) 76 | { 77 | Publisher publisher = db.Publishers.Find(id); 78 | db.Publishers.Remove(publisher); 79 | db.SaveChanges(); 80 | return RedirectToAction("Index"); 81 | } 82 | 83 | protected override void Dispose(bool disposing) 84 | { 85 | db.Dispose(); 86 | base.Dispose(disposing); 87 | } 88 | } 89 | } -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/Areas/MvcAjaxDemo/Models/ComicBook.cs: -------------------------------------------------------------------------------- 1 | namespace MvcHaack.Ajax.Sample.Models 2 | { 3 | public class ComicBook 4 | { 5 | public int Id { get; set; } 6 | public string Title { get; set; } 7 | public string Author { get; set; } 8 | public Publisher Publisher { get; set; } 9 | public int PublisherId { get; set; } 10 | public int IssueNumber { get; set; } 11 | } 12 | } -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/Areas/MvcAjaxDemo/Models/ComicContext.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Entity; 2 | 3 | namespace MvcHaack.Ajax.Sample.Models 4 | { 5 | public class ComicContext : DbContext 6 | { 7 | // You can add custom code to this file. Changes will not be overwritten. 8 | // 9 | // If you want Entity Framework to drop and regenerate your database 10 | // automatically whenever you change your model schema, add the following 11 | // code to the Application_Start method in your Global.asax file. 12 | // Note: this will destroy and re-create your database with every model change. 13 | // 14 | // System.Data.Entity.Database.SetInitializer(new System.Data.Entity.DropCreateDatabaseIfModelChanges()); 15 | 16 | public DbSet ComicBooks { get; set; } 17 | 18 | public DbSet Publishers { get; set; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/Areas/MvcAjaxDemo/Models/Publisher.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace MvcHaack.Ajax.Sample.Models 4 | { 5 | public class Publisher 6 | { 7 | public int Id { get; set; } 8 | public string Name { get; set; } 9 | public virtual ICollection ComicBooks { get; set; } 10 | } 11 | } -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/Areas/MvcAjaxDemo/Views/Home/ComicsDemo.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Simple Comics Demo"; 3 | } 4 | 5 | @section Scripts { 6 | 7 | 8 | 9 | } 10 |

11 | Click on the button to make a call to ComicsDemoController's 12 | List method and populate an unordered list with the comics returned by that method. 13 |

14 | 15 |
    16 | 17 | 18 | 19 |
    20 |
    21 | comicsdemo.html 22 |
    <script src="../../Scripts/jquery-1.6.2.js" type="text/javascript"></script>
    23 | <script src="/json/comicsdemo?json"></script>
    24 | <script src="/Scripts/comicsdemo.js"></script>
    25 | 
    26 | <ul id="comics"></ul>
    27 | 
    28 | <button id="loadButton">Load Comics</button>
    29 |
    30 | 31 |
    32 | comicsdemo.js 33 | 34 |
    35 | $(function() {
    36 |     $('#loadButton').click(
    37 |         function() {
    38 |             $mvc.ComicsDemo.List().done(function(data) {
    39 |                 $.each(data, function() {
    40 |                     $('#comics').append('<li>' + this.Title + '</li>');
    41 |                 });
    42 |             });    
    43 |         }
    44 |     );
    45 | });
    46 |
    -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/Areas/MvcAjaxDemo/Views/Home/ComicsPostDemo.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "ComicsDemoPostback"; 3 | } 4 | 5 | @section Scripts { 6 | 7 | 8 | 9 | } 10 | 11 |

    Simple Comics Post Demo

    12 | 13 | 14 | 15 | 24 | 25 |
    26 | 27 |
    28 | comicspostdemo.html 29 | 30 |
    31 | <script src="../../Scripts/jquery-1.6.2.js" type="text/javascript"></script>
    32 | <script src="/json/comicsdemo?json"></script>
    33 | <script src="/Scripts/comicsdemo.js"></script>
    34 | 
    35 | <h2>Simple Comics Post Demo</h2>
    36 | 
    37 | <button id="post">Click to post a comic to the server</button>
    38 | 
    39 | <script>
    40 |     $(function() {
    41 |         $('#post').click(function() {
    42 |             $mvc.ComicsDemo.Save({ Title: 'Adventurers', Issue: 123 }).done(function(data) {
    43 |                 alert(data.message + ' Comic: ' + data.comic.Title);
    44 |             });
    45 |         });
    46 |     });
    47 | </script>
    48 | 49 |
    -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/Areas/MvcAjaxDemo/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Index"; 3 | } 4 | 5 |

    Demos

    6 | 7 | -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/Areas/MvcAjaxDemo/Views/Home/SecureComicsPostDemo.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "ComicsDemoPostback"; 3 | } 4 | 5 | @section Scripts { 6 | 7 | 8 | 9 | } 10 | 11 |

    Simple Comics Post Demo With AntiForgery Protection

    12 | 13 | 14 | 15 | 24 | 25 |
    26 | 27 | @Html.AntiForgeryToken() 28 | 29 |
    30 | comicspostdemo.html 31 | 32 |
    33 | <script src="../../Scripts/jquery-1.6.2.js" type="text/javascript"></script>
    34 | <script src="/json/comicsdemo?json"></script>
    35 | <script src="/Scripts/comicsdemo.js"></script>
    36 | 
    37 | <h2>Simple Comics Post Demo</h2>
    38 | 
    39 | <button id="post">Click to post a comic to the server</button>
    40 | 
    41 | @@Html.AntiForgeryToken()
    42 | 
    43 | <script>
    44 |     $(function() {
    45 |         $('#post').click(function() {
    46 |             $mvc.ComicsDemo.SaveSecure({ Title: 'Adventurers', Issue: 123 }).done(function(data) {
    47 |                 alert(data.message + ' Comic: ' + data.comic.Title);
    48 |             });
    49 |         });
    50 |     });
    51 | </script>
    52 | 53 |
    -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/Areas/MvcAjaxDemo/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | @ViewBag.Title 5 | 6 | @RenderSection("Scripts", required: false) 7 | 8 | 9 | 10 |

    MVCHaack Ajax Demo

    11 | 12 | @RenderBody() 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/Areas/MvcAjaxDemo/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 | 39 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/Areas/MvcAjaxDemo/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{Layout = "~/Areas/MvcAjaxDemo/Views/Shared/_Layout.cshtml";} -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="MvcHaack.Ajax.Sample.MvcApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/Global.asax.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | using System.Web.Routing; 3 | 4 | namespace MvcHaack.Ajax.Sample 5 | { 6 | // Note: For instructions on enabling IIS6 or IIS7 classic mode, 7 | // visit http://go.microsoft.com/?LinkId=9394801 8 | 9 | public class MvcApplication : System.Web.HttpApplication 10 | { 11 | public static void RegisterGlobalFilters(GlobalFilterCollection filters) 12 | { 13 | } 14 | 15 | public static void RegisterRoutes(RouteCollection routes) 16 | { 17 | routes.IgnoreRoute(""); 18 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 19 | 20 | routes.MapRoute( 21 | "Default", // Route name 22 | "{controller}/{action}/{id}", // URL with parameters 23 | new { action = "Index", id = UrlParameter.Optional } // Parameter defaults 24 | ); 25 | 26 | } 27 | 28 | protected void Application_Start() 29 | { 30 | AreaRegistration.RegisterAllAreas(); 31 | 32 | RegisterGlobalFilters(GlobalFilters.Filters); 33 | RegisterRoutes(RouteTable.Routes); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("MvcHaack.Ajax.Sample")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("Microsoft")] 11 | [assembly: AssemblyProduct("MvcHaack.Ajax.Sample")] 12 | [assembly: AssemblyCopyright("Copyright © Microsoft 2011")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("7cec7921-5e88-4bce-9619-b4f31141798d")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Revision and Build Numbers 32 | // by using the '*' as shown below: 33 | [assembly: AssemblyVersion("1.0.0.0")] 34 | [assembly: AssemblyFileVersion("1.0.0.0")] 35 | -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/Scripts/comicsdemo.js: -------------------------------------------------------------------------------- 1 | $(function() { 2 | $('#loadButton').click( 3 | function() { 4 | $mvc.ComicsDemo.List().done(function(data) { 5 | $.each(data, function() { 6 | $('#comics').append('
  • ' + this.Title + '
  • '); 7 | }); 8 | }); 9 | } 10 | ); 11 | }); -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/Web.Debug.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/Web.Release.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/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 | -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/_bin_deployableAssemblies/Microsoft.Web.Infrastructure.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haacked/CodeHaacks/9d6dd8b6c9498d5cfca38580667c05ca2321b8de/src/MvcHaack.Ajax.DemoWeb/_bin_deployableAssemblies/Microsoft.Web.Infrastructure.dll -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/_bin_deployableAssemblies/System.Web.Helpers.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haacked/CodeHaacks/9d6dd8b6c9498d5cfca38580667c05ca2321b8de/src/MvcHaack.Ajax.DemoWeb/_bin_deployableAssemblies/System.Web.Helpers.dll -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/_bin_deployableAssemblies/System.Web.Mvc.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haacked/CodeHaacks/9d6dd8b6c9498d5cfca38580667c05ca2321b8de/src/MvcHaack.Ajax.DemoWeb/_bin_deployableAssemblies/System.Web.Mvc.dll -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/_bin_deployableAssemblies/System.Web.Razor.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haacked/CodeHaacks/9d6dd8b6c9498d5cfca38580667c05ca2321b8de/src/MvcHaack.Ajax.DemoWeb/_bin_deployableAssemblies/System.Web.Razor.dll -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/_bin_deployableAssemblies/System.Web.WebPages.Deployment.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haacked/CodeHaacks/9d6dd8b6c9498d5cfca38580667c05ca2321b8de/src/MvcHaack.Ajax.DemoWeb/_bin_deployableAssemblies/System.Web.WebPages.Deployment.dll -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/_bin_deployableAssemblies/System.Web.WebPages.Razor.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haacked/CodeHaacks/9d6dd8b6c9498d5cfca38580667c05ca2321b8de/src/MvcHaack.Ajax.DemoWeb/_bin_deployableAssemblies/System.Web.WebPages.Razor.dll -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/_bin_deployableAssemblies/System.Web.WebPages.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haacked/CodeHaacks/9d6dd8b6c9498d5cfca38580667c05ca2321b8de/src/MvcHaack.Ajax.DemoWeb/_bin_deployableAssemblies/System.Web.WebPages.dll -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/default.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | MVCHaack Ajax Sample 5 | 6 | 7 |

    MVCHaack Ajax Demos

    8 | 9 | 12 | Ajax Demos 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.DemoWeb/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.V2/JsonController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Threading; 4 | using System.Threading.Tasks; 5 | using System.Web.Mvc; 6 | using System.Web.Mvc.Async; 7 | 8 | namespace MvcHaack.Ajax 9 | { 10 | /// 11 | /// Note: this version of the code only compiles against MVC4 where Controller implements IAsyncController. 12 | /// 13 | public class JsonController : Controller 14 | { 15 | protected override IActionInvoker CreateActionInvoker() 16 | { 17 | return new JsonActionInvoker(); 18 | } 19 | 20 | protected override IAsyncResult BeginExecuteCore(AsyncCallback callback, object state) 21 | { 22 | 23 | var queryString = HttpContext.Request.QueryString; 24 | if (queryString.Keys.Count > 0 && String.Equals(queryString.GetValues(0).First(), "json", StringComparison.OrdinalIgnoreCase)) 25 | { 26 | ActionInvoker.InvokeAction(ControllerContext, "Internal::Proxy"); 27 | return new CompletedAsyncResult() { AsyncState = state }; 28 | } 29 | 30 | // This is where the proxy places the action. 31 | string action = HttpContext.Request.Headers["x-mvc-action"] ?? HttpContext.Request.QueryString["action"]; 32 | 33 | if (!RouteData.Values.ContainsKey("action") && !String.IsNullOrEmpty(action)) 34 | { 35 | RouteData.Values.Add("action", action); 36 | } 37 | 38 | if (RouteData.Values.ContainsKey("action")) 39 | { 40 | return base.BeginExecuteCore(callback, state); 41 | } 42 | else 43 | { 44 | ActionInvoker.InvokeAction(ControllerContext, "Internal::ProxyDefinition"); 45 | return new CompletedAsyncResult() { AsyncState = state }; 46 | } 47 | } 48 | 49 | protected override void EndExecuteCore(IAsyncResult asyncResult) 50 | { 51 | if (asyncResult is CompletedAsyncResult) 52 | { 53 | return; 54 | } 55 | else 56 | { 57 | base.EndExecuteCore(asyncResult); 58 | } 59 | } 60 | 61 | protected override void ExecuteCore() 62 | { 63 | EndExecuteCore(BeginExecuteCore(new AsyncCallback((IAsyncResult x) => {}), null)); 64 | } 65 | 66 | class CompletedAsyncResult : IAsyncResult 67 | { 68 | public object AsyncState 69 | { 70 | get; 71 | set; 72 | } 73 | 74 | public WaitHandle AsyncWaitHandle 75 | { 76 | get { throw new NotSupportedException("CompletedAsyncResult.AsyncWaitHandle"); } 77 | } 78 | 79 | public bool CompletedSynchronously 80 | { 81 | get { return true; } 82 | } 83 | 84 | public bool IsCompleted 85 | { 86 | get { return true; } 87 | } 88 | } 89 | } 90 | } -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.V2/JsonRoute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Web.Mvc; 3 | using System.Web.Routing; 4 | 5 | namespace MvcHaack.Ajax 6 | { 7 | public class JsonRoute : Route 8 | { 9 | public JsonRoute(string url) 10 | : base(url, new MvcRouteHandler()) 11 | { 12 | if (url.IndexOf("{action}", StringComparison.OrdinalIgnoreCase) > -1) 13 | { 14 | throw new ArgumentException("url may not contain the {action} parameter", "url"); 15 | } 16 | } 17 | 18 | public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) 19 | { 20 | return null; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.V2/MvcHaack.Ajax.V2.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | MvcHaack.Ajax.MVC4 5 | 2.0.0.0 6 | Phil Haack 7 | Phil Haack 8 | http://www.opensource.org/licenses/mit-license.php 9 | https://github.com/Haacked/CodeHaacks 10 | http://haacked.com/images/Inspector-120x120.png 11 | false 12 | See MvcHaack.Ajax package description 13 | 14 | 15 | 16 | 17 | MVCHaack.Ajax 2.0.0 Version of MVCHaack.Ajax which is compatible with MVC4 (and maybe not with MVC3). 18 | MVCHaack.Ajax 1.0.1 alerts users when using in IE 8 or less without the json2 library referenced. 19 | 20 | aspnetmvc asp.net aspnet asp.net-mvc controllerdescriptor controller 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.V2/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("MvcHaack.Ajax")] 8 | [assembly: AssemblyDescription("A libary for easily calling ASP.NET MVC Action methods from JavaScript")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("Phil Haack")] 11 | [assembly: AssemblyProduct("MvcHaack.Ajax")] 12 | [assembly: AssemblyCopyright("Copyright © Phil Haack 2011")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("b0dce40d-b27d-487e-8073-34ae7bc40262")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("2.0.0.0")] 35 | [assembly: AssemblyFileVersion("2.0.0.0")] 36 | -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.V2/ValidateJsonAntiForgeryTokenAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Specialized; 3 | using System.Web; 4 | using System.Web.Helpers; 5 | using System.Web.Mvc; 6 | 7 | namespace MvcHaack.Ajax 8 | { 9 | [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true)] 10 | public class ValidateJsonAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter 11 | { 12 | public void OnAuthorization(AuthorizationContext filterContext) 13 | { 14 | if (filterContext == null) 15 | { 16 | throw new ArgumentNullException("filterContext"); 17 | } 18 | 19 | string serializedCookieToken = null; 20 | HttpCookie cookie = HttpContext.Current.Request.Cookies[AntiForgeryConfig.CookieName]; 21 | if (cookie != null) 22 | { 23 | serializedCookieToken = cookie.Value; 24 | } 25 | 26 | string serializedHeaderToken = HttpContext.Current.Request.Headers["__RequestVerificationToken"]; 27 | AntiForgery.Validate(serializedCookieToken, serializedHeaderToken); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/MvcHaack.Ajax.V2/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/MvcHaack.Ajax/JsonController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Web.Mvc; 4 | 5 | namespace MvcHaack.Ajax 6 | { 7 | public class JsonController : Controller 8 | { 9 | protected override IActionInvoker CreateActionInvoker() 10 | { 11 | return new JsonActionInvoker(); 12 | } 13 | 14 | protected override void ExecuteCore() 15 | { 16 | var queryString = HttpContext.Request.QueryString; 17 | if (queryString.Keys.Count > 0 && String.Equals(queryString.GetValues(0).First(), "json", StringComparison.OrdinalIgnoreCase)) 18 | { 19 | ActionInvoker.InvokeAction(ControllerContext, "Internal::Proxy"); 20 | return; 21 | } 22 | 23 | // This is where the proxy places the action. 24 | string action = HttpContext.Request.Headers["x-mvc-action"] ?? HttpContext.Request.QueryString["action"]; 25 | 26 | if (!RouteData.Values.ContainsKey("action") && !String.IsNullOrEmpty(action)) 27 | { 28 | RouteData.Values.Add("action", action); 29 | } 30 | 31 | if (RouteData.Values.ContainsKey("action")) 32 | { 33 | base.ExecuteCore(); 34 | return; 35 | } 36 | 37 | ActionInvoker.InvokeAction(ControllerContext, "Internal::ProxyDefinition"); 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /src/MvcHaack.Ajax/JsonRoute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Web.Mvc; 3 | using System.Web.Routing; 4 | 5 | namespace MvcHaack.Ajax 6 | { 7 | public class JsonRoute : Route 8 | { 9 | public JsonRoute(string url) 10 | : base(url, new MvcRouteHandler()) 11 | { 12 | if (url.IndexOf("{action}", StringComparison.OrdinalIgnoreCase) > -1) 13 | { 14 | throw new ArgumentException("url may not contain the {action} parameter", "url"); 15 | } 16 | } 17 | 18 | public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) 19 | { 20 | return null; 21 | } 22 | } 23 | } -------------------------------------------------------------------------------- /src/MvcHaack.Ajax/MvcHaack.Ajax.csproj.orig: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {C90F24D5-1CE7-4F5D-A2AD-8F1892D2057F} 9 | Library 10 | Properties 11 | MvcHaack.Ajax 12 | MvcHaack.Ajax 13 | v4.0 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | Designer 54 | 55 | 56 | 57 | 64 | -------------------------------------------------------------------------------- /src/MvcHaack.Ajax/MvcHaack.Ajax.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $id$ 5 | $version$ 6 | $author$ 7 | $author$ 8 | http://www.opensource.org/licenses/mit-license.php 9 | https://github.com/Haacked/CodeHaacks 10 | http://haacked.com/images/Inspector-120x120.png 11 | false 12 | $description$ 13 | 14 | 1.0.1 alerts users when using in IE 8 or less without the json2 library referenced. 15 | 16 | aspnetmvc asp.net aspnet asp.net-mvc controllerdescriptor controller 17 | 18 | -------------------------------------------------------------------------------- /src/MvcHaack.Ajax/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("MvcHaack.Ajax")] 8 | [assembly: AssemblyDescription("A libary for easily calling ASP.NET MVC Action methods from JavaScript")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("Phil Haack")] 11 | [assembly: AssemblyProduct("MvcHaack.Ajax")] 12 | [assembly: AssemblyCopyright("Copyright © Phil Haack 2011")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("b0dce40d-b27d-487e-8073-34ae7bc40262")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.1.0.0")] 35 | [assembly: AssemblyFileVersion("1.1.0.0")] 36 | -------------------------------------------------------------------------------- /src/MvcHaack.Ajax/ValidateJsonAntiForgeryTokenAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Specialized; 3 | using System.Web; 4 | using System.Web.Helpers; 5 | using System.Web.Mvc; 6 | 7 | namespace MvcHaack.Ajax 8 | { 9 | [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true)] 10 | public class ValidateJsonAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter 11 | { 12 | 13 | public void OnAuthorization(AuthorizationContext filterContext) 14 | { 15 | if (filterContext == null) 16 | { 17 | throw new ArgumentNullException("filterContext"); 18 | } 19 | 20 | var httpContext = new JsonAntiForgeryHttpContextWrapper(HttpContext.Current); 21 | AntiForgery.Validate(httpContext, Salt ?? string.Empty); 22 | } 23 | 24 | public string Salt 25 | { 26 | get; 27 | set; 28 | } 29 | 30 | private class JsonAntiForgeryHttpContextWrapper : HttpContextWrapper 31 | { 32 | readonly HttpRequestBase _request; 33 | public JsonAntiForgeryHttpContextWrapper(HttpContext httpContext) 34 | : base(httpContext) 35 | { 36 | _request = new JsonAntiForgeryHttpRequestWrapper(httpContext.Request); 37 | } 38 | 39 | public override HttpRequestBase Request 40 | { 41 | get 42 | { 43 | return _request; 44 | } 45 | } 46 | } 47 | 48 | private class JsonAntiForgeryHttpRequestWrapper : HttpRequestWrapper 49 | { 50 | readonly NameValueCollection _form; 51 | 52 | public JsonAntiForgeryHttpRequestWrapper(HttpRequest request) 53 | : base(request) 54 | { 55 | _form = new NameValueCollection(request.Form); 56 | if (request.Headers["__RequestVerificationToken"] != null) 57 | { 58 | _form["__RequestVerificationToken"] = request.Headers["__RequestVerificationToken"]; 59 | } 60 | } 61 | 62 | public override NameValueCollection Form 63 | { 64 | get 65 | { 66 | return _form; 67 | } 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/MvcHaack.ControllerInspector.DemoWeb/Content/Site.css: -------------------------------------------------------------------------------- 1 | body 2 | { 3 | font-size: .85em; 4 | font-family: "Trebuchet MS", Verdana, Helvetica, Sans-Serif; 5 | color: #232323; 6 | background-color: #fff; 7 | } 8 | 9 | header, 10 | footer, 11 | nav, 12 | section { 13 | display: block; 14 | } 15 | 16 | /* Styles for basic forms 17 | -----------------------------------------------------------*/ 18 | 19 | fieldset 20 | { 21 | border:1px solid #ddd; 22 | padding:0 1.4em 1.4em 1.4em; 23 | margin:0 0 1.5em 0; 24 | } 25 | 26 | legend 27 | { 28 | font-size:1.2em; 29 | font-weight: bold; 30 | } 31 | 32 | textarea 33 | { 34 | min-height: 75px; 35 | } 36 | 37 | .editor-label 38 | { 39 | margin: 1em 0 0 0; 40 | } 41 | 42 | .editor-field 43 | { 44 | margin:0.5em 0 0 0; 45 | } 46 | 47 | 48 | /* Styles for validation helpers 49 | -----------------------------------------------------------*/ 50 | .field-validation-error 51 | { 52 | color: #ff0000; 53 | } 54 | 55 | .field-validation-valid 56 | { 57 | display: none; 58 | } 59 | 60 | .input-validation-error 61 | { 62 | border: 1px solid #ff0000; 63 | background-color: #ffeeee; 64 | } 65 | 66 | .validation-summary-errors 67 | { 68 | font-weight: bold; 69 | color: #ff0000; 70 | } 71 | 72 | .validation-summary-valid 73 | { 74 | display: none; 75 | } 76 | -------------------------------------------------------------------------------- /src/MvcHaack.ControllerInspector.DemoWeb/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Dynamic; 3 | using System.Linq; 4 | using System.Web.Mvc; 5 | 6 | namespace MvcHaack.ControllerInspector.DemoWeb.Controllers 7 | { 8 | [SomeFake] 9 | public class HomeController : Controller 10 | { 11 | public ActionResult Index(string id) 12 | { 13 | dynamic model = new ExpandoObject(); 14 | model.NonConventionalControllers = typeof (HomeController).GetUnconventionalControllers().ToList(); 15 | model.NonPublicControllers = typeof (HomeController).GetNonPublicControllers().ToList(); 16 | model.NonControllers = typeof (HomeController).GetNonControllersNamedWithControllerSuffix().ToList(); 17 | return View(model); 18 | } 19 | 20 | [HttpPost] 21 | [HttpPut] 22 | public ActionResult Index(string id, object something) 23 | { 24 | return View(); 25 | } 26 | 27 | [Authorize] 28 | [ActionName("GetAll")] 29 | public ActionResult List(string id = "Some default value") 30 | { 31 | return View(); 32 | } 33 | 34 | public string List(SomeModel model) 35 | { 36 | return "Test"; 37 | } 38 | 39 | [ActionName("Bar")] 40 | public ActionResult MethodWithNumericParam(short id) 41 | { 42 | return View(); 43 | } 44 | 45 | [HttpPost] 46 | public ActionResult MethodWithNonRouteParam(string hello) 47 | { 48 | return View(); 49 | } 50 | } 51 | 52 | public class SomeModel 53 | { 54 | public int Id { get; set; } 55 | public string Name { get; set; } 56 | public decimal Cost { get; set; } 57 | } 58 | 59 | [AttributeUsage(AttributeTargets.All)] 60 | public class SomeFakeAttribute : Attribute 61 | { 62 | } 63 | } -------------------------------------------------------------------------------- /src/MvcHaack.ControllerInspector.DemoWeb/Controllers/MistakeController.cs: -------------------------------------------------------------------------------- 1 | namespace MvcHaack.ControllerInspector.DemoWeb.Controllers 2 | { 3 | public class MistakeController 4 | { 5 | } 6 | } -------------------------------------------------------------------------------- /src/MvcHaack.ControllerInspector.DemoWeb/Controllers/TypoControler.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | 3 | namespace MvcHaack.ControllerInspector.DemoWeb.Controllers 4 | { 5 | public class TypoControler : Controller 6 | { 7 | // 8 | // GET: /TypoControler/ 9 | 10 | public string Index() 11 | { 12 | return "Test"; 13 | } 14 | 15 | public class BadNestedController : Controller 16 | { 17 | } 18 | } 19 | 20 | internal class InternalController : Controller 21 | { 22 | } 23 | } -------------------------------------------------------------------------------- /src/MvcHaack.ControllerInspector.DemoWeb/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="MvcHaack.ControllerInspector.DemoWeb.MvcApplication" Language="C#" %> 2 | -------------------------------------------------------------------------------- /src/MvcHaack.ControllerInspector.DemoWeb/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 MvcHaack.ControllerInspector.DemoWeb { 9 | // Note: For instructions on enabling IIS6 or IIS7 classic mode, 10 | // visit http://go.microsoft.com/?LinkId=9394801 11 | 12 | public class MvcApplication : System.Web.HttpApplication { 13 | public static void RegisterGlobalFilters(GlobalFilterCollection filters) { 14 | filters.Add(new HandleErrorAttribute()); 15 | } 16 | 17 | public static void RegisterRoutes(RouteCollection routes) { 18 | routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); 19 | 20 | routes.MapRoute( 21 | "Default", // Route name 22 | "{controller}/{action}/{id}", // URL with parameters 23 | new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults 24 | ); 25 | 26 | } 27 | 28 | protected void Application_Start() { 29 | AreaRegistration.RegisterAllAreas(); 30 | 31 | RegisterGlobalFilters(GlobalFilters.Filters); 32 | RegisterRoutes(RouteTable.Routes); 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/MvcHaack.ControllerInspector.DemoWeb/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("MvcHaack.ControllerInspector.DemoWeb")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("MvcHaack.ControllerInspector.DemoWeb")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2011")] 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("720a4a16-811d-4fed-b521-10caa627a932")] 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 | -------------------------------------------------------------------------------- /src/MvcHaack.ControllerInspector.DemoWeb/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewBag.Title = "Index"; 3 | } 4 | 5 |

    Index

    6 | 7 |

    This is standard view.

    8 | 9 |

    Append ?inspect to the query string to see the magic.

    10 |

    For more details, check out this blog post.

    11 | 12 |

    Controllers that violate conventions

    13 |
      14 | @foreach (Type type in Model.NonConventionalControllers) 15 | { 16 |
    • @type.Name
    • 17 | } 18 |
    19 | 20 |

    Controllers that cannot be instantiated

    21 |
      22 | @foreach (Type type in Model.NonPublicControllers) 23 | { 24 |
    • @type.Name
    • 25 | } 26 |
    27 | 28 |

    Controllers that do not derive from controller

    29 |
      30 | @foreach (Type type in Model.NonControllers) 31 | { 32 |
    • @type.Name
    • 33 | } 34 |
    -------------------------------------------------------------------------------- /src/MvcHaack.ControllerInspector.DemoWeb/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = null; 3 | } 4 | 5 | 6 | 7 | 8 | Error 9 | 10 | 11 |

    12 | Sorry, an error occurred while processing your request. 13 |

    14 | 15 | -------------------------------------------------------------------------------- /src/MvcHaack.ControllerInspector.DemoWeb/Views/Shared/_Layout.cshtml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | @ViewBag.Title 6 | 7 | 8 | 9 | 10 | @RenderBody() 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/MvcHaack.ControllerInspector.DemoWeb/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 | 39 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /src/MvcHaack.ControllerInspector.DemoWeb/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "~/Views/Shared/_Layout.cshtml"; 3 | } -------------------------------------------------------------------------------- /src/MvcHaack.ControllerInspector.DemoWeb/Web.Debug.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /src/MvcHaack.ControllerInspector.DemoWeb/Web.Release.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | -------------------------------------------------------------------------------- /src/MvcHaack.ControllerInspector.DemoWeb/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 | -------------------------------------------------------------------------------- /src/MvcHaack.ControllerInspector/AppStart.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | using MvcHaack.ControllerInspector; 3 | using WebActivator; 4 | 5 | [assembly: PostApplicationStartMethod(typeof(AppStart), "Start")] 6 | namespace MvcHaack.ControllerInspector { 7 | 8 | public static class AppStart { 9 | public static void Start() { 10 | var factory = ControllerBuilder.Current.GetControllerFactory(); 11 | ControllerBuilder.Current.SetControllerFactory(new InspectorControllerFactory(factory)); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/MvcHaack.ControllerInspector/ControllerValidator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Web.Mvc; 6 | 7 | namespace MvcHaack.ControllerInspector 8 | { 9 | public static class ControllerValidator 10 | { 11 | public static bool AllControllersMeetConvention(this Assembly assembly) 12 | { 13 | return assembly.GetUnconventionalControllers().Any(); 14 | } 15 | 16 | public static IEnumerable GetUnconventionalControllers(this Type typeInAssembly) 17 | { 18 | return typeInAssembly.Assembly.GetUnconventionalControllers(); 19 | } 20 | 21 | public static IEnumerable GetUnconventionalControllers(this Assembly assembly) 22 | { 23 | return from t in assembly.GetLoadableTypes() 24 | where t.IsPublicClass() && t.IsControllerType() && !t.MeetsConvention() 25 | select t; 26 | } 27 | 28 | public static IEnumerable GetNonPublicControllers(this Type typeInAssembly) 29 | { 30 | return typeInAssembly.Assembly.GetNonPublicControllers(); 31 | } 32 | 33 | public static IEnumerable GetNonPublicControllers(this Assembly assembly) 34 | { 35 | return from t in assembly.GetLoadableTypes() 36 | where !t.IsPublicClass() && t.IsControllerType() && t.MeetsConvention() 37 | select t; 38 | } 39 | 40 | public static IEnumerable GetNonControllersNamedWithControllerSuffix(this Type typeInAssembly) 41 | { 42 | return typeInAssembly.Assembly.GetNonControllersNamedWithControllerSuffix(); 43 | } 44 | 45 | public static IEnumerable GetNonControllersNamedWithControllerSuffix(this Assembly assembly) 46 | { 47 | return from t in assembly.GetLoadableTypes() 48 | where t.IsPublicClass() && !t.IsControllerType() && t.MeetsConvention() 49 | select t; 50 | } 51 | 52 | static bool IsPublicClass(this Type type) 53 | { 54 | return (type != null && type.IsPublic && type.IsClass && !type.IsAbstract); 55 | } 56 | 57 | static bool IsControllerType(this Type t) 58 | { 59 | return typeof (IController).IsAssignableFrom(t); 60 | } 61 | 62 | static bool MeetsConvention(this Type t) 63 | { 64 | return t.Name.EndsWith("Controller", StringComparison.OrdinalIgnoreCase); 65 | } 66 | 67 | public static IEnumerable GetLoadableTypes(this Assembly assembly) 68 | { 69 | if (assembly == null) throw new ArgumentNullException("assembly"); 70 | try 71 | { 72 | return assembly.GetTypes(); 73 | } 74 | catch (ReflectionTypeLoadException e) 75 | { 76 | return e.Types.Where(t => t != null); 77 | } 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /src/MvcHaack.ControllerInspector/InspectorActionInvoker.cs: -------------------------------------------------------------------------------- 1 | using System.Web.Mvc; 2 | 3 | namespace MvcHaack.ControllerInspector 4 | { 5 | public class InspectorActionInvoker : ControllerActionInvoker 6 | { 7 | readonly IActionInvoker _invoker; 8 | 9 | public InspectorActionInvoker(IActionInvoker invoker) 10 | { 11 | _invoker = invoker; 12 | } 13 | 14 | public override bool InvokeAction(ControllerContext controllerContext, string actionName) 15 | { 16 | var httpContext = controllerContext.HttpContext; 17 | var controllerActionInvoker = _invoker as ControllerActionInvoker; 18 | if (controllerActionInvoker != null) 19 | { 20 | var detailer = new ControllerDetailer(); 21 | httpContext.Response.Write(detailer.GetControllerDetails(GetControllerDescriptor(controllerContext), controllerContext.RequestContext)); 22 | return true; 23 | } 24 | 25 | return _invoker.InvokeAction(controllerContext, actionName); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/MvcHaack.ControllerInspector/InspectorControllerFactory.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.Web; 3 | using System.Web.Mvc; 4 | using System.Web.Routing; 5 | using System.Web.SessionState; 6 | 7 | namespace MvcHaack.ControllerInspector 8 | { 9 | public class InspectorControllerFactory : IControllerFactory 10 | { 11 | readonly IControllerFactory _controllerFactory; 12 | public InspectorControllerFactory(IControllerFactory controllerFactory) 13 | { 14 | _controllerFactory = controllerFactory; 15 | } 16 | 17 | public IController CreateController(RequestContext requestContext, string controllerName) 18 | { 19 | var controller = _controllerFactory.CreateController(requestContext, controllerName); 20 | 21 | if (IsInspectorRequest(requestContext.HttpContext.Request)) 22 | { 23 | var normalController = controller as Controller; 24 | if (normalController != null) 25 | { 26 | var invoker = normalController.ActionInvoker; 27 | normalController.ActionInvoker = new InspectorActionInvoker(invoker); 28 | } 29 | } 30 | return controller; 31 | } 32 | 33 | private static bool IsInspectorRequest(HttpRequestBase httpRequest) 34 | { 35 | return httpRequest.IsLocal 36 | && httpRequest.QueryString.Keys.Count > 0 37 | && httpRequest.QueryString.GetValues(null) != null 38 | && httpRequest.QueryString.GetValues(null).Contains("inspect"); 39 | } 40 | 41 | public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName) 42 | { 43 | return _controllerFactory.GetControllerSessionBehavior(requestContext, controllerName); 44 | } 45 | 46 | public void ReleaseController(IController controller) 47 | { 48 | _controllerFactory.ReleaseController(controller); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/MvcHaack.ControllerInspector/MvcHaack.ControllerInspector.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $id$ 5 | $version$ 6 | $author$ 7 | $author$ 8 | http://www.opensource.org/licenses/mit-license.php 9 | https://github.com/Haacked/CodeHaacks 10 | http://haacked.com/images/Inspector-120x120.png 11 | false 12 | $description$ 13 | 14 | 1.0.0.1 Fixed a nullref issue when using qeury strings other than ?inspect 15 | 1.1.0 Added ControllerValidator class for finding bad controllers. 16 | 17 | aspnetmvc controllerdescriptor controller 18 | 19 | -------------------------------------------------------------------------------- /src/MvcHaack.ControllerInspector/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | 8 | [assembly: AssemblyTitle("Controller Inspector for ASP.NET MVC 3")] 9 | [assembly: 10 | AssemblyDescription("Adds the ability to inspect metadata about a controller by adding the ?inspect query string.")] 11 | [assembly: AssemblyConfiguration("")] 12 | [assembly: AssemblyCompany("Phil Haack")] 13 | [assembly: AssemblyProduct("MvcHaack.ControllerInspector")] 14 | [assembly: AssemblyCopyright("Copyright © Phil Haack 2011")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | 24 | [assembly: Guid("b287cb00-6351-4c98-b9fa-1403fd47a432")] 25 | 26 | // Version information for an assembly consists of the following four values: 27 | // 28 | // Major Version 29 | // Minor Version 30 | // Build Number 31 | // Revision 32 | // 33 | // You can specify all the values or you can default the Build and Revision Numbers 34 | // by using the '*' as shown below: 35 | // [assembly: AssemblyVersion("1.0.*")] 36 | 37 | [assembly: AssemblyVersion("1.1.0.0")] 38 | [assembly: AssemblyFileVersion("1.1.0.0")] -------------------------------------------------------------------------------- /src/MvcHaack.ControllerInspector/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/MvcHaack.ViewMobilizer/MvcHaack.ViewMobilizer.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | MvcHaack.ViewMobilizer 5 | 0.3.0.2 6 | 7 | <authors>Phil Haack</authors> 8 | <owners /> 9 | <requireLicenseAcceptance>false</requireLicenseAcceptance> 10 | <description>Creates mobile versions of existing views</description> 11 | <summary /> 12 | </metadata> 13 | <files> 14 | <file src="bin\Debug\MvcHaack.ViewMobilizer.dll" target="recipes\MvcHaack.ViewMobilizer.dll" /> 15 | </files> 16 | </package> -------------------------------------------------------------------------------- /src/MvcHaack.ViewMobilizer/MvcHaack.ViewMobilizer.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haacked/CodeHaacks/9d6dd8b6c9498d5cfca38580667c05ca2321b8de/src/MvcHaack.ViewMobilizer/MvcHaack.ViewMobilizer.zip -------------------------------------------------------------------------------- /src/MvcHaack.ViewMobilizer/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("MvcHaack.ViewMobilizer")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("MvcHaack.ViewMobilizer")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2011")] 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("01ed49e5-048d-4dfd-a965-d33cf66fd216")] 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 | -------------------------------------------------------------------------------- /src/MvcHaack.ViewMobilizer/Resources/ViewMobilizer.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haacked/CodeHaacks/9d6dd8b6c9498d5cfca38580667c05ca2321b8de/src/MvcHaack.ViewMobilizer/Resources/ViewMobilizer.ico -------------------------------------------------------------------------------- /src/MvcHaack.ViewMobilizer/ViewMobilizerForm.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Windows.Forms; 3 | using Microsoft.VisualStudio.Web.Mvc.Extensibility; 4 | 5 | namespace MvcHaack.ViewMobilizer { 6 | public partial class ViewMobilizerForm : Form { 7 | ViewMobilizerModel model = null; 8 | public ViewMobilizerForm(ViewMobilizerModel model) { 9 | InitializeComponent(); 10 | foreach (var view in model.Views.Values) { 11 | viewsCheckBoxList.Items.Add(view.RelativePath, false); 12 | } 13 | this.model = model; 14 | } 15 | 16 | private void mobilizeButton_Click(object sender, System.EventArgs e) { 17 | foreach (string item in viewsCheckBoxList.CheckedItems) { 18 | var file = this.model.Views[item]; 19 | string mobileName = file.FullName.Substring(0, file.FullName.Length - ".cshtml".Length) + model.DeviceSpecificExtension; 20 | 21 | this.model.SelectedViews.Add(new Tuple<ProjectFile, string>(file, mobileName)); 22 | } 23 | } 24 | 25 | private void OnSuffixTextBoxLeave(object sender, EventArgs e) { 26 | this.model.Populate(suffixTextBox.Text); 27 | viewsCheckBoxList.Items.Clear(); 28 | foreach (var view in model.Views.Values) { 29 | viewsCheckBoxList.Items.Add(view.RelativePath, false); 30 | } 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/MvcHaack.ViewMobilizer/ViewMobilizerModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using Microsoft.VisualStudio.Web.Mvc.Extensibility; 5 | 6 | namespace MvcHaack.ViewMobilizer 7 | { 8 | public class ViewMobilizerModel 9 | { 10 | public ViewMobilizerModel(ProjectFolder folder) 11 | : this(folder, "mobile") 12 | { 13 | } 14 | 15 | public ViewMobilizerModel(ProjectFolder folder, string suffix) 16 | { 17 | Folder = folder; 18 | Populate(suffix); 19 | } 20 | 21 | public ProjectFolder Folder { get; set; } 22 | 23 | public string Suffix { get; private set; } 24 | 25 | public string DeviceSpecificExtension { get; private set; } 26 | 27 | public void Populate(string suffix) 28 | { 29 | Suffix = suffix; 30 | DeviceSpecificExtension = String.Format(".{0}.cshtml", Suffix); 31 | var views = new Dictionary<string, ProjectFile>(StringComparer.OrdinalIgnoreCase); 32 | FilterViews(Folder, views); 33 | Views = views; 34 | SelectedViews = new List<Tuple<ProjectFile, string>>(); 35 | } 36 | 37 | 38 | 39 | private void FilterViews(ProjectFolder folder, Dictionary<string, ProjectFile> views) 40 | { 41 | // Collect 42 | Traverse(folder, file => views.Add(file.RelativePath, file)); 43 | 44 | // Filter 45 | Traverse(folder, file => RemoveDeviceSpecificWithCorrespondingDesktop(file, views)); 46 | } 47 | 48 | private void Traverse(ProjectFolder folder, Action<ProjectFile> action) 49 | { 50 | foreach (var file in folder.Files.Where(file => file.RelativePath.EndsWith(".cshtml", StringComparison.OrdinalIgnoreCase))) 51 | { 52 | action(file); 53 | } 54 | foreach (var subfolder in folder.Folders) 55 | { 56 | Traverse(subfolder, action); 57 | } 58 | } 59 | 60 | private void RemoveDeviceSpecificWithCorrespondingDesktop(ProjectFile file, Dictionary<string, ProjectFile> views) 61 | { 62 | string path = file.RelativePath; 63 | 64 | if (!path.EndsWith(DeviceSpecificExtension, StringComparison.OrdinalIgnoreCase)) return; 65 | 66 | int preSuffixIndex = path.Length - DeviceSpecificExtension.Length; 67 | string desktopPath = path.Substring(0, preSuffixIndex) + ".cshtml"; 68 | if (views.ContainsKey(desktopPath)) 69 | { 70 | views.Remove(desktopPath); 71 | views.Remove(path); 72 | } 73 | } 74 | 75 | public Dictionary<string, ProjectFile> Views { get; private set; } 76 | 77 | public List<Tuple<ProjectFile, string>> SelectedViews { get; private set; } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/MvcHaack.ViewMobilizer/ViewMobilizerRecipe.cs: -------------------------------------------------------------------------------- 1 | using System.ComponentModel.Composition; 2 | using System.Drawing; 3 | using System.IO; 4 | using System.Windows.Forms; 5 | using Microsoft.VisualStudio.Web.Mvc.Extensibility; 6 | using Microsoft.VisualStudio.Web.Mvc.Extensibility.Recipes; 7 | using MvcHaack.ViewMobilizer.Properties; 8 | 9 | namespace MvcHaack.ViewMobilizer 10 | { 11 | [Export(typeof(IRecipe))] 12 | public class ViewMobilizerRecipe : IFolderRecipe 13 | { 14 | public bool Execute(ProjectFolder folder) 15 | { 16 | var model = new ViewMobilizerModel(folder); 17 | var form = new ViewMobilizerForm(model); 18 | 19 | var result = form.ShowDialog(); 20 | if (result == DialogResult.OK) 21 | { 22 | foreach (var view in model.SelectedViews) 23 | { 24 | var file = view.Item1; 25 | string mobileFileName = view.Item2; 26 | 27 | File.Copy(file.FullName, mobileFileName); 28 | folder.DteProjectItems.AddFromFile(mobileFileName); 29 | } 30 | } 31 | return true; 32 | } 33 | 34 | public bool IsValidTarget(ProjectFolder folder) 35 | { 36 | return true; 37 | } 38 | 39 | public string Description 40 | { 41 | get { return "A package for creating display mode views."; } 42 | } 43 | 44 | public Icon Icon 45 | { 46 | get { return Resources.ViewMobilizer; } 47 | } 48 | 49 | public string Name 50 | { 51 | get { return "View Mobilizer"; } 52 | } 53 | } 54 | } 55 | 56 | -------------------------------------------------------------------------------- /src/MvcHaack.ViewMobilizer/packages.config: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="utf-8"?> 2 | <packages> 3 | <package id="AspNetMvc4.RecipeSdk" version="0.1" /> 4 | </packages> -------------------------------------------------------------------------------- /src/ViewMobilizerTests/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("ViewMobilizerTests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("ViewMobilizerTests")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2011")] 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("56794b32-0fda-4346-82bd-e605fd542476")] 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 | -------------------------------------------------------------------------------- /src/ViewMobilizerTests/packages.config: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="utf-8"?> 2 | <packages> 3 | <package id="AspNetMvc4.RecipeSdk" version="0.1" /> 4 | <package id="Moq" version="4.0.10827" /> 5 | <package id="xunit" version="1.8.0.1549" /> 6 | </packages> -------------------------------------------------------------------------------- /src/WebApiHaack.DemoWeb/Api/CommentsApi.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using System.ServiceModel; 3 | using System.ServiceModel.Web; 4 | 5 | namespace WebApiHaack.DemoWeb.Api 6 | { 7 | [ServiceContract] 8 | public class CommentsApi 9 | { 10 | [WebGet] 11 | public IQueryable<Comment> Get() 12 | { 13 | return new[] { new Comment 14 | { 15 | Title = "This is neato", 16 | Body = "Ok, not as neat as I originally thought." } 17 | }.AsQueryable(); 18 | } 19 | 20 | [WebGet(UriTemplate = "auth"), RequireAuthorization] 21 | public IQueryable<Comment> GetAuth() 22 | { 23 | return new[] { new Comment 24 | { 25 | Title = "This is secured neato", 26 | Body = "Ok, a bit neater than I originally thought." } 27 | }.AsQueryable(); 28 | } 29 | } 30 | } -------------------------------------------------------------------------------- /src/WebApiHaack.DemoWeb/AppStart/CommentsConfiguration.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.ApplicationServer.Http; 2 | 3 | namespace WebApiHaack.DemoWeb.AppStart 4 | { 5 | public class CommentsConfiguration : WebApiConfiguration 6 | { 7 | public CommentsConfiguration() 8 | { 9 | EnableTestClient = true; 10 | 11 | RequestHandlers = (c, e, od) => 12 | { 13 | // TODO: Configure request operation handlers 14 | }; 15 | 16 | this.AppendAuthorizationRequestHandlers(); 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /src/WebApiHaack.DemoWeb/Global.asax: -------------------------------------------------------------------------------- 1 | <%@ Application Codebehind="Global.asax.cs" Inherits="WebApiHaack.DemoWeb.Global" Language="C#" %> 2 | -------------------------------------------------------------------------------- /src/WebApiHaack.DemoWeb/Global.asax.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Web; 3 | using System.Web.Routing; 4 | using WebApiHaack.DemoWeb.Api; 5 | using WebApiHaack.DemoWeb.AppStart; 6 | 7 | namespace WebApiHaack.DemoWeb 8 | { 9 | public class Global : HttpApplication 10 | { 11 | protected void Application_Start(object sender, EventArgs e) 12 | { 13 | RouteTable.Routes.MapServiceRoute<CommentsApi>("comments", new CommentsConfiguration()); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /src/WebApiHaack.DemoWeb/Models/Comment.cs: -------------------------------------------------------------------------------- 1 |  2 | namespace WebApiHaack.DemoWeb.Api 3 | { 4 | public class Comment 5 | { 6 | public string Title { get; set; } 7 | public string Body { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/WebApiHaack.DemoWeb/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("WebApiHaack.DemoWeb")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("Microsoft")] 12 | [assembly: AssemblyProduct("WebApiHaack.DemoWeb")] 13 | [assembly: AssemblyCopyright("Copyright © Microsoft 2011")] 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("7e4400e0-abe6-4666-9968-215cceb7abae")] 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 | -------------------------------------------------------------------------------- /src/WebApiHaack.DemoWeb/Web.Debug.config: -------------------------------------------------------------------------------- 1 | <?xml version="1.0"?> 2 | 3 | <!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 --> 4 | 5 | <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> 6 | <!-- 7 | In the example below, the "SetAttributes" transform will change the value of 8 | "connectionString" to use "ReleaseSQLServer" only when the "Match" locator 9 | finds an atrribute "name" that has a value of "MyDB". 10 | 11 | <connectionStrings> 12 | <add name="MyDB" 13 | connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True" 14 | xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/> 15 | </connectionStrings> 16 | --> 17 | <system.web> 18 | <!-- 19 | In the example below, the "Replace" transform will replace the entire 20 | <customErrors> section of your web.config file. 21 | Note that because there is only one customErrors section under the 22 | <system.web> node, there is no need to use the "xdt:Locator" attribute. 23 | 24 | <customErrors defaultRedirect="GenericError.htm" 25 | mode="RemoteOnly" xdt:Transform="Replace"> 26 | <error statusCode="500" redirect="InternalError.htm"/> 27 | </customErrors> 28 | --> 29 | </system.web> 30 | </configuration> -------------------------------------------------------------------------------- /src/WebApiHaack.DemoWeb/Web.Release.config: -------------------------------------------------------------------------------- 1 | <?xml version="1.0"?> 2 | 3 | <!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 --> 4 | 5 | <configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform"> 6 | <!-- 7 | In the example below, the "SetAttributes" transform will change the value of 8 | "connectionString" to use "ReleaseSQLServer" only when the "Match" locator 9 | finds an atrribute "name" that has a value of "MyDB". 10 | 11 | <connectionStrings> 12 | <add name="MyDB" 13 | connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True" 14 | xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/> 15 | </connectionStrings> 16 | --> 17 | <system.web> 18 | <compilation xdt:Transform="RemoveAttributes(debug)" /> 19 | <!-- 20 | In the example below, the "Replace" transform will replace the entire 21 | <customErrors> section of your web.config file. 22 | Note that because there is only one customErrors section under the 23 | <system.web> node, there is no need to use the "xdt:Locator" attribute. 24 | 25 | <customErrors defaultRedirect="GenericError.htm" 26 | mode="RemoteOnly" xdt:Transform="Replace"> 27 | <error statusCode="500" redirect="InternalError.htm"/> 28 | </customErrors> 29 | --> 30 | </system.web> 31 | </configuration> -------------------------------------------------------------------------------- /src/WebApiHaack.DemoWeb/Web.config: -------------------------------------------------------------------------------- 1 | <?xml version="1.0" encoding="utf-8"?> 2 | <!-- 3 | For more information on how to configure your ASP.NET application, please visit 4 | http://go.microsoft.com/fwlink/?LinkId=169433 5 | --> 6 | <configuration> 7 | <system.web> 8 | <compilation debug="true" targetFramework="4.0" /> 9 | <authentication mode="Forms"> 10 | <forms loginUrl="~/logon.htm" timeout="2880" /> 11 | </authentication> 12 | </system.web> 13 | <system.serviceModel> 14 | <serviceHostingEnvironment aspNetCompatibilityEnabled="true" /> 15 | </system.serviceModel> 16 | </configuration> -------------------------------------------------------------------------------- /src/WebApiHaack.DemoWeb/default.htm: -------------------------------------------------------------------------------- 1 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 | <html xmlns="http://www.w3.org/1999/xhtml"> 3 | <head> 4 | <title> 5 | 6 | 7 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/WebApiHaack.DemoWeb/logon.htm: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 |

    You are not authenticated!

    8 |

    9 | Sorry, I was too lazy to finish this demo with a logon page. 10 |

    11 |

    12 | But fork me on GitHub 13 | and help me flesh out the demo! 14 |

    15 | 16 | 17 | -------------------------------------------------------------------------------- /src/WebApiHaack.DemoWeb/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/WebApiHaack/ConfigExtensions.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using Microsoft.ApplicationServer.Http; 3 | 4 | namespace WebApiHaack 5 | { 6 | public static class ConfigExtensions 7 | { 8 | public static void AppendAuthorizationRequestHandlers(this WebApiConfiguration config) 9 | { 10 | var requestHandlers = config.RequestHandlers; 11 | config.RequestHandlers = (c, e, od) => 12 | { 13 | if (requestHandlers != null) 14 | { 15 | requestHandlers(c, e, od); // Original request handler 16 | } 17 | var authorizeAttribute = od.Attributes.OfType().FirstOrDefault(); 18 | if (authorizeAttribute != null) 19 | { 20 | c.Add(new AuthOperationHandler(authorizeAttribute)); 21 | } 22 | }; 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/WebApiHaack/OperationHandlers/AuthOperationHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Net; 4 | using System.Net.Http; 5 | using System.Security.Principal; 6 | using System.Threading; 7 | using Microsoft.ApplicationServer.Http.Dispatcher; 8 | 9 | namespace WebApiHaack 10 | { 11 | public class AuthOperationHandler : HttpOperationHandler 12 | { 13 | readonly RequireAuthorizationAttribute _authorizeAttribute; 14 | 15 | public AuthOperationHandler(RequireAuthorizationAttribute authorizeAttribute) 16 | : base("response") 17 | { 18 | _authorizeAttribute = authorizeAttribute; 19 | } 20 | 21 | protected override HttpRequestMessage OnHandle(HttpRequestMessage input) 22 | { 23 | IPrincipal user = Thread.CurrentPrincipal; 24 | if (!user.Identity.IsAuthenticated) 25 | { 26 | throw new HttpResponseException(HttpStatusCode.Unauthorized); 27 | } 28 | 29 | if (_authorizeAttribute.Roles == null) 30 | { 31 | return input; 32 | } 33 | 34 | var roles = _authorizeAttribute.Roles.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries); 35 | if (roles.Any(user.IsInRole)) 36 | { 37 | return input; 38 | } 39 | 40 | throw new HttpResponseException(HttpStatusCode.Unauthorized); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/WebApiHaack/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("WebApiHaack")] 8 | [assembly: AssemblyDescription("A library with useful extensions to Web API")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("Phil Haack")] 11 | [assembly: AssemblyProduct("WebApiHaack")] 12 | [assembly: AssemblyCopyright("Copyright © Phil Haack 2011")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("4851334c-0a14-439f-b0c5-f9fcf1f447ff")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("0.0.1.0")] 35 | [assembly: AssemblyFileVersion("0.0.1.0")] 36 | -------------------------------------------------------------------------------- /src/WebApiHaack/RequireAuthorizationAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace WebApiHaack 4 | { 5 | [AttributeUsage(AttributeTargets.Method)] 6 | public class RequireAuthorizationAttribute : Attribute 7 | { 8 | public string Roles { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/WebApiHaack/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/WindowPlacementRxDemo/App.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/WindowPlacementRxDemo/App.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Configuration; 4 | using System.Data; 5 | using System.Linq; 6 | using System.Windows; 7 | 8 | namespace WindowPlacementRxDemo 9 | { 10 | /// 11 | /// Interaction logic for App.xaml 12 | /// 13 | public partial class App : Application 14 | { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/WindowPlacementRxDemo/MainWindow.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/WindowPlacementRxDemo/MainWindow.xaml.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reactive; 3 | using System.Reactive.Linq; 4 | using System.Windows; 5 | using ReactiveUI; 6 | using WindowPlacementExample; 7 | 8 | namespace WindowPlacementRxDemo 9 | { 10 | /// 11 | /// Interaction logic for MainWindow.xaml 12 | /// 13 | public partial class MainWindow : Window 14 | { 15 | public MainWindow() 16 | { 17 | InitializeComponent(); 18 | 19 | Observable.Merge( 20 | Observable.FromEventPattern 21 | (h => SizeChanged += h, h => SizeChanged -= h) 22 | .Select(e => Unit.Default), 23 | Observable.FromEventPattern 24 | (h => LocationChanged += h, h => LocationChanged -= h) 25 | .Select(e => Unit.Default) 26 | ).Throttle(TimeSpan.FromSeconds(5), RxApp.DeferredScheduler) 27 | .Subscribe(_ => 28 | { 29 | info.Text = "Placement saved: " + DateTime.Now; 30 | this.SavePlacement(); 31 | }); 32 | } 33 | 34 | protected override void OnSourceInitialized(EventArgs e) 35 | { 36 | base.OnSourceInitialized(e); 37 | this.RestorePlacement(); 38 | } 39 | 40 | protected override void OnClosing(System.ComponentModel.CancelEventArgs e) 41 | { 42 | this.SavePlacement(); 43 | base.OnClosing(e); 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /src/WindowPlacementRxDemo/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Resources; 3 | using System.Runtime.CompilerServices; 4 | using System.Runtime.InteropServices; 5 | using System.Windows; 6 | 7 | // General Information about an assembly is controlled through the following 8 | // set of attributes. Change these attribute values to modify the information 9 | // associated with an assembly. 10 | [assembly: AssemblyTitle("WindowPlacementRxDemo")] 11 | [assembly: AssemblyDescription("")] 12 | [assembly: AssemblyConfiguration("")] 13 | [assembly: AssemblyCompany("")] 14 | [assembly: AssemblyProduct("WindowPlacementRxDemo")] 15 | [assembly: AssemblyCopyright("Copyright © 2012")] 16 | [assembly: AssemblyTrademark("")] 17 | [assembly: AssemblyCulture("")] 18 | 19 | // Setting ComVisible to false makes the types in this assembly not visible 20 | // to COM components. If you need to access a type in this assembly from 21 | // COM, set the ComVisible attribute to true on that type. 22 | [assembly: ComVisible(false)] 23 | 24 | //In order to begin building localizable applications, set 25 | //CultureYouAreCodingWith in your .csproj file 26 | //inside a . For example, if you are using US english 27 | //in your source files, set the to en-US. Then uncomment 28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in 29 | //the line below to match the UICulture setting in the project file. 30 | 31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] 32 | 33 | 34 | [assembly: ThemeInfo( 35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located 36 | //(used if a resource is not found in the page, 37 | // or application resource dictionaries) 38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located 39 | //(used if a resource is not found in the page, 40 | // app, or any theme specific resource dictionaries) 41 | )] 42 | 43 | 44 | // Version information for an assembly consists of the following four values: 45 | // 46 | // Major Version 47 | // Minor Version 48 | // Build Number 49 | // Revision 50 | // 51 | // You can specify all the values or you can default the Build and Revision Numbers 52 | // by using the '*' as shown below: 53 | // [assembly: AssemblyVersion("1.0.*")] 54 | [assembly: AssemblyVersion("1.0.0.0")] 55 | [assembly: AssemblyFileVersion("1.0.0.0")] 56 | -------------------------------------------------------------------------------- /src/WindowPlacementRxDemo/Properties/Resources.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.261 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace WindowPlacementRxDemo.Properties 12 | { 13 | 14 | 15 | /// 16 | /// A strongly-typed resource class, for looking up localized strings, etc. 17 | /// 18 | // This class was auto-generated by the StronglyTypedResourceBuilder 19 | // class via a tool like ResGen or Visual Studio. 20 | // To add or remove a member, edit your .ResX file then rerun ResGen 21 | // with the /str option, or rebuild your VS project. 22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] 23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 25 | internal class Resources 26 | { 27 | 28 | private static global::System.Resources.ResourceManager resourceMan; 29 | 30 | private static global::System.Globalization.CultureInfo resourceCulture; 31 | 32 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] 33 | internal Resources() 34 | { 35 | } 36 | 37 | /// 38 | /// Returns the cached ResourceManager instance used by this class. 39 | /// 40 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 41 | internal static global::System.Resources.ResourceManager ResourceManager 42 | { 43 | get 44 | { 45 | if ((resourceMan == null)) 46 | { 47 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WindowPlacementRxDemo.Properties.Resources", typeof(Resources).Assembly); 48 | resourceMan = temp; 49 | } 50 | return resourceMan; 51 | } 52 | } 53 | 54 | /// 55 | /// Overrides the current thread's CurrentUICulture property for all 56 | /// resource lookups using this strongly typed resource class. 57 | /// 58 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] 59 | internal static global::System.Globalization.CultureInfo Culture 60 | { 61 | get 62 | { 63 | return resourceCulture; 64 | } 65 | set 66 | { 67 | resourceCulture = value; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/WindowPlacementRxDemo/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.261 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace WindowPlacementRxDemo.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | 26 | [global::System.Configuration.UserScopedSettingAttribute()] 27 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] 28 | [global::System.Configuration.DefaultSettingValueAttribute("")] 29 | public string WindowPlacement { 30 | get { 31 | return ((string)(this["WindowPlacement"])); 32 | } 33 | set { 34 | this["WindowPlacement"] = value; 35 | } 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/WindowPlacementRxDemo/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/WindowPlacementRxDemo/app.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 |
    6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/WindowPlacementRxDemo/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | --------------------------------------------------------------------------------