mvccontrib 2.0.95.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/Dependencies/Microsoft.Web.Mvc.dll +0 -0
- data/lib/Dependencies/Rhino.Mocks.dll +0 -0
- data/lib/InputBuilderTemplates/Array.Master +25 -0
- data/lib/InputBuilderTemplates/Array.aspx +173 -0
- data/lib/InputBuilderTemplates/ArrayAddButton.aspx +3 -0
- data/lib/InputBuilderTemplates/ArrayRemoveButton.aspx +3 -0
- data/lib/InputBuilderTemplates/Boolean.aspx +6 -0
- data/lib/InputBuilderTemplates/DateTime.aspx +15 -0
- data/lib/InputBuilderTemplates/Display.Master +9 -0
- data/lib/InputBuilderTemplates/DisplayInline.aspx +6 -0
- data/lib/InputBuilderTemplates/DisplayLabel.aspx +7 -0
- data/lib/InputBuilderTemplates/DisplayParagraph.aspx +4 -0
- data/lib/InputBuilderTemplates/Enum.aspx +8 -0
- data/lib/InputBuilderTemplates/Field.Master +22 -0
- data/lib/InputBuilderTemplates/Form.aspx +8 -0
- data/lib/InputBuilderTemplates/Guid.aspx +6 -0
- data/lib/InputBuilderTemplates/HiddenField.Master +4 -0
- data/lib/InputBuilderTemplates/Int32.aspx +6 -0
- data/lib/InputBuilderTemplates/MultilineText.aspx +3 -0
- data/lib/InputBuilderTemplates/RadioButtons.aspx +14 -0
- data/lib/InputBuilderTemplates/ReadOnly.aspx +8 -0
- data/lib/InputBuilderTemplates/Row.Master +7 -0
- data/lib/InputBuilderTemplates/String.aspx +6 -0
- data/lib/InputBuilderTemplates/Submit.aspx +6 -0
- data/lib/License.txt +71 -0
- data/lib/MvcContrib.FluentHtml.dll +0 -0
- data/lib/MvcContrib.FluentHtml.xml +1291 -0
- data/lib/MvcContrib.TestHelper.XML +1178 -0
- data/lib/MvcContrib.TestHelper.dll +0 -0
- data/lib/MvcContrib.WatiN.dll +0 -0
- data/lib/MvcContrib.XML +2491 -0
- data/lib/MvcContrib.dll +0 -0
- data/lib/T4MVC/T4MVC.settings.t4 +96 -0
- data/lib/T4MVC/T4MVC.tt +1418 -0
- data/lib/T4MVC/readme.txt +224 -0
- data/lib/help/mvccontrib/MvcContrib.ActionResults/ExpressionToRouteValueConverter`1.htm +199 -0
- data/lib/help/mvccontrib/MvcContrib.ActionResults/IControllerExpressionContainer.htm +133 -0
- data/lib/help/mvccontrib/MvcContrib.ActionResults/PermanentRedirectResult.htm +189 -0
- data/lib/help/mvccontrib/MvcContrib.ActionResults/PermanentRedirectToActionResult.htm +145 -0
- data/lib/help/mvccontrib/MvcContrib.ActionResults/RedirectToRouteResult`1.htm +145 -0
- data/lib/help/mvccontrib/MvcContrib.ActionResults/XmlResult.htm +135 -0
- data/lib/help/mvccontrib/MvcContrib.ActionResults/index.htm +127 -0
- data/lib/help/mvccontrib/MvcContrib.Attributes/AbstractParameterBinderAttribute.htm +208 -0
- data/lib/help/mvccontrib/MvcContrib.Attributes/DerivedTypeBinderAwareAttribute.htm +137 -0
- data/lib/help/mvccontrib/MvcContrib.Attributes/DeserializeAttribute.htm +139 -0
- data/lib/help/mvccontrib/MvcContrib.Attributes/RequestStore.htm +272 -0
- data/lib/help/mvccontrib/MvcContrib.Attributes/index.htm +118 -0
- data/lib/help/mvccontrib/MvcContrib.Binders/DerivedTypeModelBinder.htm +126 -0
- data/lib/help/mvccontrib/MvcContrib.Binders/DerivedTypeModelBinderCache.htm +168 -0
- data/lib/help/mvccontrib/MvcContrib.Binders/IPropertyNameProvider.htm +136 -0
- data/lib/help/mvccontrib/MvcContrib.Binders/ITypeStampOperator.htm +136 -0
- data/lib/help/mvccontrib/MvcContrib.Binders/SubControllerBinder.htm +146 -0
- data/lib/help/mvccontrib/MvcContrib.Binders/TypeStampOperator.htm +139 -0
- data/lib/help/mvccontrib/MvcContrib.Binders/index.htm +127 -0
- data/lib/help/mvccontrib/MvcContrib.ControllerFactories/IoCControllerFactory.htm +134 -0
- data/lib/help/mvccontrib/MvcContrib.ControllerFactories/index.htm +109 -0
- data/lib/help/mvccontrib/MvcContrib.EnumerableExtensions/EnumerableExtensions.htm +176 -0
- data/lib/help/mvccontrib/MvcContrib.EnumerableExtensions/index.htm +109 -0
- data/lib/help/mvccontrib/MvcContrib.Filters/DebugAttribute.htm +172 -0
- data/lib/help/mvccontrib/MvcContrib.Filters/LayoutAttribute.htm +182 -0
- data/lib/help/mvccontrib/MvcContrib.Filters/ModelStateToTempDataAttribute.htm +169 -0
- data/lib/help/mvccontrib/MvcContrib.Filters/ParamType.htm +173 -0
- data/lib/help/mvccontrib/MvcContrib.Filters/PassParametersDuringRedirectAttribute.htm +170 -0
- data/lib/help/mvccontrib/MvcContrib.Filters/PreconditionFilter.htm +154 -0
- data/lib/help/mvccontrib/MvcContrib.Filters/PredicatePreconditionFilter.htm +154 -0
- data/lib/help/mvccontrib/MvcContrib.Filters/RegExPreconditionFilter.htm +154 -0
- data/lib/help/mvccontrib/MvcContrib.Filters/RescueAttribute.htm +199 -0
- data/lib/help/mvccontrib/MvcContrib.Filters/SubControllerActionToViewDataAttribute.htm +152 -0
- data/lib/help/mvccontrib/MvcContrib.Filters/TempDataToViewDataAttribute.htm +152 -0
- data/lib/help/mvccontrib/MvcContrib.Filters/UtilityHtmlExtensions.htm +148 -0
- data/lib/help/mvccontrib/MvcContrib.Filters/index.htm +142 -0
- data/lib/help/mvccontrib/MvcContrib.FluentController/AbstractFluentController.htm +269 -0
- data/lib/help/mvccontrib/MvcContrib.FluentController/AbstractRestfulFluentController.htm +305 -0
- data/lib/help/mvccontrib/MvcContrib.FluentController/FluentControllerAction`1.htm +203 -0
- data/lib/help/mvccontrib/MvcContrib.FluentController/index.htm +115 -0
- data/lib/help/mvccontrib/MvcContrib.Interfaces/IDependencyResolver.htm +150 -0
- data/lib/help/mvccontrib/MvcContrib.Interfaces/index.htm +109 -0
- data/lib/help/mvccontrib/MvcContrib.Pagination/CustomPagination`1.htm +168 -0
- data/lib/help/mvccontrib/MvcContrib.Pagination/IPagination.htm +168 -0
- data/lib/help/mvccontrib/MvcContrib.Pagination/IPagination`1.htm +123 -0
- data/lib/help/mvccontrib/MvcContrib.Pagination/LazyPagination`1.htm +191 -0
- data/lib/help/mvccontrib/MvcContrib.Pagination/PaginationHelper.htm +163 -0
- data/lib/help/mvccontrib/MvcContrib.Pagination/index.htm +124 -0
- data/lib/help/mvccontrib/MvcContrib.PortableAreas/ApplicationBus.htm +524 -0
- data/lib/help/mvccontrib/MvcContrib.PortableAreas/AssemblyResourceManager.htm +178 -0
- data/lib/help/mvccontrib/MvcContrib.PortableAreas/EmbeddedResourceController.htm +237 -0
- data/lib/help/mvccontrib/MvcContrib.PortableAreas/IApplicationBus.htm +160 -0
- data/lib/help/mvccontrib/MvcContrib.PortableAreas/ICommandMessage`1.htm +149 -0
- data/lib/help/mvccontrib/MvcContrib.PortableAreas/ICommandResult.htm +149 -0
- data/lib/help/mvccontrib/MvcContrib.PortableAreas/IEventMessage.htm +139 -0
- data/lib/help/mvccontrib/MvcContrib.PortableAreas/IMessageHandler.htm +160 -0
- data/lib/help/mvccontrib/MvcContrib.PortableAreas/IMessageHandlerFactory.htm +152 -0
- data/lib/help/mvccontrib/MvcContrib.PortableAreas/IMessageHandler`1.htm +152 -0
- data/lib/help/mvccontrib/MvcContrib.PortableAreas/IQueryMessage`1.htm +149 -0
- data/lib/help/mvccontrib/MvcContrib.PortableAreas/MessageHandlerFactory.htm +139 -0
- data/lib/help/mvccontrib/MvcContrib.PortableAreas/MessageHandler`1.htm +139 -0
- data/lib/help/mvccontrib/MvcContrib.PortableAreas/PortableAreaRegistration.htm +178 -0
- data/lib/help/mvccontrib/MvcContrib.PortableAreas/index.htm +151 -0
- data/lib/help/mvccontrib/MvcContrib.Routing/CompressResponseAttribute.htm +148 -0
- data/lib/help/mvccontrib/MvcContrib.Routing/DebugHttpHandler.htm +171 -0
- data/lib/help/mvccontrib/MvcContrib.Routing/DebugRoute.htm +211 -0
- data/lib/help/mvccontrib/MvcContrib.Routing/DebugRouteHandler.htm +148 -0
- data/lib/help/mvccontrib/MvcContrib.Routing/MvcRoute.htm +256 -0
- data/lib/help/mvccontrib/MvcContrib.Routing/RegexRoute.htm +183 -0
- data/lib/help/mvccontrib/MvcContrib.Routing/RouteAttributeUtility.htm +162 -0
- data/lib/help/mvccontrib/MvcContrib.Routing/RouteDebugger.htm +152 -0
- data/lib/help/mvccontrib/MvcContrib.Routing/UrlRouteAttribute.htm +163 -0
- data/lib/help/mvccontrib/MvcContrib.Routing/UrlRouteParameterConstraintAttribute.htm +156 -0
- data/lib/help/mvccontrib/MvcContrib.Routing/UrlRouteParameterDefaultAttribute.htm +156 -0
- data/lib/help/mvccontrib/MvcContrib.Routing/index.htm +139 -0
- data/lib/help/mvccontrib/MvcContrib.Services/DependencyResolver.htm +144 -0
- data/lib/help/mvccontrib/MvcContrib.Services/EmailMetadata.htm +165 -0
- data/lib/help/mvccontrib/MvcContrib.Services/EmailTemplateService.htm +125 -0
- data/lib/help/mvccontrib/MvcContrib.Services/IEmailTemplateService.htm +147 -0
- data/lib/help/mvccontrib/MvcContrib.Services/IViewStreamReader.htm +136 -0
- data/lib/help/mvccontrib/MvcContrib.Services/index.htm +124 -0
- data/lib/help/mvccontrib/MvcContrib.SimplyRestful/IRestfulActionResolver.htm +136 -0
- data/lib/help/mvccontrib/MvcContrib.SimplyRestful/RestfulAction.htm +238 -0
- data/lib/help/mvccontrib/MvcContrib.SimplyRestful/RestfulActionResolver.htm +123 -0
- data/lib/help/mvccontrib/MvcContrib.SimplyRestful/RestfulGetAction.htm +194 -0
- data/lib/help/mvccontrib/MvcContrib.SimplyRestful/RestfulPostAction.htm +172 -0
- data/lib/help/mvccontrib/MvcContrib.SimplyRestful/SimplyRestfulRouteHandler.htm +185 -0
- data/lib/help/mvccontrib/MvcContrib.SimplyRestful/index.htm +127 -0
- data/lib/help/mvccontrib/MvcContrib.Sorting/SortDirection.htm +153 -0
- data/lib/help/mvccontrib/MvcContrib.Sorting/SortExtensions.htm +150 -0
- data/lib/help/mvccontrib/MvcContrib.Sorting/index.htm +112 -0
- data/lib/help/mvccontrib/MvcContrib.UI.ASPXViewEngine/AutoTypeViewPage`1.htm +973 -0
- data/lib/help/mvccontrib/MvcContrib.UI.ASPXViewEngine/AutoTypeViewUserControl`1.htm +354 -0
- data/lib/help/mvccontrib/MvcContrib.UI.ASPXViewEngine/index.htm +112 -0
- data/lib/help/mvccontrib/MvcContrib.UI.DataList/DataListExtensions.htm +141 -0
- data/lib/help/mvccontrib/MvcContrib.UI.DataList/DataList`1.htm +243 -0
- data/lib/help/mvccontrib/MvcContrib.UI.DataList/index.htm +112 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Grid.ActionSyntax/ActionSyntaxExtensions.htm +209 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Grid.ActionSyntax/index.htm +109 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Grid.Syntax/IGridWithOptions`1.htm +162 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Grid.Syntax/IGrid`1.htm +132 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Grid.Syntax/index.htm +112 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Grid/AutoColumnGridModel`1.htm +160 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Grid/ColumnBuilder`1.htm +182 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Grid/GridColumn`1.htm +211 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Grid/GridExtensions.htm +292 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Grid/GridModel`1.htm +215 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Grid/GridRenderer`1.htm +147 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Grid/GridRowViewData`1.htm +162 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Grid/GridRow`1.htm +169 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Grid/GridSections`1.htm +147 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Grid/GridSortOptions.htm +162 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Grid/Grid`1.htm +162 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Grid/HtmlTableGridRenderer`1.htm +147 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Grid/IGridColumn`1.htm +240 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Grid/IGridModel`1.htm +182 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Grid/IGridRenderer`1.htm +167 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Grid/IGridSections`1.htm +160 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Grid/RenderingContext.htm +167 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Grid/index.htm +160 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Html/HtmlHelperExtension.htm +166 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Html/HtmlStringExtensions.htm +157 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Html/ModelVisualizerExtension.htm +157 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Html/index.htm +115 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Attributes/CanDeleteAllAttribute.htm +135 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Attributes/DisplayOrderAttribute.htm +140 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Attributes/ExampleAttribute.htm +184 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Attributes/LabelAttribute.htm +155 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Attributes/NoAddAttribute.htm +135 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Attributes/NoDeleteAttribute.htm +135 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Attributes/PartialViewAttribute.htm +155 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Attributes/index.htm +127 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Conventions/DateTimePropertyConvention.htm +129 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Conventions/DefaultNameConvention.htm +129 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Conventions/DefaultProperyConvention.htm +198 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Conventions/EnumPropertyConvention.htm +129 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Conventions/GuidPropertyConvention.htm +129 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Conventions/IPropertyViewModelFactory.htm +150 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Conventions/IPropertyViewModelNameConvention.htm +142 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Conventions/IRequireViewModelFactory.htm +142 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Conventions/PropertyInfoExtensions.htm +166 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Conventions/index.htm +136 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Helpers/DisplayOrderExtensions.htm +130 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Helpers/ExpressionHelper.htm +130 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Helpers/ReflectionHelper.htm +162 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Helpers/index.htm +115 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.InputSpecification/DefaultTypeViewModelFactoryConvention.htm +142 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.InputSpecification/IInputSpecification`1.htm +139 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.InputSpecification/ITypeViewModelFactory.htm +129 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.InputSpecification/IViewModelFactory.htm +142 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.InputSpecification/InputPropertySpecification.htm +160 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.InputSpecification/InputTypeSpecification`1.htm +154 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.InputSpecification/Input`1.htm +158 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.InputSpecification/RenderInputBuilderException.htm +182 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.InputSpecification/ViewModelFactory`1.htm +174 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.InputSpecification/index.htm +136 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.ViewEngine/AssemblyResourceProvider.htm +212 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.ViewEngine/AssemblyResourceStore.htm +160 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.ViewEngine/AssemblyResourceVirtualFile.htm +152 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.ViewEngine/InputBuilderViewEngine.htm +188 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.ViewEngine/index.htm +118 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Views/DisplayPartial.htm +167 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Views/HtmlDisplayExtensions.htm +150 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Views/HtmlExtensions.htm +214 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Views/IInputSpecificationExtensions.htm +166 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Views/ModelType`1.htm +179 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Views/Partial.htm +255 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Views/PropertyViewModel.htm +207 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Views/PropertyViewModel`1.htm +194 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Views/TypeViewModel.htm +179 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder.Views/index.htm +133 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder/ArrayPropertyConvention.htm +159 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder/ArrayTypeViewModelExtensions.htm +142 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder/DefaultPropertyConventionsFactory.htm +274 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder/DefaultTypeConventionsFactory.htm +274 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder/InputBuilder.htm +181 -0
- data/lib/help/mvccontrib/MvcContrib.UI.InputBuilder/index.htm +121 -0
- data/lib/help/mvccontrib/MvcContrib.UI.MenuBuilder/ActionMenuItem`1.htm +221 -0
- data/lib/help/mvccontrib/MvcContrib.UI.MenuBuilder/AuthorizeAttributeExtensions.htm +144 -0
- data/lib/help/mvccontrib/MvcContrib.UI.MenuBuilder/Menu.htm +375 -0
- data/lib/help/mvccontrib/MvcContrib.UI.MenuBuilder/MenuBuilderHtmlExtensions.htm +149 -0
- data/lib/help/mvccontrib/MvcContrib.UI.MenuBuilder/MenuHelpText.htm +148 -0
- data/lib/help/mvccontrib/MvcContrib.UI.MenuBuilder/MenuItem.htm +362 -0
- data/lib/help/mvccontrib/MvcContrib.UI.MenuBuilder/MenuList.htm +268 -0
- data/lib/help/mvccontrib/MvcContrib.UI.MenuBuilder/MenuTitle.htm +148 -0
- data/lib/help/mvccontrib/MvcContrib.UI.MenuBuilder/OpenAuthorizeAttribute.htm +180 -0
- data/lib/help/mvccontrib/MvcContrib.UI.MenuBuilder/SecureActionMenuItem`1.htm +208 -0
- data/lib/help/mvccontrib/MvcContrib.UI.MenuBuilder/index.htm +136 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Pager/Pager.htm +183 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Pager/PaginationExtensions.htm +156 -0
- data/lib/help/mvccontrib/MvcContrib.UI.Pager/index.htm +112 -0
- data/lib/help/mvccontrib/MvcContrib.UI.ParamBuilder/ExplicitFacadeDictionary`2.htm +119 -0
- data/lib/help/mvccontrib/MvcContrib.UI.ParamBuilder/ParamBuilder.htm +148 -0
- data/lib/help/mvccontrib/MvcContrib.UI.ParamBuilder/ParamNames.htm +135 -0
- data/lib/help/mvccontrib/MvcContrib.UI.ParamBuilder/Params.htm +134 -0
- data/lib/help/mvccontrib/MvcContrib.UI.ParamBuilder/index.htm +118 -0
- data/lib/help/mvccontrib/MvcContrib.UI.ReturnUrl/IReturnUrlManager.htm +136 -0
- data/lib/help/mvccontrib/MvcContrib.UI.ReturnUrl/ReturnUrlManager.htm +144 -0
- data/lib/help/mvccontrib/MvcContrib.UI.ReturnUrl/index.htm +115 -0
- data/lib/help/mvccontrib/MvcContrib.UI/CleanTagBuilder.htm +210 -0
- data/lib/help/mvccontrib/MvcContrib.UI/index.htm +109 -0
- data/lib/help/mvccontrib/MvcContrib.ViewFactories/FileSystemViewSourceLoader.htm +138 -0
- data/lib/help/mvccontrib/MvcContrib.ViewFactories/FileViewSource.htm +134 -0
- data/lib/help/mvccontrib/MvcContrib.ViewFactories/IViewSource.htm +147 -0
- data/lib/help/mvccontrib/MvcContrib.ViewFactories/IViewSourceLoader.htm +167 -0
- data/lib/help/mvccontrib/MvcContrib.ViewFactories/index.htm +121 -0
- data/lib/help/mvccontrib/MvcContrib/Bus.htm +178 -0
- data/lib/help/mvccontrib/MvcContrib/ControllerExtensions.htm +212 -0
- data/lib/help/mvccontrib/MvcContrib/ConversionExtensions.htm +186 -0
- data/lib/help/mvccontrib/MvcContrib/DefaultConvertible.htm +304 -0
- data/lib/help/mvccontrib/MvcContrib/DictionaryExtensions.htm +192 -0
- data/lib/help/mvccontrib/MvcContrib/Hash.htm +216 -0
- data/lib/help/mvccontrib/MvcContrib/Hash`1.htm +261 -0
- data/lib/help/mvccontrib/MvcContrib/HeadResult.htm +168 -0
- data/lib/help/mvccontrib/MvcContrib/HttpContextExtensions.htm +174 -0
- data/lib/help/mvccontrib/MvcContrib/HttpContextProvider.htm +170 -0
- data/lib/help/mvccontrib/MvcContrib/HttpHeaders.htm +193 -0
- data/lib/help/mvccontrib/MvcContrib/IHttpContextProvider.htm +170 -0
- data/lib/help/mvccontrib/MvcContrib/ISubController.htm +178 -0
- data/lib/help/mvccontrib/MvcContrib/ISubController`1.htm +167 -0
- data/lib/help/mvccontrib/MvcContrib/MimeTypes.htm +182 -0
- data/lib/help/mvccontrib/MvcContrib/NameValueDeserializer.htm +230 -0
- data/lib/help/mvccontrib/MvcContrib/ObjectExtensions.htm +206 -0
- data/lib/help/mvccontrib/MvcContrib/StringExtensions.htm +192 -0
- data/lib/help/mvccontrib/MvcContrib/SubController.htm +271 -0
- data/lib/help/mvccontrib/MvcContrib/SubController`1.htm +247 -0
- data/lib/help/mvccontrib/MvcContrib/UrlHelperExtensions.htm +178 -0
- data/lib/help/mvccontrib/MvcContrib/ViewDataExtensions.htm +288 -0
- data/lib/help/mvccontrib/MvcContrib/index.htm +175 -0
- data/lib/help/mvccontrib/index.htm +29 -0
- data/lib/help/mvccontrib/js/jquery-1.3.2.min.js +19 -0
- data/lib/help/mvccontrib/js/jquery.scrollTo-min.js +11 -0
- data/lib/help/mvccontrib/js/navigation.js +11 -0
- data/lib/help/mvccontrib/main.css +208 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Behaviors/AutoLabelBehavior.htm +130 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Behaviors/AutoLabelSettings.htm +105 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Behaviors/BehaviorMarkerExtensions.htm +118 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Behaviors/CacheingBehaviorApplier.htm +98 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Behaviors/GenericTypeSpec.htm +122 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Behaviors/IBehavior.htm +85 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Behaviors/IBehaviorMarker.htm +85 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Behaviors/IBehavior`1.htm +100 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Behaviors/IBehaviorsContainer.htm +97 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Behaviors/IMemberBehavior.htm +85 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Behaviors/IModelStateHandler.htm +100 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Behaviors/ISupportsMaxLength.htm +87 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Behaviors/ISupportsModelState.htm +98 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Behaviors/MemberBehaviorHelper`1.htm +122 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Behaviors/ThreadSafeDictionary`2.htm +200 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Behaviors/ValidationBehavior.htm +85 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Behaviors/index.htm +99 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/Button.htm +141 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/ButtonBase`1.htm +141 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/CheckBox.htm +141 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/CheckBoxBase`1.htm +166 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/CheckBoxList.htm +151 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/CheckBoxListBase`1.htm +192 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/DisableableElement`1.htm +158 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/Element`1.htm +289 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/FileUpload.htm +141 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/FormElement`1.htm +141 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/FormLiteral.htm +142 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/FormLiteralBase`1.htm +142 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/Hidden.htm +141 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/IElement.htm +229 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/IMemberElement.htm +151 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/Index.htm +180 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/Input`1.htm +170 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/Label.htm +141 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/LabelBase`1.htm +157 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/Literal.htm +141 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/LiteralBase`1.htm +158 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/MultiSelect.htm +151 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/MultiSelect`1.htm +151 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/Option.htm +182 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/OptionsElementBase`1.htm +210 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/Password.htm +141 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/RadioButton.htm +141 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/RadioButtonBase`1.htm +141 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/RadioSet.htm +151 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/RadioSetBase`1.htm +168 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/ResetButton.htm +141 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/ResetButtonBase`1.htm +141 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/Select.htm +151 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/SelectBase`1.htm +213 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/Select`1.htm +151 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/SubmitButton.htm +141 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/SubmitButtonBase`1.htm +141 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/TextArea.htm +139 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/TextAreaBase`1.htm +166 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/TextBox.htm +141 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/TextInput`1.htm +158 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/TypeStamp.htm +155 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Elements/ValidationMessage.htm +141 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Expressions/ExpressionExtensions.htm +96 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Expressions/ExpressionNameVisitor.htm +72 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Expressions/ExpressionNameVisitorResult.htm +74 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Expressions/index.htm +57 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Html/HtmlAttribute.htm +253 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Html/HtmlEventAttribute.htm +77 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Html/HtmlInputType.htm +165 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Html/HtmlTag.htm +165 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml.Html/index.htm +60 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml/IViewModelContainer`1.htm +93 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml/ModelStateDictionaryExtensions.htm +106 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml/ModelViewMasterPage`1.htm +484 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml/ModelViewPage`1.htm +810 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml/ModelViewUserControl`1.htm +314 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml/PartialNameConventionService.htm +106 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml/PartialRenderer`2.htm +107 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml/StringExtensions.htm +108 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml/ViewDataContainerExtensions.htm +320 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml/ViewModelContainerExtensions.htm +412 -0
- data/lib/help/mvccontrib_fluentHtml/MvcContrib.FluentHtml/index.htm +81 -0
- data/lib/help/mvccontrib_fluentHtml/index.htm +29 -0
- data/lib/help/mvccontrib_fluentHtml/js/jquery-1.3.2.min.js +19 -0
- data/lib/help/mvccontrib_fluentHtml/js/jquery.scrollTo-min.js +11 -0
- data/lib/help/mvccontrib_fluentHtml/js/navigation.js +11 -0
- data/lib/help/mvccontrib_fluentHtml/main.css +208 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.Fakes/FakeHttpContext.htm +305 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.Fakes/FakeHttpRequest.htm +316 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.Fakes/FakeHttpResponse.htm +486 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.Fakes/FakeHttpSessionState.htm +235 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.Fakes/FakeIdentity.htm +83 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.Fakes/FakePrincipal.htm +86 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.Fakes/index.htm +64 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.FluentController/ActionExpectations`1.htm +182 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.FluentController/ActionRedirect.htm +103 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.FluentController/ActionRender.htm +115 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.FluentController/ActionReturn.htm +110 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.FluentController/CallSuccess.htm +105 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.FluentController/ControllerRedirect.htm +103 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.FluentController/ControllerRender.htm +102 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.FluentController/GivenController.htm +86 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.FluentController/ModelStateHelper.htm +92 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.FluentController/ViewRender.htm +102 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.FluentController/index.htm +76 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.Ui/AssertExtensions.htm +150 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.Ui/BaseClassLibraryExtensions.htm +134 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.Ui/DisplayTable`1.htm +110 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.Ui/EnumerableExtensions.htm +94 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.Ui/IBrowserDriver.htm +184 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.Ui/IInputTester.htm +102 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.Ui/IInputTesterFactory.htm +94 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.Ui/IMultipleInputTesterFactory.htm +102 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.Ui/InputForm`1.htm +133 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.Ui/InputTesterBase`1.htm +81 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.Ui/InputTesterFactory.htm +466 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.Ui/MultipleInputTesterFactory.htm +250 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.Ui/RowFilter`1.htm +108 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.Ui/TextInputTester.htm +81 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.Ui/TextInputTesterFactory.htm +81 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper.Ui/index.htm +94 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper/ActionResultAssertionException.htm +190 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper/ActionResultHelper.htm +304 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper/AssertionException.htm +137 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper/AttributeExtensions.htm +117 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper/DerivedRoute.htm +95 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper/ElementIdentifier.htm +110 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper/GeneralTestExtensions.htm +155 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper/IRouteType.htm +108 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper/IWriteableHttpFileCollection.htm +109 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper/MethodInfoExtensions.htm +109 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper/NameAndDescriptionIdentifier.htm +110 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper/NamedRoute.htm +95 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper/NavigationLinkIdentifier.htm +110 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper/ObjectExtensions.htm +95 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper/OutBoundUrl.htm +116 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper/OutBoundUrlContext.htm +118 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper/RecordIdentifier.htm +110 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper/RouteTestingExtensions.htm +238 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper/SectionIdentifier.htm +110 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper/TestControllerBuilder.htm +232 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper/WebTestUtility.htm +108 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper/WriteableHttpFileCollection.htm +171 -0
- data/lib/help/mvccontrib_testhelper/MvcContrib.TestHelper/index.htm +115 -0
- data/lib/help/mvccontrib_testhelper/index.htm +29 -0
- data/lib/help/mvccontrib_testhelper/js/jquery-1.3.2.min.js +19 -0
- data/lib/help/mvccontrib_testhelper/js/jquery.scrollTo-min.js +11 -0
- data/lib/help/mvccontrib_testhelper/js/navigation.js +11 -0
- data/lib/help/mvccontrib_testhelper/main.css +208 -0
- metadata +483 -0
data/lib/MvcContrib.dll
ADDED
|
Binary file
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
<#+
|
|
2
|
+
/*
|
|
3
|
+
|
|
4
|
+
This file contains settings used by T4MVC.tt. The main goal is to avoid the need for users
|
|
5
|
+
to fork the 'official' template in order to achieve what they want.
|
|
6
|
+
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
// The prefix used for things like MVC.Dinners.Name and MVC.Dinners.Delete(Model.DinnerID)
|
|
11
|
+
const string HelpersPrefix = "MVC";
|
|
12
|
+
|
|
13
|
+
// Namespaces to be referenced by the generated code
|
|
14
|
+
readonly string[] ReferencedNamespaces = new string[] {
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// The folder under the project that contains the areas
|
|
18
|
+
const string AreasFolder = "Areas";
|
|
19
|
+
|
|
20
|
+
// Choose whether you want to include an 'Areas' token when referring to areas.
|
|
21
|
+
// e.g. Assume the Area is called Blog and the Controller is Post:
|
|
22
|
+
// - When false use MVC.Blog.Post.etc...
|
|
23
|
+
// - When true use MVC.Areas.Blog.Post.etc...
|
|
24
|
+
static bool IncludeAreasToken = false;
|
|
25
|
+
|
|
26
|
+
// The folder under the project that contains the controllers
|
|
27
|
+
const string ControllersFolder = "Controllers";
|
|
28
|
+
|
|
29
|
+
// The folder under the project that contains the views
|
|
30
|
+
const string ViewsRootFolder = "Views";
|
|
31
|
+
|
|
32
|
+
// The name of the interface that all T4MVC action results will implement
|
|
33
|
+
const string ActionResultInterfaceName = "IT4MVCActionResult";
|
|
34
|
+
|
|
35
|
+
// If true, the T4MVC action result interface will be generated
|
|
36
|
+
// If false, the namespace of the interface must be referenced in the 'ReferencedNamespaces' setting
|
|
37
|
+
const bool GenerateActionResultInterface = true;
|
|
38
|
+
|
|
39
|
+
// If true, use lower case tokens in routes for the area, controller and action names
|
|
40
|
+
const bool UseLowercaseRoutes = false;
|
|
41
|
+
|
|
42
|
+
// The namespace that the links are generated in (e.g. "Links", as in Links.Content.nerd_jpg)
|
|
43
|
+
const string LinksNamespace = "Links";
|
|
44
|
+
|
|
45
|
+
// If true, links to static files include a query string containing the file's last change time. This way,
|
|
46
|
+
// when the static file changes, the link changes and guarantees that the client will re-request the resource.
|
|
47
|
+
// e.g. when true, the link looks like: "/Content/nerd.jpg?2009-09-04T12:25:48"
|
|
48
|
+
const bool AddTimestampToStaticLinks = false;
|
|
49
|
+
|
|
50
|
+
// Folders containing static files for which links are generated (e.g. Links.Scripts.Map_js)
|
|
51
|
+
readonly string[] StaticFilesFolders = new string[] {
|
|
52
|
+
"Scripts",
|
|
53
|
+
"Content",
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
// Static files to exclude from the generated links
|
|
57
|
+
readonly string[] ExcludedStaticFileExtensions = new string[] {
|
|
58
|
+
".cs"
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// If true, the template marks itself as unsaved as part of its execution.
|
|
62
|
+
// This way it will be saved and update itself next time the project is built.
|
|
63
|
+
// Basically, it keeps marking itself as unsaved to make the next build work.
|
|
64
|
+
// Note: this is certainly hacky, but is the best I could come up with so far.
|
|
65
|
+
static bool AlwaysKeepTemplateDirty = false;
|
|
66
|
+
|
|
67
|
+
// If true,the template output will be split into multiple files.
|
|
68
|
+
static bool SplitIntoMultipleFiles = true;
|
|
69
|
+
|
|
70
|
+
void RenderAdditionalCode() {
|
|
71
|
+
#>
|
|
72
|
+
static class T4MVCHelpers {
|
|
73
|
+
// You can change the ProcessVirtualPath method to modify the path that gets returned to the client.
|
|
74
|
+
// e.g. you can prepend a domain, or append a query string:
|
|
75
|
+
// return "http://localhost" + path + "?foo=bar";
|
|
76
|
+
private static string ProcessVirtualPathDefault(string virtualPath) {
|
|
77
|
+
// The path that comes in starts with ~/ and must first be made absolute
|
|
78
|
+
string path = VirtualPathUtility.ToAbsolute(virtualPath);
|
|
79
|
+
|
|
80
|
+
// Add your own modifications here before returning the path
|
|
81
|
+
return path;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Calling ProcessVirtualPath through delegate to allow it to be replaced for unit testing
|
|
85
|
+
public static Func<string, string> ProcessVirtualPath = ProcessVirtualPathDefault;
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
// Logic to determine if the app is running in production or dev environment
|
|
89
|
+
public static bool IsProduction() {
|
|
90
|
+
return (HttpContext.Current != null && !HttpContext.Current.IsDebuggingEnabled);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
<#+
|
|
95
|
+
}
|
|
96
|
+
#>
|
data/lib/T4MVC/T4MVC.tt
ADDED
|
@@ -0,0 +1,1418 @@
|
|
|
1
|
+
<#
|
|
2
|
+
/*
|
|
3
|
+
T4MVC Version 2.6.14
|
|
4
|
+
Find latest version and documentation at http://mvccontrib.codeplex.com/wikipage?title=T4MVC
|
|
5
|
+
Discuss on the T4MVC forum: http://forums.asp.net/1215.aspx
|
|
6
|
+
|
|
7
|
+
T4MVC is part of the MvcContrib project (http://mvccontrib.codeplex.com)
|
|
8
|
+
Maintained by David Ebbo, with much feedback from the MVC community (thanks all!)
|
|
9
|
+
david.ebbo@microsoft.com
|
|
10
|
+
http://twitter.com/davidebbo
|
|
11
|
+
http://blogs.msdn.com/davidebb
|
|
12
|
+
|
|
13
|
+
Related blog posts: http://blogs.msdn.com/davidebb/archive/tags/T4MVC/default.aspx
|
|
14
|
+
|
|
15
|
+
Please use in accordance to the MvcContrib license (http://mvccontrib.codeplex.com/license)
|
|
16
|
+
*/
|
|
17
|
+
#>
|
|
18
|
+
<#@ template language="C#v3.5" debug="true" hostspecific="true" #>
|
|
19
|
+
<#@ assembly name="System.Core" #>
|
|
20
|
+
<#@ assembly name="Microsoft.VisualStudio.Shell.Interop.8.0" #>
|
|
21
|
+
<#@ assembly name="EnvDTE" #>
|
|
22
|
+
<#@ assembly name="EnvDTE80" #>
|
|
23
|
+
<#@ assembly name="VSLangProj" #>
|
|
24
|
+
<#@ import namespace="System.Collections.Generic" #>
|
|
25
|
+
<#@ import namespace="System.IO" #>
|
|
26
|
+
<#@ import namespace="System.Linq" #>
|
|
27
|
+
<#@ import namespace="System.Text" #>
|
|
28
|
+
<#@ import namespace="System.Text.RegularExpressions" #>
|
|
29
|
+
<#@ import namespace="Microsoft.VisualStudio.Shell.Interop" #>
|
|
30
|
+
<#@ import namespace="EnvDTE" #>
|
|
31
|
+
<#@ import namespace="EnvDTE80" #>
|
|
32
|
+
<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #>
|
|
33
|
+
<#PrepareDataToRender(this); #>
|
|
34
|
+
<#var manager = Manager.Create(Host, GenerationEnvironment); #>
|
|
35
|
+
<#manager.StartHeader(); #>// <auto-generated />
|
|
36
|
+
// This file was generated by a T4 template.
|
|
37
|
+
// Don't change it directly as your change would get overwritten. Instead, make changes
|
|
38
|
+
// to the .tt file (i.e. the T4 template) and save it to regenerate this file.
|
|
39
|
+
|
|
40
|
+
// Make sure the compiler doesn't complain about missing Xml comments
|
|
41
|
+
#pragma warning disable 1591
|
|
42
|
+
#region T4MVC
|
|
43
|
+
|
|
44
|
+
using System;
|
|
45
|
+
using System.Diagnostics;
|
|
46
|
+
using System.CodeDom.Compiler;
|
|
47
|
+
using System.Collections.Generic;
|
|
48
|
+
using System.Runtime.CompilerServices;
|
|
49
|
+
using System.Web;
|
|
50
|
+
using System.Web.Hosting;
|
|
51
|
+
using System.Web.Mvc;
|
|
52
|
+
using System.Web.Mvc.Ajax;
|
|
53
|
+
using System.Web.Mvc.Html;
|
|
54
|
+
using System.Web.Routing;
|
|
55
|
+
using <#=T4MVCNamespace #>;
|
|
56
|
+
<#foreach (var referencedNamespace in ReferencedNamespaces) { #>
|
|
57
|
+
using <#=referencedNamespace #>;
|
|
58
|
+
<#} #>
|
|
59
|
+
<#manager.EndBlock(); #>
|
|
60
|
+
|
|
61
|
+
[<#= GeneratedCode #>, DebuggerNonUserCode]
|
|
62
|
+
public static class <#=HelpersPrefix #> {
|
|
63
|
+
<#if (IncludeAreasToken) { #>
|
|
64
|
+
public static class Areas {
|
|
65
|
+
<#} #>
|
|
66
|
+
<#foreach (var area in Areas.Where(a => !string.IsNullOrEmpty(a.Name))) { #>
|
|
67
|
+
static readonly <#=area.Name #>Class s_<#=area.Name #> = new <#=area.Name #>Class();
|
|
68
|
+
public static <#=area.Name #>Class <#=EscapeID(area.Namespace) #> { get { return s_<#=area.Name #>; } }
|
|
69
|
+
<#} #>
|
|
70
|
+
<#if (IncludeAreasToken) { #>
|
|
71
|
+
}
|
|
72
|
+
<#} #>
|
|
73
|
+
<#foreach (var controller in DefaultArea.GetControllers()) { #>
|
|
74
|
+
public static <#=controller.FullClassName #> <#=controller.Name #> = new <#=controller.FullDerivedClassName #>();
|
|
75
|
+
<#} #>
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
namespace <#=T4MVCNamespace #> {
|
|
79
|
+
<#foreach (var area in Areas.Where(a => !string.IsNullOrEmpty(a.Name))) { #>
|
|
80
|
+
[<#= GeneratedCode #>, DebuggerNonUserCode]
|
|
81
|
+
public class <#=area.Name #>Class {
|
|
82
|
+
public readonly string Name = "<#=ProcessAreaOrControllerName(area.Name) #>";
|
|
83
|
+
<#foreach (var controller in area.GetControllers()) { #>
|
|
84
|
+
public <#=controller.FullClassName #> <#=controller.Name #> = new <#=controller.FullDerivedClassName #>();
|
|
85
|
+
<#} #>
|
|
86
|
+
}
|
|
87
|
+
<#} #>
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
namespace System.Web.Mvc {
|
|
91
|
+
[<#= GeneratedCode #>, DebuggerNonUserCode]
|
|
92
|
+
public static class T4Extensions {
|
|
93
|
+
public static <#=HtmlStringType #> ActionLink(this HtmlHelper htmlHelper, string linkText, ActionResult result) {
|
|
94
|
+
return htmlHelper.RouteLink(linkText, result.GetRouteValueDictionary());
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
public static <#=HtmlStringType #> ActionLink(this HtmlHelper htmlHelper, string linkText, ActionResult result, object htmlAttributes) {
|
|
98
|
+
return ActionLink(htmlHelper, linkText, result, new RouteValueDictionary(htmlAttributes));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
public static <#=HtmlStringType #> ActionLink(this HtmlHelper htmlHelper, string linkText, ActionResult result, IDictionary<string, object> htmlAttributes) {
|
|
102
|
+
return htmlHelper.RouteLink(linkText, result.GetRouteValueDictionary(), htmlAttributes);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
public static MvcForm BeginForm(this HtmlHelper htmlHelper, ActionResult result, FormMethod formMethod) {
|
|
106
|
+
return htmlHelper.BeginForm(result, formMethod, null);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
public static MvcForm BeginForm(this HtmlHelper htmlHelper, ActionResult result, FormMethod formMethod, object htmlAttributes) {
|
|
110
|
+
return BeginForm(htmlHelper, result, formMethod, new RouteValueDictionary(htmlAttributes));
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
public static MvcForm BeginForm(this HtmlHelper htmlHelper, ActionResult result, FormMethod formMethod, IDictionary<string, object> htmlAttributes) {
|
|
114
|
+
var callInfo = result.GetT4MVCResult();
|
|
115
|
+
return htmlHelper.BeginForm(callInfo.Action, callInfo.Controller, callInfo.RouteValueDictionary, formMethod, htmlAttributes);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
<#if (MvcVersion >= 2) {#>
|
|
119
|
+
public static void RenderAction(this HtmlHelper htmlHelper, ActionResult result) {
|
|
120
|
+
var callInfo = result.GetT4MVCResult();
|
|
121
|
+
htmlHelper.RenderAction(callInfo.Action, callInfo.Controller, callInfo.RouteValueDictionary);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
public static MvcHtmlString Action(this HtmlHelper htmlHelper, ActionResult result) {
|
|
125
|
+
var callInfo = result.GetT4MVCResult();
|
|
126
|
+
return htmlHelper.Action(callInfo.Action, callInfo.Controller, callInfo.RouteValueDictionary);
|
|
127
|
+
}
|
|
128
|
+
<#} #>
|
|
129
|
+
public static string Action(this UrlHelper urlHelper, ActionResult result) {
|
|
130
|
+
return urlHelper.RouteUrl(result.GetRouteValueDictionary());
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
public static string ActionAbsolute(this UrlHelper urlHelper, ActionResult result) {
|
|
134
|
+
return string.Format("{0}{1}",urlHelper.RequestContext.HttpContext.Request.Url.GetLeftPart(UriPartial.Authority),
|
|
135
|
+
urlHelper.RouteUrl(result.GetRouteValueDictionary()));
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
public static <#=HtmlStringType #> ActionLink(this AjaxHelper ajaxHelper, string linkText, ActionResult result, AjaxOptions ajaxOptions) {
|
|
139
|
+
return ajaxHelper.RouteLink(linkText, result.GetRouteValueDictionary(), ajaxOptions);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
public static <#=HtmlStringType #> ActionLink(this AjaxHelper ajaxHelper, string linkText, ActionResult result, AjaxOptions ajaxOptions, object htmlAttributes) {
|
|
143
|
+
return ajaxHelper.RouteLink(linkText, result.GetRouteValueDictionary(), ajaxOptions, new RouteValueDictionary(htmlAttributes));
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
public static <#=HtmlStringType #> ActionLink(this AjaxHelper ajaxHelper, string linkText, ActionResult result, AjaxOptions ajaxOptions, IDictionary<string, object> htmlAttributes) {
|
|
147
|
+
return ajaxHelper.RouteLink(linkText, result.GetRouteValueDictionary(), ajaxOptions, htmlAttributes);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
public static Route MapRoute(this RouteCollection routes, string name, string url, ActionResult result) {
|
|
151
|
+
return routes.MapRoute(name, url, result, (ActionResult)null);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
public static Route MapRoute(this RouteCollection routes, string name, string url, ActionResult result, object defaults) {
|
|
155
|
+
return MapRoute(routes, name, url, result, defaults, null);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
public static Route MapRoute(this RouteCollection routes, string name, string url, ActionResult result, object defaults, object constraints) {
|
|
159
|
+
// Start by adding the default values from the anonymous object (if any)
|
|
160
|
+
var routeValues = new RouteValueDictionary(defaults);
|
|
161
|
+
|
|
162
|
+
// Then add the Controller/Action names and the parameters from the call
|
|
163
|
+
foreach (var pair in result.GetRouteValueDictionary()) {
|
|
164
|
+
routeValues.Add(pair.Key, pair.Value);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
var routeConstraints = new RouteValueDictionary(constraints);
|
|
168
|
+
|
|
169
|
+
// Create and add the route
|
|
170
|
+
var route = new Route(url, routeValues, routeConstraints, new MvcRouteHandler());
|
|
171
|
+
routes.Add(name, route);
|
|
172
|
+
return route;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
public static <#=ActionResultInterfaceName #> GetT4MVCResult(this ActionResult result) {
|
|
176
|
+
var t4MVCResult = result as <#=ActionResultInterfaceName #>;
|
|
177
|
+
if (t4MVCResult == null) {
|
|
178
|
+
throw new InvalidOperationException("T4MVC methods can only be passed pseudo-action calls (e.g. MVC.Home.About()), and not real action calls.");
|
|
179
|
+
}
|
|
180
|
+
return t4MVCResult;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
public static RouteValueDictionary GetRouteValueDictionary(this ActionResult result) {
|
|
184
|
+
return result.GetT4MVCResult().RouteValueDictionary;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
public static ActionResult AddRouteValues(this ActionResult result, object routeValues) {
|
|
188
|
+
return result.AddRouteValues(new RouteValueDictionary(routeValues));
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
public static ActionResult AddRouteValues(this ActionResult result, RouteValueDictionary routeValues) {
|
|
192
|
+
RouteValueDictionary currentRouteValues = result.GetRouteValueDictionary();
|
|
193
|
+
|
|
194
|
+
// Add all the extra values
|
|
195
|
+
foreach (var pair in routeValues) {
|
|
196
|
+
currentRouteValues.Add(pair.Key, pair.Value);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return result;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
public static ActionResult AddRouteValues(this ActionResult result, System.Collections.Specialized.NameValueCollection nameValueCollection) {
|
|
203
|
+
// Copy all the values from the NameValueCollection into the route dictionary
|
|
204
|
+
nameValueCollection.CopyTo(result.GetRouteValueDictionary());
|
|
205
|
+
return result;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
public static ActionResult AddRouteValue(this ActionResult result, string name, object value) {
|
|
209
|
+
RouteValueDictionary routeValues = result.GetRouteValueDictionary();
|
|
210
|
+
routeValues.Add(name, value);
|
|
211
|
+
return result;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
public static void InitMVCT4Result(this <#=ActionResultInterfaceName #> result, string area, string controller, string action) {
|
|
215
|
+
result.Controller = controller;
|
|
216
|
+
result.Action = action;
|
|
217
|
+
result.RouteValueDictionary = new RouteValueDictionary();
|
|
218
|
+
<# if (Areas.Count > 1) { #>result.RouteValueDictionary.Add("Area", area ?? "");<# } #>
|
|
219
|
+
result.RouteValueDictionary.Add("Controller", controller);
|
|
220
|
+
result.RouteValueDictionary.Add("Action", action);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
public static bool FileExists(string virtualPath) {
|
|
224
|
+
if (!HostingEnvironment.IsHosted) return false;
|
|
225
|
+
string filePath = HostingEnvironment.MapPath(virtualPath);
|
|
226
|
+
return System.IO.File.Exists(filePath);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
static DateTime CenturyBegin=new DateTime(2001,1,1);
|
|
230
|
+
public static string TimestampString(string virtualPath) {
|
|
231
|
+
if (!HostingEnvironment.IsHosted) return string.Empty;
|
|
232
|
+
string filePath = HostingEnvironment.MapPath(virtualPath);
|
|
233
|
+
return Convert.ToString((System.IO.File.GetLastWriteTimeUtc(filePath).Ticks-CenturyBegin.Ticks)/1000000000,16);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
<#if (GenerateActionResultInterface) { #>
|
|
239
|
+
[<#= GeneratedCode #>]
|
|
240
|
+
public interface <#=ActionResultInterfaceName #> {
|
|
241
|
+
string Action { get; set; }
|
|
242
|
+
string Controller { get; set; }
|
|
243
|
+
RouteValueDictionary RouteValueDictionary { get; set; }
|
|
244
|
+
}
|
|
245
|
+
<#} #>
|
|
246
|
+
|
|
247
|
+
<#foreach (var resultType in ResultTypes.Values) { #>
|
|
248
|
+
[<#= GeneratedCode #>, DebuggerNonUserCode]
|
|
249
|
+
public class T4MVC_<#=resultType.Name #> : <#=resultType.FullName #>, <#=ActionResultInterfaceName #> {
|
|
250
|
+
public T4MVC_<#=resultType.Name #>(string area, string controller, string action): base(<#resultType.Constructor.WriteNonEmptyParameterValues(true); #>) {
|
|
251
|
+
this.InitMVCT4Result(area, controller, action);
|
|
252
|
+
}
|
|
253
|
+
<#foreach (var method in resultType.AbstractMethods) { #>
|
|
254
|
+
<#=method.IsPublic ? "public" : "protected" #> override void <#=method.Name #>(<#method.WriteFormalParameters(true); #>) { }
|
|
255
|
+
<#} #>
|
|
256
|
+
|
|
257
|
+
public string Controller { get; set; }
|
|
258
|
+
public string Action { get; set; }
|
|
259
|
+
public RouteValueDictionary RouteValueDictionary { get; set; }
|
|
260
|
+
}
|
|
261
|
+
<#} #>
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
namespace <#=LinksNamespace #> {
|
|
266
|
+
<#
|
|
267
|
+
foreach (string folder in StaticFilesFolders) {
|
|
268
|
+
ProcessStaticFiles(Project, folder);
|
|
269
|
+
}
|
|
270
|
+
#>
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
<#
|
|
274
|
+
RenderAdditionalCode();
|
|
275
|
+
#>
|
|
276
|
+
<#foreach (var controller in GetAbstractControllers().Where(c => !c.HasDefaultConstructor)) { #>
|
|
277
|
+
<#manager.StartNewFile(controller.GeneratedFileName); #>
|
|
278
|
+
namespace <#=controller.Namespace #> {
|
|
279
|
+
public partial class <#=controller.ClassName #> {
|
|
280
|
+
protected <#=controller.ClassName #>() { }
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
<#manager.EndBlock(); #>
|
|
284
|
+
<#} #>
|
|
285
|
+
|
|
286
|
+
<#foreach (var controller in GetControllers()) { #>
|
|
287
|
+
<#
|
|
288
|
+
// Don't generate the file at all if the existing one is up to date
|
|
289
|
+
if (controller.GeneratedCodeIsUpToDate) {
|
|
290
|
+
manager.KeepGeneratedFile(controller.GeneratedFileName);
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
#>
|
|
294
|
+
<#manager.StartNewFile(controller.GeneratedFileName); #>
|
|
295
|
+
<#if (!String.IsNullOrEmpty(controller.Namespace)) { #>
|
|
296
|
+
namespace <#=controller.Namespace #> {
|
|
297
|
+
<#} #>
|
|
298
|
+
public <#if (!controller.NotRealController) { #>partial <#} #>class <#=controller.ClassName #> {
|
|
299
|
+
<#if (!controller.NotRealController) { #>
|
|
300
|
+
<#if (!controller.HasExplicitConstructor) { #>
|
|
301
|
+
[<#= GeneratedCode #>, DebuggerNonUserCode]
|
|
302
|
+
public <#=controller.ClassName #>() { }
|
|
303
|
+
|
|
304
|
+
<#} #>
|
|
305
|
+
[<#= GeneratedCode #>, DebuggerNonUserCode]
|
|
306
|
+
protected <#=controller.ClassName #>(Dummy d) { }
|
|
307
|
+
|
|
308
|
+
[<#= GeneratedCode #>, DebuggerNonUserCode]
|
|
309
|
+
protected RedirectToRouteResult RedirectToAction(ActionResult result) {
|
|
310
|
+
var callInfo = result.GetT4MVCResult();
|
|
311
|
+
return RedirectToRoute(callInfo.RouteValueDictionary);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
<#foreach (var method in controller.ActionMethodsUniqueWithoutParameterlessOverload) { #>
|
|
315
|
+
[NonAction]
|
|
316
|
+
[<#= GeneratedCode #>, DebuggerNonUserCode]
|
|
317
|
+
public <#=method.ReturnTypeFullName #> <#=method.Name #>() {
|
|
318
|
+
return new T4MVC_<#=method.ReturnType #>(Area, Name, ActionNames.<#=method.ActionName #>);
|
|
319
|
+
}
|
|
320
|
+
<#} #>
|
|
321
|
+
|
|
322
|
+
[<#= GeneratedCode #>, DebuggerNonUserCode]
|
|
323
|
+
public <#=controller.ClassName #> Actions { get { return <#=controller.T4MVCControllerFullName #>; } }
|
|
324
|
+
[<#= GeneratedCode #>]
|
|
325
|
+
public readonly string Area = "<#=ProcessAreaOrControllerName(controller.AreaName) #>";
|
|
326
|
+
[<#= GeneratedCode #>]
|
|
327
|
+
public readonly string Name = "<#=ProcessAreaOrControllerName(controller.Name) #>";
|
|
328
|
+
|
|
329
|
+
static readonly ActionNamesClass s_actions = new ActionNamesClass();
|
|
330
|
+
[<#= GeneratedCode #>, DebuggerNonUserCode]
|
|
331
|
+
public ActionNamesClass ActionNames { get { return s_actions; } }
|
|
332
|
+
[<#= GeneratedCode #>, DebuggerNonUserCode]
|
|
333
|
+
public class ActionNamesClass {
|
|
334
|
+
<#foreach (var method in controller.ActionMethodsWithUniqueNames) { #>
|
|
335
|
+
<# if (UseLowercaseRoutes) { #>
|
|
336
|
+
public readonly string <#=method.ActionName #> = (<#=method.ActionNameValueExpression #>).ToLowerInvariant();
|
|
337
|
+
<# } else { #>
|
|
338
|
+
public readonly string <#=method.ActionName #> = <#=method.ActionNameValueExpression #>;
|
|
339
|
+
<# }
|
|
340
|
+
} #>
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
<#} #>
|
|
344
|
+
|
|
345
|
+
static readonly ViewNames s_views = new ViewNames();
|
|
346
|
+
[<#= GeneratedCode #>, DebuggerNonUserCode]
|
|
347
|
+
public ViewNames Views { get { return s_views; } }
|
|
348
|
+
[<#= GeneratedCode #>, DebuggerNonUserCode]
|
|
349
|
+
public class ViewNames {
|
|
350
|
+
<#RenderControllerViews(controller);#>
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
<#if (!controller.NotRealController) { #>
|
|
355
|
+
[<#= GeneratedCode #>, DebuggerNonUserCode]
|
|
356
|
+
public class <#=controller.DerivedClassName #>: <#=controller.FullClassName #> {
|
|
357
|
+
public <#=controller.DerivedClassName #>() : base(Dummy.Instance) { }
|
|
358
|
+
|
|
359
|
+
<#foreach (var method in controller.ActionMethods) { #>
|
|
360
|
+
public override <#=method.ReturnTypeFullName #> <#=method.Name #>(<#method.WriteFormalParameters(true); #>) {
|
|
361
|
+
var callInfo = new T4MVC_<#=method.ReturnType #>(Area, Name, ActionNames.<#=method.ActionName #>);
|
|
362
|
+
<#if (method.Parameters.Count > 0) { #>
|
|
363
|
+
<#foreach (var p in method.Parameters) { #>
|
|
364
|
+
callInfo.RouteValueDictionary.Add(<#=p.RouteNameExpression #>, <#=p.Name #>);
|
|
365
|
+
<#} #>
|
|
366
|
+
<#}#>
|
|
367
|
+
return callInfo;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
<#} #>
|
|
371
|
+
}
|
|
372
|
+
<#} #>
|
|
373
|
+
<#if (!String.IsNullOrEmpty(controller.Namespace)) { #>
|
|
374
|
+
}
|
|
375
|
+
<#} #>
|
|
376
|
+
|
|
377
|
+
<#manager.EndBlock(); #>
|
|
378
|
+
<#} #>
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
namespace <#=T4MVCNamespace #> {
|
|
382
|
+
[<#= GeneratedCode #>, DebuggerNonUserCode]
|
|
383
|
+
public class Dummy {
|
|
384
|
+
private Dummy() { }
|
|
385
|
+
public static Dummy Instance = new Dummy();
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
<#manager.StartFooter(); #>
|
|
390
|
+
#endregion T4MVC
|
|
391
|
+
#pragma warning restore 1591
|
|
392
|
+
<#manager.EndBlock(); #>
|
|
393
|
+
<#manager.Process(SplitIntoMultipleFiles); #>
|
|
394
|
+
|
|
395
|
+
<#@ Include File="T4MVC.settings.t4" #>
|
|
396
|
+
|
|
397
|
+
<#+
|
|
398
|
+
const string T4MVCNamespace = "T4MVC";
|
|
399
|
+
const string ControllerSuffix = "Controller";
|
|
400
|
+
|
|
401
|
+
static DTE Dte;
|
|
402
|
+
static Project Project;
|
|
403
|
+
static string AppRoot;
|
|
404
|
+
static HashSet<AreaInfo> Areas;
|
|
405
|
+
static AreaInfo DefaultArea;
|
|
406
|
+
static Dictionary<string, ResultTypeInfo> ResultTypes;
|
|
407
|
+
static TextTransformation TT;
|
|
408
|
+
static string T4FileName;
|
|
409
|
+
static string T4Folder;
|
|
410
|
+
static string GeneratedCode = @"GeneratedCode(""T4MVC"", ""2.0"")";
|
|
411
|
+
static float MvcVersion;
|
|
412
|
+
static string HtmlStringType;
|
|
413
|
+
static Microsoft.CSharp.CSharpCodeProvider codeProvider = new Microsoft.CSharp.CSharpCodeProvider();
|
|
414
|
+
|
|
415
|
+
IEnumerable<ControllerInfo> GetControllers() {
|
|
416
|
+
var controllers = new List<ControllerInfo>();
|
|
417
|
+
|
|
418
|
+
foreach (var area in Areas) {
|
|
419
|
+
controllers.AddRange(area.GetControllers());
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
return controllers;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
IEnumerable<ControllerInfo> GetAbstractControllers() {
|
|
426
|
+
var controllers = new List<ControllerInfo>();
|
|
427
|
+
|
|
428
|
+
foreach (var area in Areas) {
|
|
429
|
+
controllers.AddRange(area.GetAbstractControllers());
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
return controllers;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
void PrepareDataToRender(TextTransformation tt) {
|
|
436
|
+
TT = tt;
|
|
437
|
+
T4FileName = Path.GetFileName(Host.TemplateFile);
|
|
438
|
+
T4Folder = Path.GetDirectoryName(Host.TemplateFile);
|
|
439
|
+
Areas = new HashSet<AreaInfo>();
|
|
440
|
+
ResultTypes = new Dictionary<string, ResultTypeInfo>();
|
|
441
|
+
|
|
442
|
+
// Get the DTE service from the host
|
|
443
|
+
var serviceProvider = Host as IServiceProvider;
|
|
444
|
+
if (serviceProvider != null) {
|
|
445
|
+
Dte = serviceProvider.GetService(typeof(SDTE)) as DTE;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
// Fail if we couldn't get the DTE. This can happen when trying to run in TextTransform.exe
|
|
449
|
+
if (Dte == null) {
|
|
450
|
+
throw new Exception("T4MVC can only execute through the Visual Studio host");
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
Project = GetProjectContainingT4File(Dte);
|
|
454
|
+
|
|
455
|
+
if (Project == null) {
|
|
456
|
+
Error("Could not find the VS Project containing the T4 file.");
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
// Get the path of the root folder of the app
|
|
461
|
+
AppRoot = Path.GetDirectoryName(Project.FullName) + '\\';
|
|
462
|
+
|
|
463
|
+
MvcVersion = GetMvcVersion();
|
|
464
|
+
|
|
465
|
+
// Use the proper return type of render helpers
|
|
466
|
+
HtmlStringType = MvcVersion < 2 ? "string" : "MvcHtmlString";
|
|
467
|
+
|
|
468
|
+
ProcessAreas(Project);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
float GetMvcVersion() {
|
|
472
|
+
var vsProject = (VSLangProj.VSProject)Project.Object;
|
|
473
|
+
|
|
474
|
+
foreach (VSLangProj.Reference r in vsProject.References) {
|
|
475
|
+
if (r.Name.Equals("System.Web.Mvc", StringComparison.OrdinalIgnoreCase)) {
|
|
476
|
+
return r.MajorVersion + (r.MinorVersion / 10);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
// We should never get here, but default to v1 just in case
|
|
481
|
+
return 1;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
Project GetProjectContainingT4File(DTE dte) {
|
|
485
|
+
|
|
486
|
+
// Find the .tt file's ProjectItem
|
|
487
|
+
ProjectItem projectItem = dte.Solution.FindProjectItem(Host.TemplateFile);
|
|
488
|
+
|
|
489
|
+
// If the .tt file is not opened, open it
|
|
490
|
+
if (projectItem.Document == null)
|
|
491
|
+
projectItem.Open(Constants.vsViewKindCode);
|
|
492
|
+
|
|
493
|
+
if (AlwaysKeepTemplateDirty) {
|
|
494
|
+
// Mark the .tt file as unsaved. This way it will be saved and update itself next time the
|
|
495
|
+
// project is built. Basically, it keeps marking itself as unsaved to make the next build work.
|
|
496
|
+
// Note: this is certainly hacky, but is the best I could come up with so far.
|
|
497
|
+
projectItem.Document.Saved = false;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
return projectItem.ContainingProject;
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
void ProcessAreas(Project project) {
|
|
504
|
+
// Process the default area
|
|
505
|
+
ProcessArea(project.ProjectItems, null);
|
|
506
|
+
|
|
507
|
+
// Get the Areas folder
|
|
508
|
+
ProjectItem areaProjectItem = GetProjectItem(project, AreasFolder);
|
|
509
|
+
if (areaProjectItem == null)
|
|
510
|
+
return;
|
|
511
|
+
|
|
512
|
+
foreach (ProjectItem item in areaProjectItem.ProjectItems) {
|
|
513
|
+
if (IsFolder(item)) {
|
|
514
|
+
ProcessArea(item.ProjectItems, item.Name);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
void ProcessArea(ProjectItems areaFolderItems, string name) {
|
|
520
|
+
var area = new AreaInfo() { Name = name };
|
|
521
|
+
ProcessAreaControllers(areaFolderItems, area);
|
|
522
|
+
ProcessAreaViews(areaFolderItems, area);
|
|
523
|
+
Areas.Add(area);
|
|
524
|
+
|
|
525
|
+
if (String.IsNullOrEmpty(name))
|
|
526
|
+
DefaultArea = area;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
void ProcessAreaControllers(ProjectItems areaFolderItems, AreaInfo area) {
|
|
530
|
+
// Get area Controllers folder
|
|
531
|
+
ProjectItem controllerProjectItem = GetProjectItem(areaFolderItems, ControllersFolder);
|
|
532
|
+
if (controllerProjectItem == null)
|
|
533
|
+
return;
|
|
534
|
+
|
|
535
|
+
ProcessControllersRecursive(controllerProjectItem, area);
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
void ProcessAreaViews(ProjectItems areaFolderItems, AreaInfo area) {
|
|
539
|
+
// Get area Views folder
|
|
540
|
+
ProjectItem viewsProjectItem = GetProjectItem(areaFolderItems, ViewsRootFolder);
|
|
541
|
+
if (viewsProjectItem == null)
|
|
542
|
+
return;
|
|
543
|
+
|
|
544
|
+
ProcessAllViews(viewsProjectItem, area);
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
void ProcessControllersRecursive(ProjectItem projectItem, AreaInfo area) {
|
|
548
|
+
|
|
549
|
+
// Recurse into all the sub-items (both files and folder can have some - e.g. .tt files)
|
|
550
|
+
foreach (ProjectItem item in projectItem.ProjectItems) {
|
|
551
|
+
ProcessControllersRecursive(item, area);
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
if (projectItem.FileCodeModel != null) {
|
|
555
|
+
DateTime controllerLastWriteTime = File.GetLastWriteTime(projectItem.get_FileNames(0));
|
|
556
|
+
foreach (var type in projectItem.FileCodeModel.CodeElements.OfType<CodeClass2>()) {
|
|
557
|
+
ProcessControllerType(type, area, controllerLastWriteTime);
|
|
558
|
+
}
|
|
559
|
+
// Process all the elements that are namespaces
|
|
560
|
+
foreach (var ns in projectItem.FileCodeModel.CodeElements.OfType<CodeNamespace>()) {
|
|
561
|
+
foreach (var type in ns.Members.OfType<CodeClass2>()) {
|
|
562
|
+
ProcessControllerType(type, area, controllerLastWriteTime);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
void ProcessControllerType(CodeClass2 type, AreaInfo area, DateTime controllerLastWriteTime) {
|
|
569
|
+
// Only process types that end with Controller
|
|
570
|
+
// REVIEW: this check is not super reliable. Should look at base class.
|
|
571
|
+
if (!type.Name.EndsWith(ControllerSuffix, StringComparison.OrdinalIgnoreCase))
|
|
572
|
+
return;
|
|
573
|
+
|
|
574
|
+
// Don't process generic classes (their concrete derived classes will be processed)
|
|
575
|
+
if (type.IsGeneric)
|
|
576
|
+
return;
|
|
577
|
+
|
|
578
|
+
// Make sure the class is partial
|
|
579
|
+
if (type.ClassKind != vsCMClassKind.vsCMClassKindPartialClass) {
|
|
580
|
+
try {
|
|
581
|
+
type.ClassKind = vsCMClassKind.vsCMClassKindPartialClass;
|
|
582
|
+
}
|
|
583
|
+
catch {
|
|
584
|
+
// If we couldn't make it partial, give a warning and skip it
|
|
585
|
+
Warning(String.Format("{0} was not able to make the class {1} partial. Please change it manually if possible", T4FileName, type.Name));
|
|
586
|
+
return;
|
|
587
|
+
}
|
|
588
|
+
Warning(String.Format("{0} changed the class {1} to be partial", T4FileName, type.Name));
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
// Collect misc info about the controller class and add it to the collection
|
|
592
|
+
var controllerInfo = new ControllerInfo {
|
|
593
|
+
Area = area,
|
|
594
|
+
Namespace = type.Namespace != null ? type.Namespace.Name : String.Empty,
|
|
595
|
+
ClassName = type.Name
|
|
596
|
+
};
|
|
597
|
+
|
|
598
|
+
// Check if the controller has changed since the generated file was last created
|
|
599
|
+
DateTime lastGenerationTime = File.GetLastWriteTime(controllerInfo.GeneratedFileFullPath);
|
|
600
|
+
if (lastGenerationTime > controllerLastWriteTime) {
|
|
601
|
+
controllerInfo.GeneratedCodeIsUpToDate = true;
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
// Either process new ControllerInfo or integrate results into existing object for partially defined controllers
|
|
605
|
+
var target = area.Controllers.Add(controllerInfo) ? controllerInfo : area.Controllers.First(c => c.Equals(controllerInfo));
|
|
606
|
+
target.HasExplicitConstructor |= HasExplicitConstructor(type);
|
|
607
|
+
target.HasExplicitDefaultConstructor |= HasExplicitDefaultConstructor(type);
|
|
608
|
+
|
|
609
|
+
if (type.IsAbstract) {
|
|
610
|
+
// If it's abstract, set a flag and don't process action methods (derived classes will)
|
|
611
|
+
target.IsAbstract = true;
|
|
612
|
+
}
|
|
613
|
+
else {
|
|
614
|
+
// Process all the action methods in the controller
|
|
615
|
+
ProcessControllerActionMethods(target, type);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
void ProcessControllerActionMethods(ControllerInfo controllerInfo, CodeClass2 current) {
|
|
620
|
+
|
|
621
|
+
// We want to process not just the controller class itself, but also its parents, as they
|
|
622
|
+
// may themselves define actions
|
|
623
|
+
for (CodeClass2 type = current; type != null && type.FullName != "System.Web.Mvc.Controller"; type = (CodeClass2)type.Bases.Item(1)) {
|
|
624
|
+
|
|
625
|
+
// If the type doesn't come from this project, some actions on it will fail. Try to get a real project type if possible.
|
|
626
|
+
if (type.InfoLocation != vsCMInfoLocation.vsCMInfoLocationProject) {
|
|
627
|
+
// Go through all the projects in the solution
|
|
628
|
+
//foreach (Project prj in Dte.Solution.Projects) {
|
|
629
|
+
for (int i = 1; i <= Dte.Solution.Projects.Count; i++) {
|
|
630
|
+
Project prj = null;
|
|
631
|
+
try {
|
|
632
|
+
prj = Dte.Solution.Projects.Item(i);
|
|
633
|
+
}
|
|
634
|
+
catch (System.Runtime.Serialization.SerializationException) {
|
|
635
|
+
// Some project types (that we don't care about) cause a strange exception, so ingore it
|
|
636
|
+
continue;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
// Skip it if it's the current project or doesn't have a code model
|
|
640
|
+
if (prj == Project || prj.CodeModel == null)
|
|
641
|
+
continue;
|
|
642
|
+
|
|
643
|
+
// If we can get a local project type, use it instead of the original
|
|
644
|
+
var codeType = prj.CodeModel.CodeTypeFromFullName(type.FullName);
|
|
645
|
+
if (codeType != null && codeType.InfoLocation == vsCMInfoLocation.vsCMInfoLocationProject) {
|
|
646
|
+
type = (CodeClass2)codeType;
|
|
647
|
+
break;
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
foreach (CodeFunction2 method in GetMethods(type)) {
|
|
653
|
+
// Ignore non-public methods
|
|
654
|
+
if (method.Access != vsCMAccess.vsCMAccessPublic)
|
|
655
|
+
continue;
|
|
656
|
+
|
|
657
|
+
// Ignore methods that are marked as not being actions
|
|
658
|
+
if (GetAttribute(method.Attributes, "System.Web.Mvc.NonActionAttribute") != null)
|
|
659
|
+
continue;
|
|
660
|
+
|
|
661
|
+
// This takes care of avoiding generic types which cause method.Type.CodeType to blow up
|
|
662
|
+
if (method.Type.TypeKind != vsCMTypeRef.vsCMTypeRefCodeType)
|
|
663
|
+
continue;
|
|
664
|
+
|
|
665
|
+
// We only support action methods that return an ActionResult derived type
|
|
666
|
+
if (!method.Type.CodeType.get_IsDerivedFrom("System.Web.Mvc.ActionResult")) {
|
|
667
|
+
Warning(String.Format("{0} doesn't support {1}.{2} because it doesn't return a supported ActionResult type", T4FileName, type.Name, method.Name));
|
|
668
|
+
continue;
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
// If we haven't yet seen this return type, keep track of it
|
|
672
|
+
if (!ResultTypes.ContainsKey(method.Type.CodeType.Name)) {
|
|
673
|
+
var resTypeInfo = new ResultTypeInfo(method.Type.CodeType);
|
|
674
|
+
|
|
675
|
+
ResultTypes[method.Type.CodeType.Name] = resTypeInfo;
|
|
676
|
+
}
|
|
677
|
+
|
|
678
|
+
// Make sure the method is virtual
|
|
679
|
+
if (!method.CanOverride && method.OverrideKind != vsCMOverrideKind.vsCMOverrideKindOverride) {
|
|
680
|
+
try {
|
|
681
|
+
method.CanOverride = true;
|
|
682
|
+
}
|
|
683
|
+
catch {
|
|
684
|
+
// If we couldn't make it virtual, give a warning and skip it
|
|
685
|
+
Warning(String.Format("{0} was not able to make the action method {1}.{2} virtual. Please change it manually if possible", T4FileName, type.Name, method.Name));
|
|
686
|
+
continue;
|
|
687
|
+
}
|
|
688
|
+
Warning(String.Format("{0} changed the action method {1}.{2} to be virtual", T4FileName, type.Name, method.Name));
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
// Collect misc info about the action method and add it to the collection
|
|
692
|
+
controllerInfo.ActionMethods.Add(new ActionMethodInfo(method));
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
void ProcessAllViews(ProjectItem viewsProjectItem, AreaInfo area) {
|
|
698
|
+
// Go through all the sub-folders in the Views folder
|
|
699
|
+
foreach (ProjectItem item in viewsProjectItem.ProjectItems) {
|
|
700
|
+
|
|
701
|
+
// We only care about sub-folders, not files
|
|
702
|
+
if (!IsFolder(item))
|
|
703
|
+
continue;
|
|
704
|
+
|
|
705
|
+
// Find the controller for this view folder
|
|
706
|
+
ControllerInfo controller = area.Controllers.SingleOrDefault(c => c.Name.Equals(item.Name, StringComparison.OrdinalIgnoreCase));
|
|
707
|
+
|
|
708
|
+
if (controller == null) {
|
|
709
|
+
// If it doesn't match a controller, treat as a pseudo-controller for consistency
|
|
710
|
+
controller = new ControllerInfo {
|
|
711
|
+
Area = area,
|
|
712
|
+
NotRealController = true,
|
|
713
|
+
Namespace = MakeClassName(T4MVCNamespace, area.Name),
|
|
714
|
+
ClassName = item.Name + ControllerSuffix
|
|
715
|
+
};
|
|
716
|
+
area.Controllers.Add(controller);
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
AddViewsRecursive(item.ProjectItems, controller.ViewsFolder);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
void AddViewsRecursive(ProjectItems items, ViewsFolderInfo viewsFolder) {
|
|
724
|
+
// Go through all the files in the subfolder to get the view names
|
|
725
|
+
foreach (ProjectItem item in items) {
|
|
726
|
+
if (item.Kind == Constants.vsProjectItemKindPhysicalFile) {
|
|
727
|
+
if (Path.GetExtension(item.Name).Equals(".master", StringComparison.OrdinalIgnoreCase))
|
|
728
|
+
continue; // ignore master files
|
|
729
|
+
viewsFolder.AddView(item);
|
|
730
|
+
}
|
|
731
|
+
else if (item.Kind == Constants.vsProjectItemKindPhysicalFolder) {
|
|
732
|
+
string folderName = Path.GetFileName(item.Name);
|
|
733
|
+
if (folderName.Equals("App_LocalResources", StringComparison.OrdinalIgnoreCase))
|
|
734
|
+
continue;
|
|
735
|
+
var subViewFolder = new ViewsFolderInfo() { Name = folderName };
|
|
736
|
+
viewsFolder.SubFolders.Add(subViewFolder);
|
|
737
|
+
AddViewsRecursive(item.ProjectItems, subViewFolder);
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
void RenderControllerViews(ControllerInfo controller) {
|
|
743
|
+
PushIndent(" ");
|
|
744
|
+
RenderViewsRecursive(controller.ViewsFolder, controller);
|
|
745
|
+
PopIndent();
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
void RenderViewsRecursive(ViewsFolderInfo viewsFolder, ControllerInfo controller) {
|
|
749
|
+
|
|
750
|
+
// For each view, generate a readonly string
|
|
751
|
+
foreach (var viewPair in viewsFolder.Views) {
|
|
752
|
+
WriteLine("public readonly string " + EscapeID(Sanitize(viewPair.Key)) + " = \"" + viewPair.Value + "\";");
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
// For each sub folder, generate a class and recurse
|
|
756
|
+
foreach (var subFolder in viewsFolder.SubFolders) {
|
|
757
|
+
string newClassName = Sanitize(subFolder.Name);#>
|
|
758
|
+
static readonly _<#=newClassName#> s_<#=newClassName#> = new _<#=newClassName#>();
|
|
759
|
+
public _<#=newClassName#> <#=EscapeID(newClassName)#> { get { return s_<#=newClassName#>; } }
|
|
760
|
+
public partial class _<#=newClassName#>{
|
|
761
|
+
<#+
|
|
762
|
+
PushIndent(" ");
|
|
763
|
+
RenderViewsRecursive(subFolder, controller);
|
|
764
|
+
PopIndent();
|
|
765
|
+
|
|
766
|
+
WriteLine("}");
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
|
|
770
|
+
void ProcessStaticFiles(Project project, string folder) {
|
|
771
|
+
|
|
772
|
+
ProjectItem folderProjectItem = GetProjectItem(project, folder);
|
|
773
|
+
if (folderProjectItem != null) {
|
|
774
|
+
ProcessStaticFilesRecursive(folderProjectItem, "~");
|
|
775
|
+
}
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
void ProcessStaticFilesRecursive(ProjectItem projectItem, string path) {
|
|
779
|
+
|
|
780
|
+
if (IsFolder(projectItem)) { #>
|
|
781
|
+
[<#= GeneratedCode #>, DebuggerNonUserCode]
|
|
782
|
+
public static class <#=EscapeID(Sanitize(projectItem.Name)) #> {
|
|
783
|
+
private const string URLPATH = "<#=path#>/<#=projectItem.Name#>";
|
|
784
|
+
public static string Url() { return T4MVCHelpers.ProcessVirtualPath(URLPATH); }
|
|
785
|
+
public static string Url(string fileName) { return T4MVCHelpers.ProcessVirtualPath(URLPATH + "/" + fileName); }
|
|
786
|
+
<#+
|
|
787
|
+
PushIndent(" ");
|
|
788
|
+
|
|
789
|
+
// Recurse into all the items in the folder
|
|
790
|
+
foreach (ProjectItem item in projectItem.ProjectItems) {
|
|
791
|
+
ProcessStaticFilesRecursive(item, path + "/" + projectItem.Name);
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
PopIndent();
|
|
795
|
+
#>
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
<#+
|
|
799
|
+
}
|
|
800
|
+
else { #>
|
|
801
|
+
<#+
|
|
802
|
+
if (!ExcludedStaticFileExtensions.Any(extension => projectItem.Name.EndsWith(extension, StringComparison.OrdinalIgnoreCase))) {
|
|
803
|
+
// if it's a non-minified javascript file
|
|
804
|
+
if (projectItem.Name.EndsWith(".js") && !projectItem.Name.EndsWith(".min.js")) {
|
|
805
|
+
if (AddTimestampToStaticLinks) { #>
|
|
806
|
+
public static readonly string <#=Sanitize(projectItem.Name)#> = T4MVCHelpers.IsProduction() && T4Extensions.FileExists(URLPATH + "/<#=projectItem.Name.Replace(".js", ".min.js")#>") ? Url("<#=projectItem.Name.Replace(".js", ".min.js")#>")+"?"+T4Extensions.TimestampString(URLPATH + "/<#=projectItem.Name#>") : Url("<#=projectItem.Name#>")+"?"+T4Extensions.TimestampString(URLPATH + "/<#=projectItem.Name#>");
|
|
807
|
+
<#+} else {#>
|
|
808
|
+
public static readonly string <#=Sanitize(projectItem.Name)#> = T4MVCHelpers.IsProduction() && T4Extensions.FileExists(URLPATH + "/<#=projectItem.Name.Replace(".js", ".min.js")#>") ? Url("<#=projectItem.Name.Replace(".js", ".min.js")#>") : Url("<#=projectItem.Name#>");
|
|
809
|
+
<#+} #>
|
|
810
|
+
<#+}
|
|
811
|
+
else if (AddTimestampToStaticLinks) { #>
|
|
812
|
+
public static readonly string <#=Sanitize(projectItem.Name)#> = Url("<#=projectItem.Name#>")+"?"+T4Extensions.TimestampString(URLPATH + "/<#=projectItem.Name#>");
|
|
813
|
+
<#+}
|
|
814
|
+
else { #>
|
|
815
|
+
public static readonly string <#=Sanitize(projectItem.Name)#> = Url("<#=projectItem.Name#>");
|
|
816
|
+
<#+}
|
|
817
|
+
} #>
|
|
818
|
+
<#+
|
|
819
|
+
// Non folder items may also have children (virtual folders, Class.cs -> Class.Designer.cs, template output)
|
|
820
|
+
// Just register them on the same path as their parent item
|
|
821
|
+
foreach (ProjectItem item in projectItem.ProjectItems) {
|
|
822
|
+
ProcessStaticFilesRecursive(item, path);
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
ProjectItem GetProjectItem(Project project, string name) {
|
|
827
|
+
return GetProjectItem(project.ProjectItems, name);
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
ProjectItem GetProjectItem(ProjectItems items, string subPath) {
|
|
831
|
+
|
|
832
|
+
ProjectItem current = null;
|
|
833
|
+
foreach (string name in subPath.Split('\\')) {
|
|
834
|
+
try {
|
|
835
|
+
// ProjectItems.Item() throws when it doesn't exist, so catch the exception
|
|
836
|
+
// to return null instead.
|
|
837
|
+
current = items.Item(name);
|
|
838
|
+
}
|
|
839
|
+
catch {
|
|
840
|
+
// If any chunk couldn't be found, fail
|
|
841
|
+
return null;
|
|
842
|
+
}
|
|
843
|
+
items = current.ProjectItems;
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
return current;
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
static string GetVirtualPath(ProjectItem item) {
|
|
850
|
+
string fileFullPath = item.get_FileNames(0);
|
|
851
|
+
if (!fileFullPath.StartsWith(AppRoot, StringComparison.OrdinalIgnoreCase))
|
|
852
|
+
throw new Exception(string.Format("File {0} is not under app root {1}. Please report issue.", fileFullPath, AppRoot));
|
|
853
|
+
|
|
854
|
+
// Make a virtual path from the physical path
|
|
855
|
+
return "~/" + fileFullPath.Substring(AppRoot.Length).Replace('\\', '/');
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
static string ProcessAreaOrControllerName(string name) {
|
|
859
|
+
return UseLowercaseRoutes ? name.ToLowerInvariant() : name;
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
// Return all the CodeFunction2 in the CodeElements collection
|
|
863
|
+
static IEnumerable<CodeFunction2> GetMethods(CodeClass2 codeClass) {
|
|
864
|
+
// Only look at regular method (e.g. ignore things like contructors)
|
|
865
|
+
return codeClass.Members.OfType<CodeFunction2>()
|
|
866
|
+
.Where(f => f.FunctionKind == vsCMFunction.vsCMFunctionFunction);
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
// Check if the class has any explicit constructor
|
|
870
|
+
static bool HasExplicitConstructor(CodeClass2 codeClass) {
|
|
871
|
+
return codeClass.Members.OfType<CodeFunction2>().Any(
|
|
872
|
+
f => f.FunctionKind == vsCMFunction.vsCMFunctionConstructor);
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
// Check if the class has a default (i.e. no params) constructor
|
|
876
|
+
static bool HasExplicitDefaultConstructor(CodeClass2 codeClass) {
|
|
877
|
+
return codeClass.Members.OfType<CodeFunction2>().Any(
|
|
878
|
+
f => f.FunctionKind == vsCMFunction.vsCMFunctionConstructor && f.Parameters.Count == 0);
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
// Find a method with a given name
|
|
882
|
+
static CodeFunction2 GetMethod(CodeClass2 codeClass, string name) {
|
|
883
|
+
return GetMethods(codeClass).FirstOrDefault(f => f.Name == name);
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
// Find an attribute of a given type on an attribute collection
|
|
887
|
+
static CodeAttribute2 GetAttribute(CodeElements attributes, string attributeType) {
|
|
888
|
+
for (int i = 1; i <= attributes.Count; i++) {
|
|
889
|
+
var attrib = (CodeAttribute2)attributes.Item(i);
|
|
890
|
+
if (attrib.FullName == attributeType) {
|
|
891
|
+
return attrib;
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
return null;
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
// Return whether a ProjectItem is a folder and not a file
|
|
898
|
+
static bool IsFolder(ProjectItem item) {
|
|
899
|
+
return (item.Kind == Constants.vsProjectItemKindPhysicalFolder);
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
static string MakeClassName(string ns, string classname) {
|
|
903
|
+
return String.IsNullOrEmpty(ns) ? classname :
|
|
904
|
+
String.IsNullOrEmpty(classname) ? ns : ns + "." + codeProvider.CreateEscapedIdentifier(classname);
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
static string Sanitize(string token) {
|
|
908
|
+
// Replace all invalid chars by underscores
|
|
909
|
+
token = Regex.Replace(token, @"[\W\b]", "_", RegexOptions.IgnoreCase);
|
|
910
|
+
|
|
911
|
+
// If it starts with a digit, prefix it with an underscore
|
|
912
|
+
token = Regex.Replace(token, @"^\d", @"_$0");
|
|
913
|
+
|
|
914
|
+
// Check for reserved words
|
|
915
|
+
// TODO: Clean this up and add other reserved words (keywords, etc)
|
|
916
|
+
if (token == "Url") token = "_Url";
|
|
917
|
+
|
|
918
|
+
return token;
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
static string EscapeID(string id) {
|
|
922
|
+
return codeProvider.CreateEscapedIdentifier(id);
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
// Data structure to collect data about an area
|
|
926
|
+
class AreaInfo {
|
|
927
|
+
public AreaInfo() {
|
|
928
|
+
Controllers = new HashSet<ControllerInfo>();
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
public string Name { get; set; }
|
|
932
|
+
public HashSet<ControllerInfo> Controllers { get; set; }
|
|
933
|
+
|
|
934
|
+
public string Namespace {
|
|
935
|
+
get {
|
|
936
|
+
// When *not* using an 'Areas' token, we need to disambiguate conflicts
|
|
937
|
+
// between Area names and controller names (from the default Area)
|
|
938
|
+
if (!IncludeAreasToken && DefaultArea.Controllers.Any(c => c.Name == Name))
|
|
939
|
+
return Name + "Area";
|
|
940
|
+
|
|
941
|
+
return Name;
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
public IEnumerable<ControllerInfo> GetControllers() {
|
|
946
|
+
return Controllers.Where(c => !c.IsAbstract);
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
public IEnumerable<ControllerInfo> GetAbstractControllers() {
|
|
950
|
+
return Controllers.Where(c => c.IsAbstract);
|
|
951
|
+
}
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
// Data structure to collect data about a controller class
|
|
955
|
+
class ControllerInfo {
|
|
956
|
+
public ControllerInfo() {
|
|
957
|
+
ActionMethods = new HashSet<ActionMethodInfo>();
|
|
958
|
+
ViewsFolder = new ViewsFolderInfo();
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
public AreaInfo Area { get; set; }
|
|
962
|
+
|
|
963
|
+
public string AreaName {
|
|
964
|
+
get { return Area.Name ?? ""; }
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
public string T4MVCControllerFullName {
|
|
968
|
+
get {
|
|
969
|
+
string name = HelpersPrefix;
|
|
970
|
+
if (!String.IsNullOrEmpty(AreaName))
|
|
971
|
+
name += "." + EscapeID(Area.Namespace);
|
|
972
|
+
return name + "." + Name; ;
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
public string ViewPath {
|
|
977
|
+
get {
|
|
978
|
+
if (string.IsNullOrEmpty(Area.Name))
|
|
979
|
+
return String.Format("~/{0}/{1}/", ViewsRootFolder, Name);
|
|
980
|
+
else
|
|
981
|
+
return String.Format("~/{0}/{1}/{2}/", AreasFolder, ViewsRootFolder, Name);
|
|
982
|
+
}
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
// True when this is not a real controller, but a placeholder for views folders that don't match a controller
|
|
986
|
+
public bool NotRealController { get; set; }
|
|
987
|
+
|
|
988
|
+
public bool HasExplicitConstructor { get; set; }
|
|
989
|
+
public bool HasExplicitDefaultConstructor { get; set; }
|
|
990
|
+
public bool HasDefaultConstructor { get { return !HasExplicitConstructor || HasExplicitDefaultConstructor; } }
|
|
991
|
+
public bool IsAbstract { get; set; }
|
|
992
|
+
|
|
993
|
+
public bool GeneratedCodeIsUpToDate { get; set; }
|
|
994
|
+
|
|
995
|
+
public string ClassName { get; set; }
|
|
996
|
+
public string Name {
|
|
997
|
+
get {
|
|
998
|
+
// Trim the Controller suffix
|
|
999
|
+
return ClassName.Substring(0, ClassName.Length - ControllerSuffix.Length);
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
|
|
1003
|
+
public string Namespace { get; set; }
|
|
1004
|
+
|
|
1005
|
+
public string FullClassName {
|
|
1006
|
+
get {
|
|
1007
|
+
return MakeClassName(Namespace, ClassName);
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
1010
|
+
|
|
1011
|
+
public string DerivedClassName {
|
|
1012
|
+
get {
|
|
1013
|
+
return "T4MVC_" + ClassName;
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
public string FullDerivedClassName {
|
|
1018
|
+
get {
|
|
1019
|
+
if (NotRealController)
|
|
1020
|
+
return FullClassName;
|
|
1021
|
+
return MakeClassName(Namespace, DerivedClassName);
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
public string GeneratedFileName {
|
|
1026
|
+
get {
|
|
1027
|
+
return MakeClassName(AreaName, ClassName + ".generated.cs");
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
|
|
1031
|
+
public string GeneratedFileFullPath {
|
|
1032
|
+
get {
|
|
1033
|
+
return Path.Combine(T4Folder, GeneratedFileName);
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
public HashSet<ActionMethodInfo> ActionMethods { get; set; }
|
|
1038
|
+
|
|
1039
|
+
IEnumerable<ActionMethodInfo> ActionMethodsWithNoParameters {
|
|
1040
|
+
get {
|
|
1041
|
+
return ActionMethods.Where(m => m.Parameters.Count == 0);
|
|
1042
|
+
}
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
public IEnumerable<ActionMethodInfo> ActionMethodsUniqueWithoutParameterlessOverload {
|
|
1046
|
+
get {
|
|
1047
|
+
return ActionMethodsWithUniqueNames.Except(ActionMethodsWithNoParameters, new ActionComparer());
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
|
|
1051
|
+
// Return a list of actions without duplicate names (even with multiple overloads)
|
|
1052
|
+
public IEnumerable<ActionMethodInfo> ActionMethodsWithUniqueNames {
|
|
1053
|
+
get {
|
|
1054
|
+
return ActionMethods.Distinct(new ActionComparer());
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
class ActionComparer : IEqualityComparer<ActionMethodInfo> {
|
|
1059
|
+
public bool Equals(ActionMethodInfo x, ActionMethodInfo y) {
|
|
1060
|
+
return x.ActionName == y.ActionName;
|
|
1061
|
+
}
|
|
1062
|
+
|
|
1063
|
+
public int GetHashCode(ActionMethodInfo obj) {
|
|
1064
|
+
return obj.ActionName.GetHashCode();
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
public ViewsFolderInfo ViewsFolder { get; private set; }
|
|
1069
|
+
|
|
1070
|
+
public override string ToString() {
|
|
1071
|
+
return Name;
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
public override bool Equals(object obj) {
|
|
1075
|
+
return obj != null && FullClassName == ((ControllerInfo)obj).FullClassName;
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
public override int GetHashCode() {
|
|
1079
|
+
return FullClassName.GetHashCode();
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1083
|
+
// Info about a view folder, its views and its sub view folders
|
|
1084
|
+
class ViewsFolderInfo {
|
|
1085
|
+
public ViewsFolderInfo() {
|
|
1086
|
+
Views = new Dictionary<string, string>();
|
|
1087
|
+
SubFolders = new List<ViewsFolderInfo>();
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
public void AddView(ProjectItem item) {
|
|
1091
|
+
string viewName = Path.GetFileName(item.Name);
|
|
1092
|
+
string viewFieldName = Path.GetFileNameWithoutExtension(viewName);
|
|
1093
|
+
|
|
1094
|
+
// If the simple view name is already in use, include the extension (e.g. foo_ascx instead of just foo)
|
|
1095
|
+
if (Views.ContainsKey(viewFieldName))
|
|
1096
|
+
viewFieldName = Sanitize(viewName);
|
|
1097
|
+
|
|
1098
|
+
Views[viewFieldName] = GetVirtualPath(item);
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
public string Name { get; set; }
|
|
1102
|
+
public Dictionary<string, string> Views { get; private set; }
|
|
1103
|
+
public List<ViewsFolderInfo> SubFolders { get; set; }
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
// Data structure to collect data about a method
|
|
1107
|
+
class FunctionInfo {
|
|
1108
|
+
protected CodeFunction2 _method;
|
|
1109
|
+
private string _signature;
|
|
1110
|
+
|
|
1111
|
+
public FunctionInfo(CodeFunction2 method) {
|
|
1112
|
+
Parameters = new List<MethodParamInfo>();
|
|
1113
|
+
|
|
1114
|
+
// Can be null when an custom ActionResult has no ctor
|
|
1115
|
+
if (method == null)
|
|
1116
|
+
return;
|
|
1117
|
+
|
|
1118
|
+
_method = method;
|
|
1119
|
+
|
|
1120
|
+
// Build a unique signature for the method, used to avoid duplication
|
|
1121
|
+
_signature = method.Name;
|
|
1122
|
+
|
|
1123
|
+
// Process all the parameters
|
|
1124
|
+
foreach (var p in method.Parameters.OfType<CodeParameter2>()) {
|
|
1125
|
+
string routeNameExpression = "\"" + p.Name + "\"";
|
|
1126
|
+
|
|
1127
|
+
// If there is a [Bind(Prefix = "someName")] attribute, use it
|
|
1128
|
+
if (p.InfoLocation != vsCMInfoLocation.vsCMInfoLocationExternal) {
|
|
1129
|
+
var attrib = GetAttribute(p.Attributes, "System.Web.Mvc.BindAttribute");
|
|
1130
|
+
if (attrib != null) {
|
|
1131
|
+
var arg = attrib.Arguments.OfType<CodeAttributeArgument>().FirstOrDefault(a => a.Name == "Prefix");
|
|
1132
|
+
if (arg != null)
|
|
1133
|
+
routeNameExpression = arg.Value;
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
Parameters.Add(
|
|
1138
|
+
new MethodParamInfo() {
|
|
1139
|
+
Name = p.Name,
|
|
1140
|
+
RouteNameExpression = routeNameExpression,
|
|
1141
|
+
Type = p.Type.AsString
|
|
1142
|
+
});
|
|
1143
|
+
_signature += "," + p.Type.AsString;
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
public string Name { get { return _method.Name; } }
|
|
1148
|
+
public string ReturnType { get { return _method.Type.CodeType.Name; } }
|
|
1149
|
+
public string ReturnTypeFullName { get { return _method.Type.CodeType.FullName; } }
|
|
1150
|
+
public bool IsPublic { get { return _method.Access == vsCMAccess.vsCMAccessPublic; } }
|
|
1151
|
+
public List<MethodParamInfo> Parameters { get; private set; }
|
|
1152
|
+
|
|
1153
|
+
// Write out all the parameters as part of a method declaration
|
|
1154
|
+
public void WriteFormalParameters(bool first) {
|
|
1155
|
+
foreach (var p in Parameters) {
|
|
1156
|
+
if (first)
|
|
1157
|
+
first = false;
|
|
1158
|
+
else
|
|
1159
|
+
TT.Write(", ");
|
|
1160
|
+
|
|
1161
|
+
TT.Write(p.Type + " " + p.Name);
|
|
1162
|
+
}
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
// Pass non-empty param values to make sure the ActionResult ctors don't complain
|
|
1166
|
+
// REVIEW: this is a bit dirty
|
|
1167
|
+
public void WriteNonEmptyParameterValues(bool first) {
|
|
1168
|
+
foreach (var p in Parameters) {
|
|
1169
|
+
if (first)
|
|
1170
|
+
first = false;
|
|
1171
|
+
else
|
|
1172
|
+
TT.Write(", ");
|
|
1173
|
+
|
|
1174
|
+
switch (p.Type) {
|
|
1175
|
+
case "string":
|
|
1176
|
+
TT.Write("\" \"");
|
|
1177
|
+
break;
|
|
1178
|
+
case "byte[]":
|
|
1179
|
+
TT.Write("new byte[0]");
|
|
1180
|
+
break;
|
|
1181
|
+
default:
|
|
1182
|
+
TT.Write("default(" + p.Type + ")");
|
|
1183
|
+
break;
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
|
|
1188
|
+
public override bool Equals(object obj) {
|
|
1189
|
+
return obj != null && _signature == ((FunctionInfo)obj)._signature;
|
|
1190
|
+
}
|
|
1191
|
+
|
|
1192
|
+
public override int GetHashCode() {
|
|
1193
|
+
return _signature.GetHashCode();
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
|
|
1197
|
+
// Data structure to collect data about an action method
|
|
1198
|
+
class ActionMethodInfo : FunctionInfo {
|
|
1199
|
+
public ActionMethodInfo(CodeFunction2 method)
|
|
1200
|
+
: base(method) {
|
|
1201
|
+
// Normally, the action name is the method name. But if there is an [ActionName] on
|
|
1202
|
+
// the method, get the expression from that instead
|
|
1203
|
+
ActionNameValueExpression = '"' + Name + '"';
|
|
1204
|
+
var attrib = GetAttribute(method.Attributes, "System.Web.Mvc.ActionNameAttribute");
|
|
1205
|
+
if (attrib != null) {
|
|
1206
|
+
var arg = (CodeAttributeArgument)attrib.Arguments.Item(1);
|
|
1207
|
+
ActionNameValueExpression = arg.Value;
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
public string ActionName { get { return Name; } }
|
|
1212
|
+
public string ActionNameValueExpression { get; set; }
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
// Data about an ActionResult derived type
|
|
1216
|
+
class ResultTypeInfo {
|
|
1217
|
+
CodeType _codeType;
|
|
1218
|
+
public ResultTypeInfo(CodeType codeType) {
|
|
1219
|
+
_codeType = codeType;
|
|
1220
|
+
|
|
1221
|
+
var ctor = _codeType.Members.OfType<CodeFunction2>().FirstOrDefault(
|
|
1222
|
+
f => f.FunctionKind == vsCMFunction.vsCMFunctionConstructor);
|
|
1223
|
+
Constructor = new FunctionInfo(ctor);
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
public string Name { get { return _codeType.Name; } }
|
|
1227
|
+
public string FullName { get { return _codeType.FullName; } }
|
|
1228
|
+
public FunctionInfo Constructor { get; set; }
|
|
1229
|
+
public IEnumerable<FunctionInfo> AbstractMethods {
|
|
1230
|
+
get {
|
|
1231
|
+
return _codeType.Members.OfType<CodeFunction2>().Where(
|
|
1232
|
+
f => f.MustImplement).Select(f => new FunctionInfo(f));
|
|
1233
|
+
}
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
|
|
1237
|
+
class MethodParamInfo {
|
|
1238
|
+
public string Name { get; set; }
|
|
1239
|
+
public string RouteNameExpression { get; set; }
|
|
1240
|
+
public string Type { get; set; }
|
|
1241
|
+
}
|
|
1242
|
+
|
|
1243
|
+
|
|
1244
|
+
/*
|
|
1245
|
+
Manager.tt from Damien Guard: http://damieng.com/blog/2009/11/06/multiple-outputs-from-t4-made-easy-revisited
|
|
1246
|
+
*/
|
|
1247
|
+
|
|
1248
|
+
|
|
1249
|
+
// Manager class records the various blocks so it can split them up
|
|
1250
|
+
class Manager {
|
|
1251
|
+
private class Block {
|
|
1252
|
+
public String Name;
|
|
1253
|
+
public int Start, Length;
|
|
1254
|
+
}
|
|
1255
|
+
|
|
1256
|
+
private Block currentBlock;
|
|
1257
|
+
private List<Block> files = new List<Block>();
|
|
1258
|
+
private Block footer = new Block();
|
|
1259
|
+
private Block header = new Block();
|
|
1260
|
+
private ITextTemplatingEngineHost host;
|
|
1261
|
+
private StringBuilder template;
|
|
1262
|
+
protected List<String> generatedFileNames = new List<String>();
|
|
1263
|
+
|
|
1264
|
+
public static Manager Create(ITextTemplatingEngineHost host, StringBuilder template) {
|
|
1265
|
+
return (host is IServiceProvider) ? new VSManager(host, template) : new Manager(host, template);
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
public void KeepGeneratedFile(String name) {
|
|
1269
|
+
name = Path.Combine(Path.GetDirectoryName(host.TemplateFile), name);
|
|
1270
|
+
generatedFileNames.Add(name);
|
|
1271
|
+
}
|
|
1272
|
+
|
|
1273
|
+
public void StartNewFile(String name) {
|
|
1274
|
+
if (name == null)
|
|
1275
|
+
throw new ArgumentNullException("name");
|
|
1276
|
+
CurrentBlock = new Block { Name = name };
|
|
1277
|
+
}
|
|
1278
|
+
|
|
1279
|
+
public void StartFooter() {
|
|
1280
|
+
CurrentBlock = footer;
|
|
1281
|
+
}
|
|
1282
|
+
|
|
1283
|
+
public void StartHeader() {
|
|
1284
|
+
CurrentBlock = header;
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
public void EndBlock() {
|
|
1288
|
+
if (CurrentBlock == null)
|
|
1289
|
+
return;
|
|
1290
|
+
CurrentBlock.Length = template.Length - CurrentBlock.Start;
|
|
1291
|
+
if (CurrentBlock != header && CurrentBlock != footer)
|
|
1292
|
+
files.Add(CurrentBlock);
|
|
1293
|
+
currentBlock = null;
|
|
1294
|
+
}
|
|
1295
|
+
|
|
1296
|
+
public virtual void Process(bool split) {
|
|
1297
|
+
if (split) {
|
|
1298
|
+
EndBlock();
|
|
1299
|
+
String headerText = template.ToString(header.Start, header.Length);
|
|
1300
|
+
String footerText = template.ToString(footer.Start, footer.Length);
|
|
1301
|
+
String outputPath = Path.GetDirectoryName(host.TemplateFile);
|
|
1302
|
+
files.Reverse();
|
|
1303
|
+
foreach (Block block in files) {
|
|
1304
|
+
String fileName = Path.Combine(outputPath, block.Name);
|
|
1305
|
+
String content = headerText + template.ToString(block.Start, block.Length) + footerText;
|
|
1306
|
+
generatedFileNames.Add(fileName);
|
|
1307
|
+
CreateFile(fileName, content);
|
|
1308
|
+
template.Remove(block.Start, block.Length);
|
|
1309
|
+
}
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
|
|
1313
|
+
protected virtual void CreateFile(String fileName, String content) {
|
|
1314
|
+
if (IsFileContentDifferent(fileName, content))
|
|
1315
|
+
File.WriteAllText(fileName, content);
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
public virtual String GetCustomToolNamespace(String fileName) {
|
|
1319
|
+
return null;
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
public virtual String DefaultProjectNamespace {
|
|
1323
|
+
get { return null; }
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
protected bool IsFileContentDifferent(String fileName, String newContent) {
|
|
1327
|
+
return !(File.Exists(fileName) && File.ReadAllText(fileName) == newContent);
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1330
|
+
private Manager(ITextTemplatingEngineHost host, StringBuilder template) {
|
|
1331
|
+
this.host = host;
|
|
1332
|
+
this.template = template;
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
private Block CurrentBlock {
|
|
1336
|
+
get { return currentBlock; }
|
|
1337
|
+
set {
|
|
1338
|
+
if (CurrentBlock != null)
|
|
1339
|
+
EndBlock();
|
|
1340
|
+
if (value != null)
|
|
1341
|
+
value.Start = template.Length;
|
|
1342
|
+
currentBlock = value;
|
|
1343
|
+
}
|
|
1344
|
+
}
|
|
1345
|
+
|
|
1346
|
+
private class VSManager : Manager {
|
|
1347
|
+
private EnvDTE.ProjectItem templateProjectItem;
|
|
1348
|
+
private EnvDTE.DTE dte;
|
|
1349
|
+
private Action<String> checkOutAction;
|
|
1350
|
+
private Action<IEnumerable<String>> projectSyncAction;
|
|
1351
|
+
|
|
1352
|
+
public override String DefaultProjectNamespace {
|
|
1353
|
+
get {
|
|
1354
|
+
return templateProjectItem.ContainingProject.Properties.Item("DefaultNamespace").Value.ToString();
|
|
1355
|
+
}
|
|
1356
|
+
}
|
|
1357
|
+
|
|
1358
|
+
public override String GetCustomToolNamespace(string fileName) {
|
|
1359
|
+
return dte.Solution.FindProjectItem(fileName).Properties.Item("CustomToolNamespace").Value.ToString();
|
|
1360
|
+
}
|
|
1361
|
+
|
|
1362
|
+
public override void Process(bool split) {
|
|
1363
|
+
if (templateProjectItem.ProjectItems == null)
|
|
1364
|
+
return;
|
|
1365
|
+
base.Process(split);
|
|
1366
|
+
projectSyncAction.EndInvoke(projectSyncAction.BeginInvoke(generatedFileNames, null, null));
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1369
|
+
protected override void CreateFile(String fileName, String content) {
|
|
1370
|
+
if (IsFileContentDifferent(fileName, content)) {
|
|
1371
|
+
CheckoutFileIfRequired(fileName);
|
|
1372
|
+
File.WriteAllText(fileName, content);
|
|
1373
|
+
}
|
|
1374
|
+
}
|
|
1375
|
+
|
|
1376
|
+
internal VSManager(ITextTemplatingEngineHost host, StringBuilder template)
|
|
1377
|
+
: base(host, template) {
|
|
1378
|
+
var hostServiceProvider = (IServiceProvider)host;
|
|
1379
|
+
if (hostServiceProvider == null)
|
|
1380
|
+
throw new ArgumentNullException("Could not obtain IServiceProvider");
|
|
1381
|
+
dte = (EnvDTE.DTE)hostServiceProvider.GetService(typeof(EnvDTE.DTE));
|
|
1382
|
+
if (dte == null)
|
|
1383
|
+
throw new ArgumentNullException("Could not obtain DTE from host");
|
|
1384
|
+
templateProjectItem = dte.Solution.FindProjectItem(host.TemplateFile);
|
|
1385
|
+
checkOutAction = (String fileName) => dte.SourceControl.CheckOutItem(fileName);
|
|
1386
|
+
projectSyncAction = (IEnumerable<String> keepFileNames) => ProjectSync(templateProjectItem, keepFileNames);
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
private static void ProjectSync(EnvDTE.ProjectItem templateProjectItem, IEnumerable<String> keepFileNames) {
|
|
1390
|
+
var keepFileNameSet = new HashSet<String>(keepFileNames);
|
|
1391
|
+
var projectFiles = new Dictionary<String, EnvDTE.ProjectItem>();
|
|
1392
|
+
var originalFilePrefix = Path.GetFileNameWithoutExtension(templateProjectItem.get_FileNames(0)) + ".";
|
|
1393
|
+
foreach (EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems)
|
|
1394
|
+
projectFiles.Add(projectItem.get_FileNames(0), projectItem);
|
|
1395
|
+
|
|
1396
|
+
// Remove unused items from the project
|
|
1397
|
+
foreach (var pair in projectFiles)
|
|
1398
|
+
if (!keepFileNames.Contains(pair.Key) && !(Path.GetFileNameWithoutExtension(pair.Key) + ".").StartsWith(originalFilePrefix))
|
|
1399
|
+
pair.Value.Delete();
|
|
1400
|
+
|
|
1401
|
+
// Add missing files to the project
|
|
1402
|
+
foreach (String fileName in keepFileNameSet)
|
|
1403
|
+
if (!projectFiles.ContainsKey(fileName))
|
|
1404
|
+
templateProjectItem.ProjectItems.AddFromFile(fileName);
|
|
1405
|
+
}
|
|
1406
|
+
|
|
1407
|
+
private void CheckoutFileIfRequired(String fileName) {
|
|
1408
|
+
var sc = dte.SourceControl;
|
|
1409
|
+
if (sc != null && sc.IsItemUnderSCC(fileName) && !sc.IsItemCheckedOut(fileName))
|
|
1410
|
+
checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName, null, null));
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
}
|
|
1414
|
+
|
|
1415
|
+
/*
|
|
1416
|
+
End of Manager.tt
|
|
1417
|
+
*/
|
|
1418
|
+
#>
|