Windows Azure Full IIS

by Rok Bermež 10. January 2011 23:00
Some time ago I wrote how to deploy multitenant application to the Cloud. The process was tricky at best. With new Windows Azure SDK 1.3 things just got a lot simpler and I absolutely love it. The feature is called Full IIS and allows your web roles to access the full range of web server features that are available in on-premise IIS installations. However if you choose to use them, there are a few differences from the classic Azure Hosted Web Core (HWC) model. First you need to tell Windows Azure SDK to use Full IIS instead of HWC and you do this by adding a valid <Sites> section to your ServiceDefinition.csdef  file.  By default Visual Studio will create HWC model definition like this:     <Sites>       <Site name="Web">         <Bindings>           <Binding name="Endpoint1" endpointName="Endpoint1" />         </Bindings>       </Site>     </Sites> You can easily customize it to define multiple web sites, or virtual apps (virtual directories are also supported now): <Sites>   <Site name="MainSite">     <VirtualApplication name="WebApp1" physicalDirectory="D:\Delo\Projects\WebApp1\" />     <Bindings>       <Binding name="HttpIn" endpointName="HttpIn" />     </Bindings>   </Site>   <Site name="AnotherSiteOrSubDomain" physicalDirectory="D:\Delo\Projects\ AnotherSiteOrSubDomain ">     <Bindings>       <Binding hostHeader="" name="HttpIn" endpointName="HttpIn"/>     </Bindings>   </Site> </Sites> Things are much more similar to on-premises application then in HWC model. While RoleEntryPoint  runs under different process (WaIISHost.exe) than your web roles  (w3wp.exe), OnStart method still gets called but configuration settings work a bit differently. You cannot register or store some static values to be available to all websites. Remember its running in a different process... so you wont be able to access its data. What I mean by this is, probably everyone dealing with Azure Development has something similar to this in their role onstart method: CloudStorageAccount.SetConfigurationSettingPublisher((configName, configSetter) =>{     configSetter(RoleEnvironment.GetConfigurationSettingValue(configName)); }); While code is still perfectly sound, it wont do any good to our web roles, so the proper place to register it would by global.asax on ApplicationStart event. It all kind of makes sense, since different websites need different resources anyway.


.Net | c# | Azure

MultipleGenericBindingGenerator for Ninject.Extensions.Conventions

by Rok Bermež 10. January 2011 17:55
Ninject.Extensions.Conventions provides convention based binding for Ninject modeled after the StructureMap 2.5 AssemblyScanner by Jeremy Miller. When StructureMap users can use something like: Scan(scanner => { scanner.AssembliesFromApplicationBaseDirectory(assembly => assembly.FullName.StartsWith("Ntk.Infrastructure.")); scanner.ConnectImplementationsToTypesClosing(typeof (IMessageHandler <,>)); scanner.ConnectImplementationsToTypesClosing(typeof (IMessageHandler <>)); }); Ninject.Extensions.Conventions using GenericBindingGenerator can not: kernel.Scan(scanner => { scanner.FromAssembliesMatching( "Ntk.Infrastructure.*.dll" ); scanner.BindWith(new GenericBindingGenerator(typeof(IMessageHandler<>))); scanner.BindWith(new GenericBindingGenerator(typeof(IMessageHandler<,>))); scanner.InTransientScope(); }); So slightly modified version of GenericBindingGenerator called MultipleGenericBindingGenerator comes to the rescue: kernel.Scan(scanner => { scanner.FromAssembliesMatching("Ntk.Infrastructure.*.dll"); scanner.BindWith(new MultipleGenericBindingGenerator(typeof(IMessageHandler<>),typeof(IMessageHandler<,>))); scanner.InTransientScope(); }); If anyone needs anything like this, here is the code: using System; using System.Collections.Generic; using System.Linq; using System.Web; using Ninject; using Ninject.Activation; using Ninject.Extensions.Conventions; namespace TestProj{ public class MultipleGenericBindingGenerator : IBindingGenerator { private static readonly Type TypeOfObject = typeof (object); private readonly Type[] _contractTypes; /// <summary> /// Initializes a new instance of the <see cref="MultipleGenericBindingGenerator"/> class. /// </summary> /// <param name="contractTypes">Types of the contract.</param> public MultipleGenericBindingGenerator(params Type[] contractTypes) { foreach (var type in contractTypes) { if (!(type.IsGenericType || type.ContainsGenericParameters)) { throw new ArgumentException(String.Format("The contract must be an open generic type ({0}).",type.Name), "contractTypes"); } } _contractTypes = contractTypes; } #region Implementation of IBindingGenerator /// <summary> /// Processes the specified type creating kernel bindings. /// </summary> /// <param name="type">The type to process.</param> /// <param name="scopeCallback">the scope callback.</param> /// <param name="kernel">The kernel to configure.</param> public void Process( Type type, Func<IContext, object> scopeCallback, IKernel kernel ) { Type interfaceType = ResolveClosingInterface( type ); if ( interfaceType != null ) { kernel.Bind( interfaceType ).To( type ).InScope( scopeCallback ); } } #endregion /// <summary> /// Resolves the closing interface. /// </summary> /// <param name="targetType">Type of the target.</param> /// <returns></returns> public Type ResolveClosingInterface( Type targetType ) { if ( targetType.IsInterface || targetType.IsAbstract ) { return null; } do { Type[] interfaces = targetType.GetInterfaces(); foreach ( Type @interface in interfaces ) { if ( !@interface.IsGenericType ) { continue; } if (_contractTypes.Contains(@interface.GetGenericTypeDefinition())) { return @interface; } } targetType = targetType.BaseType; } while ( targetType != TypeOfObject ); return null; } } }


.Net | c# | ASP.NET | mvc | Web

T4MVC templates for strongly typed ASP.MVC

by Rok Bermež 10. January 2011 12:19
T4 templates for strongly typed ASP.MVC   MVC is a software pattern, that has been first introduced 1979 by Norwegian scientist Trygve Reenskaug.  The idea was to decouple the tight knot between views and models, to have a much more control over the software. For example, very known ASP.NET 2.0 technology had the implementation of views, but controllers and models were combined in the code behind, which has the impact on the testing and other features, which is needed to build a easy proficient sustainable web solution. Year ago Microsoft has launched a framework ASP.NET MVC for supporting software pattern and add additional value with different view engines , such as Razor, to eliminate this requirement. Since then, developers are having  few consideration about choosing between ASP.NET WebForms and ASP.NET MVC, but that is topic for another blog post. MVC grew very quickly and alot of developers are using the new .NET framework to write efficient, light weight, powerfull web apps. Even though we do have a great enviroment for writing, testing, debugging  .NET apps, there is still a lack of string and mis-machted typos. Consider following example: <%:Html.ActionLink(»My link«,«Indeks«,«Home«) %> This is a link to the Home controller, with a method Indeks. But wait, there is no indeks method there. It is a typo. Since we forgot to write x, instead of ks, we got a runtime error. We have to run the site, click of the link, read the error message, ask ourself, what did we do, use the debugger, run the site, check again, go through bunch of step, just because we made a typo. This is the reason, why expert developers, such as david Ebbo, created a helper (T4 templates), that goes through the code and created a strongly typed strings for controllers, views, even a content. Fixed upper example: <%:Html.ActionLink(»My link«, MVC.Home.Index)%> Its so easy. No more runtime checking, no repro bugs, even intellisense helps us understand, which name and even parameters we will use.  You can use the following strongly typed helpers in the whole app, not only the views ( also in controllers, etc.) It is quite simple to use it: 1.       Download the zip file on the codeplex site 2.       Required watching the David Ebbo intro with examples 3.       Unzip the file 4.       Add the 2 files in the root of your MVC app ( and T4MVC.setting.t4) 5.       Build it 6.       Use it J You can change the setting for t4 in the settings file to bend it to you will J Happy no-typo coding.


.Net | c# | ASP.NET | Web | mvc

RadEditor MVC Helper Sample

by Rok Bermež 8. September 2010 15:09
I was asked for RadEditor MVC helper, so here it goes (copy paste code out) : public static MvcHtmlString RadEditorFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) where TModel : class { return RadEditorFor(htmlHelper, expression, ((IDictionary<string, object>)null)); } public static MvcHtmlString RadEditorFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes) where TModel : class { return RadEditorFor(htmlHelper, expression, new RouteValueDictionary(htmlAttributes)); } public static MvcHtmlString RadEditorFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes) where TModel : class { string name = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(ExpressionHelper.GetExpressionText((LambdaExpression)expression)); TProperty value = ExpressionHelper2.GetValue(htmlHelper, expression); return RadEditor(htmlHelper, name, value, htmlAttributes); } public static MvcHtmlString RadEditor(this HtmlHelper htmlHelper, string name) { return RadEditor(htmlHelper, name, null); } public static MvcHtmlString RadEditor(this HtmlHelper htmlHelper, string name, object value) { return RadEditor(htmlHelper, name, null, ((IDictionary<string, object>)null)); } public static MvcHtmlString RadEditor(this HtmlHelper htmlHelper, string name, object value, object htmlAttributes) { return RadEditor(htmlHelper, name, value, new RouteValueDictionary(htmlAttributes)); } public static MvcHtmlString RadEditor(this HtmlHelper htmlHelper, string name, object value, IDictionary<string, object> htmlAttributes) { if (String.IsNullOrEmpty(name)) { name = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name); if (string.IsNullOrEmpty(name)) { throw new ArgumentException("name"); } } if (htmlAttributes == null) htmlAttributes = new Dictionary<string, object>(); Page page = new Page(); RadMvcScriptManager mvcScriptManager = new RadMvcScriptManager(); mvcScriptManager.EnableViewState = false; page.Controls.Add(mvcScriptManager); RadStyleSheetManager radStyleSheetManager = new RadStyleSheetManager(); page.Controls.Add(radStyleSheetManager); //string id = name.Replace(".", "_"); RadEditor radEditor = new RadEditor(); radEditor.ID = name + "_radeditor"; radEditor.ClientIDMode = ClientIDMode.Static; radEditor.ImageManager.ContentProviderTypeName = typeof(AzureStorageFileBrowserContentProvider).AssemblyQualifiedName; radEditor.ImageManager.MaxUploadFileSize = 3000000; radEditor.ImageManager.ViewPaths = new string[] { "uploaded/images" }; radEditor.ImageManager.UploadPaths = new string[] { "uploaded/images" }; radEditor.ImageManager.DeletePaths = new string[] { "uploaded/images" }; radEditor.DocumentManager.ContentProviderTypeName = typeof(AzureStorageFileBrowserContentProvider).AssemblyQualifiedName; radEditor.DocumentManager.MaxUploadFileSize = 20000000; radEditor.DocumentManager.ViewPaths = new string[] { "uploaded/documents" }; radEditor.DocumentManager.UploadPaths = new string[] { "uploaded/documents" }; radEditor.DocumentManager.DeletePaths = new string[] { "uploaded/documents" }; radEditor.MediaManager.ContentProviderTypeName = typeof(AzureStorageFileBrowserContentProvider).AssemblyQualifiedName; radEditor.MediaManager.MaxUploadFileSize = 50000000; radEditor.MediaManager.ViewPaths = new string[] { "uploaded/media" }; radEditor.MediaManager.UploadPaths = new string[] { "uploaded/media" }; radEditor.MediaManager.DeletePaths = new string[] { "uploaded/media" }; radEditor.FlashManager.ContentProviderTypeName = typeof(AzureStorageFileBrowserContentProvider).AssemblyQualifiedName; radEditor.FlashManager.MaxUploadFileSize = 50000000; radEditor.FlashManager.ViewPaths = new string[] { "uploaded/flash" }; radEditor.FlashManager.UploadPaths = new string[] { "uploaded/flash" }; radEditor.FlashManager.DeletePaths = new string[] { "uploaded/flash" }; //radEditor.TemplateManager.ContentProviderTypeName = typeof(AzureStorageFileBrowserContentProvider).AssemblyQualifiedName; radEditor.TemplateManager.MaxUploadFileSize = 500000; radEditor.TemplateManager.ViewPaths = new string[] { "~/content/templates" }; radEditor.NewLineBr = false; radEditor.Skin = "Vista"; //radEditor.ToolsFile = "~/Content/administracija/EditorToolbar.xml"; if (htmlAttributes.ContainsKey("ToolsFile")) radEditor.ToolsFile = htmlAttributes["ToolsFile"] as string; UIHintControlParameterDataAnnotationsModelMetadata mmd = (UIHintControlParameterDataAnnotationsModelMetadata)htmlHelper.ViewData.ModelMetadata; if (mmd.TemplateControlParameterExist("ToolBar")) { radEditor.ToolsFile = mmd.GetTemplateControlParameter<string>("ToolBar"); } if (mmd.TemplateControlParameterExist("DisableHtmlFormating") && mmd.GetTemplateControlParameter<bool>("DisableHtmlFormating")) { radEditor.StripFormattingOptions = EditorStripFormattingOptions.None; radEditor.DisableFilter(Telerik.Web.UI.EditorFilters.ConvertToXhtml); } if (value != null) radEditor.Content = value as string; radEditor.DialogHandlerUrl = "/Telerik.Web.UI.DialogHandler.axd"; page.Controls.Add(radEditor); StringWriter output = new StringWriter(); HttpContext.Current.Server.Execute(page, output, false); return MvcHtmlString.Create(htmlHelper.Hidden("", "ToBeReplaced").ToString() + output.ToString()); }


.Net | c# | Web

Telerik ASP.NET AJAX Controls in MVC project Part ||

by Rok Bermež 3. September 2010 15:09
Telerik Reporting used in ASP.NET MVC [More]


.Net | c# | ASP.NET | Web


<<  January 2018  >>

View posts in large calendar

Page List

Month List