MVC 3 beta on Windows Azure

by Rok Bermež 10. November 2010 10:48
This is also valid for RC release of MVC 3. When preparing a demo for my next lecture I noticed that when using MVC3 beta, everything works correctly in development fabric, but it fails when deployed to Windows Azure. Web Role is cycling between initializing / stopping and that usually mean that not all dependencies are included with the deployed project. To solve the problem just add references to the following dlls located in C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v1.0\Assemblies: System.WebPages.dll System.Web.WebPages.Razor.dll System.Web.Helpers.dll System.Web.Razor.dll WebMatrix.Data.dll Microsoft.Web.Infrastructure.dll and make sure that all of them (including System.Web.Mvc.dll (v3.0.0.0)) are marked as Copy local = true.


.Net | ASP.NET | Azure | Web

Using MVC routing to address multi-tenant Azure applications

by Rok Bermež 11. October 2010 10:29
Currently I have a scenario where I have to have more than one site and multiple domains/subdomains in a single Windows Azure web role. For obvious reasons Windows Azure give us FQDN (like instead of IP address so we have to use CNAME to point to our instance/s. The only problem with this approach is that only domain name cannot have CNAME record. For instance is fine, but just is not since it needs specific IP address. For the time being this was solved by pointing it to some specific address which would redirect the user to www of that domain. That part was simple and straightforward, but now we need something inside our web role, that would detect requested domain and serve appropriate content. There are a couple of threads online that deal with the issue of addressing multi-tenant application in Windows Azure and most of them deal with url rewriting on the single domain. You can read more about it here and here. In my project I used MVC Areas to separate different sites so all I needed was MVC routing to use domain name from incoming request in its routing configuration. I found an excellent article on the subject here, but unfortunately it was written before MVC 2 introduced areas, so in order to use it lets add area support to it. First lets download the sample here, open and if needed convert solution and open DomainRoute.cs. We only need to add one line to the end of GetRouteData method: if (Defaults.Keys.Contains("area")) data.DataTokens.Add("area", Defaults["area"]); so that it looks like: if (DataTokens != null) { foreach (var token in DataTokens) { data.DataTokens.Add(token.Key, token.Value); } } if (Defaults.Keys.Contains("area")) data.DataTokens.Add("area", Defaults["area"]); } return data; }   And we are ready to register our areas as their own domains/subdomains public override void RegisterArea(AreaRegistrationContext context) { context.Routes.Add("subodomain_default", new DomainRoute( "", "{controller}/{action}/{id}", new { area = AreaName, controller = "Home", action = "Index", id = UrlParameter.Optional } ) { DataTokens = new RouteValueDictionary(new { Namespaces = new string[] { "MvcWebRole1.Areas.subdomain.Controllers" } }) } ); }  I strongly suggest you pass Namspaces to every route registration so you can have multiple controllers with the same name serving different tenants. Soon Ill add a DomainRouteExtension and post it here so the usage will be even simpler.


.Net | Azure | Web

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

Telerik ASP.NET AJAX Controls in MVC project

by Rok Bermež 18. August 2010 14:37
If we want to use Telerik ASP.NET AJAX controls in MVC project, we must also use either ScriptManager or RadScriptManager. But since neither works very well here is more MVC friendly solution: public class RadMvcScriptManager : RadScriptManager { static string JavaScriptBlockFormat = @"<script type=""text/javascript"">//<![CDATA[ {0}//]]></script>"; protected override void Render(HtmlTextWriter writer) { foreach (RegisteredScript script in GetRegisteredClientScriptBlocks()) { if (HttpContext.Current.Items[script.Key] == null) { HttpContext.Current.Items[script.Key] = true; if (script.ScriptType == RegisteredScriptType.ClientScriptInclude) { writer.WriteLine(String.Format(@"<script type=""text/javascript"" src=""{0}""></script>", HttpUtility.HtmlEncode(script.Url))); } } } if (HttpContext.Current.Items["AppInitialize"] == null) { Page.Items["AppInitialize"] = true; writer.WriteLine( String.Format( JavaScriptBlockFormat, @"if(typeof(Sys) != ""undefined""){ $addHandler(window, ""load"", function(){Sys.Application.initialize();}); } else { throw new Error(""Microsoft ASP.NET AJAX cannot be initialized!"")}")); } StringBuilder builder = new StringBuilder(); if (HasReflectionPermission()) { SerializeScriptsForScriptControls(Page, builder); } string scriptContent = builder.ToString(); if (!String.IsNullOrEmpty(scriptContent)) { writer.WriteLine(String.Format( JavaScriptBlockFormat, String.Format("Sys.Application.add_init(function(){{{0}}});", scriptContent))); } } internal void SerializeScriptsForScriptControls(Control control, StringBuilder builder) { if (control is IScriptControl && control.Visible) { IEnumerable<ScriptDescriptor> descriptors = ((IScriptControl)control).GetScriptDescriptors(); if (descriptors != null) { foreach (ScriptDescriptor descriptor in descriptors) { SerializeScriptControlDescriptor(descriptor, builder); } } } if (control.HasControls()) { foreach (Control child in control.Controls) { SerializeScriptsForScriptControls(child, builder); } } } internal void SerializeScriptControlDescriptor(ScriptDescriptor descriptor, StringBuilder builder) { MethodInfo getScriptInfo = descriptor.GetType().GetMethod( "GetScript", BindingFlags.Instance | BindingFlags.NonPublic); if (getScriptInfo != null) { string script = (string)getScriptInfo.Invoke(descriptor, new object[] { }); builder.AppendLine(script); } } internal static bool HasReflectionPermission() { try { new ReflectionPermission(ReflectionPermissionFlag.MemberAccess).Demand(); return true; } catch (SecurityException) { return false; } } }


.Net | c# | Web


<<  March 2018  >>

View posts in large calendar

Page List

Month List