Blog

Categorised by 'ASP.NET'.

  • ReactJSI've been meddling around with ReactJS over the last week or so, seeing if this is something viable to use for future client projects. I am always constantly on the lookout to whether there are better alternatives on how my fellow developers and I develop our sites.

    Throughout the sample applications I've been building, I constantly asked myself one question: Why Would I Use ReactJS In My Day To Day Development? I am ASP.NET developer who build websites either using Web Forms or MVC Razor. So I am finding it difficult to comprehend whether using ReactJS is viable in these frameworks, especially MVC.

    ReactJS is primarily a view framework where you have the ability to write component-based web applications directly into your JavaScript that then gets output to the DOM virtually - making for a very fast and responsive webpage. It's a different approach to developing websites that I quite like. But for the moment, I just don't see how it can benefit me when the full MVC framework does a pretty good job with all the bells and whistles.

    For example, I segregate all my key HTML markup into partial views in order to increase re-use throughout my web application, which works really well when making AJAX calls where the markup needs to be displayed on the page asynchronously as well as server-side. I can just see by implementing ReactJS, I will be duplicating this process at JavaScript and CSHTML level if a markup change ever needed to be made. If partial views does the job effectively, I'm not too sure the need for ReactJS in my future ASP.NET MVC creations.

    Don't get me wrong - I really like ReactJS. It makes writing JavaScript an even more enjoyable experience purely due to the JSX syntax. Long gone are the days where you have to concatenate strings to form HTML. More importantly, it's readable and truly scalable.

    Unfortunately, it doesn't look like ReactJS is a viable option for me at this moment in time. I can see how it would be a very useful framework for building web applications where there is a requirement for the view to be created strictly client-side along with heavy use of AJAX calls from an API layer to serve data to your application. But in situations where you have two frameworks that provide the ability to create views, in this case ReactJS and ASP.NET MVC, it doesn't make sense.

    I could be talking absolute nonsense and missing the whole point. If this is the case (most likely!), please leave a comment.

  • I've just completed working on a site that required PayPal integration to carry out credit card payments, using PayPal's REST API interface. I did find some aspects of the implementing PayPal's REST API a little confusing and there seemed to be a blurred line on what is the best approach. This is probably due to the vast number of .NET examples provided in PayPal's own Github repository.

    I decided to create my own PayPal REST API .NET Starter kit, by combining my own efforts together with PayPal documentation and code examples from other developers online. Feel free to fork it from my Bitbucket repository: https://bitbucket.org/SurinderBhomra/paypal-.net-starter-kit.

    The PayPal REST API .NET Starter kit contains everything you need to make a start in making your first card payment. It encompasses a very basic form to enter test transactions, as well as the following Nuget package references:

    • log4net
    • Newtonsoft.Json
    • PayPalCoreSDK
    • RestApiSDK

    All you'll need to do is create is a PayPal Client ID and Secret, build the solution and away you go. Every time you make a transaction, a "PaypalPayment" object is returned, containing useful information to be used at application level if the payment was a success and if not, the full error information.

    A successful transaction will generate the following invoice to the user's PayPal account:

    PayPal Invoice Sample

    I am using my PayPal Starter kit as a foundation to build upon if I ever get the opportunity to develop more features, such as refunds.

    Feel free to modify my code and (even better!) add more features.

  • Web Configuration Snippet When working on large projects whether it be websites or software applications, I like to try and make sure that settings from within my app/web configuration files are not only easily accessible within code, but also maintainable for future updates.

    Over the years, I have tried different approaches in an attempt to streamline how I use ASP.NET's configuration files within my day-to-day development and this is what I currently do.

    Group and Alphabetise

    I have started to sort all my settings alphabetically and group common functions/settings together. This alone makes navigating through a large configuration file much more easier.

    In addition, having a standard in-house development style and agreeing with your fellow developers how sections within the configuration file is expected to be structured can be useful. For example, on web projects I've worked on, all key sections are  sorted in the following order:

    1. configSections
    2. appSettings
    3. connectionStrings
    4. system.web
    5. customErrors
    6. system.webServer
    7. locations

    Common Naming Conventions

    I like to name my appsettings in the following format: "<Setting-Group>.<Name>". So if I were to add appsettings that related to Twitter, it would look something as the following:

    <add key="Twitter.ApiUrl" value="https://api.twitter.com/1.1/statuses/show.json" />
    <add key="Twitter.ApiKey" value="" />
    <add key="Twitter.ApiSecret" value="" />
    <add key="Twitter.AccessToken" value="" />
    <add key="Twitter.AccessTokenSecret" value="" />
    <add key="Twitter.Username" value="shomra" />
    

    This provides a simple and descriptive approach to breaking down all settings into manageable chunks.

    Strongly-Type AppSettings

    One thing that truly annoyed me when I first started .NET development is calling configuration values from within C# code. Not only did you have to write out (the very long-winded!) "ConfigurationManager.AppSettings["Twitter.Username"]", but also cast the value to a specific type.

    Using the "ConfigurationManager.AppSettings[]" call is awful. It creates the potential for typo's that aren't caught by the compiler and there's no nice intellisense to make our coding easier.

    I create a static configuration wrapper class to strongly-type all my config settings. The way I name my settings (as you can see from the "Common Naming Conventions" section) compliments the structure of my wrapper class.

    public class Config
    {
        public static class Social
        {
            #region Twitter
    
            public static class Twitter
            {
                public static string TwitterApiUrl
                {
                    get
                    {
                        return ConfigurationManager.AppSettings["Twitter.ApiUrl"];
                    }
                }
    
                public static string TwitterUsername
                {
                    get
                    {
                        return ConfigurationManager.AppSettings["Twitter.Username"];
                    }
                }
    
                public static string TwitterApiKey
                {
                    get
                    {
                        return ConfigurationManager.AppSettings["Twitter.ApiKey"];
                    }
                }
    
                public static string TwitterApiSecret
                {
                    get
                    {
                        return ConfigurationManager.AppSettings["Twitter.ApiSecret"];
                    }
                }
    
                public static string TwitterAccessToken
                {
                    get
                    {
                        return ConfigurationManager.AppSettings["Twitter.AccessToken"];
                    }
                }
    
                public static string TwitterAccessTokenSecret
                {
                    get
                    {
                        return ConfigurationManager.AppSettings["Twitter.AccessTokenSecret"];
                    }
                }
            }
    
            #endregion
        }
    }
    

    Admittingly, this can be quite time-consuming but when compared to the long-term benefits this has saved me a lot of headache.

    What Else Could Be Done?

    I've seen some developers use Applications Settings Architecture within the .NET framework when building Windows applications by creating a "Settings" file within the project.

    The only downside I can see with this approach is that all config values declared within the "Settings" file will be compiled at runtime and you lose the flexibility to change configuration values externally. Here's a nice StackOverflow post that describes this method in greater detail.

    If any of you readers have further suggestions or advice, I am all ears! :-)

    The Future...

    As Nick Dyer quite rightly pointed out to me yesterday on Google+, that our beloved web.config file will no longer form part of the applications we create in ASP.NET 5. We will have the freedom to create an applications configuration the way we want, simplifying the whole process.

    As I understand, there will be support for creating configuration inputs that can be placed inside JSON, XML and INI files using the new IConfiguration and ConfigurationModel sources.

    Sounds very promising.

  • A while ago, I wrote a post that showed how you would Render a Partial View As A String. But what if you had a Partial View and wanted to output its action to a string?

    Just like the majority of all other coding problems I encounter, StackOverflow always has the answer. In this case, a clever guy posted this piece of code:

    var sw = new StringWriter();
    PartialViewResult result = Email("Subject", "Body");
    
    result.View = ViewEngines.Engines.FindPartialView(ControllerContext, "Email").View;
    
    ViewContext vc = new ViewContext(ControllerContext, result.View, result.ViewData, result.TempData, sw);
    
    result.View.Render(vc, sw);
    
    var html = sw.GetStringBuilder().ToString();
    

    Works well enough. However, I didn't like the thought of having to add all this code inside my controller, especially when I have to output many Partial View actions to a string. So I created an extension method:

    /// <summary>
    /// Renders a Partial View Action to string.
    /// </summary>
    /// <param name="controller">Controller to extend</param>
    /// <param name="partialView">PartialView to render</param>
    /// <param name="partialViewName">Name of Partial View</param>
    /// <returns>Renders Partial View as a string</returns>
    public static string RenderActionToString(this Controller controller, PartialViewResult partialView, string partialViewName)
    {
        using (var sw = new StringWriter())
        {
            partialView.View = ViewEngines.Engines.FindPartialView(controller.ControllerContext, partialViewName).View;
    
            ViewContext vc = new ViewContext(controller.ControllerContext, partialView.View, partialView.ViewData,
                partialView.TempData, sw);
    
            partialView.View.Render(vc, sw);
    
            return sw.GetStringBuilder().ToString();
        }
    }
    

    This extension method can be used in the following way:

    //Access PollController class.
    PollController pc = new PollController();
    
    //Get the LatestPoll PartialView action and output to string.
    string myPartialView = this.RenderActionToString(pc.LatestPoll(), "../Poll/_LatestPoll");
    

    Much cleaner!

  • After quite a successful stint in creating some really amazing websites using MVC Razor 5, I had to revert back to working in the world of Web Forms for a new client project. Now I have to deal with .NET web controls, Postbacks and Viewstates.

    When creating a few simple forms consisting of some drop down lists, textboxes and textareas, I noticed wherever I set a "MaxLength" property it would not work. A character limit on my input field would just be ignored in all browsers. I could only replicate this bug when the Max Length property is used alongside the "TextMode" property.

    There were various places where I had the "TextMode" property set to either "Number" or "MultiLine". Soon as this was removed, the value set in "MaxLength" would work.

    How very odd...

    Thankfully, I am not the only person to experience the same issue. Currently, the only way to get around this problem is to add the following JavaScript code (slightly refactored for my own implementation) to check the character length "onKeyDown".

    var ASPNETForm = {
        "CheckTextAreaLength": function(textBox, e, length) {
            var mLen = textBox["MaxLength"];
    
            if (null == mLen)
                mLen = length;
    
            var maxLength = parseInt(mLen);
            if (!ASPNETForm.CheckSpecialKeys(e)) {
                if (textBox.value.length > maxLength - 1) {
                    if (window.event) { //IE
                        e.returnValue = false;
                        return false;
                    }
                    else //Firefox
                        e.preventDefault();
                }
            }
        },
        "CheckSpecialKeys": function(e) {
            if (e.keyCode != 8 && e.keyCode != 46 && e.keyCode != 35 && e.keyCode != 36 && e.keyCode != 37 && e.keyCode != 38 && e.keyCode != 39 && e.keyCode != 40)
                return false;
            else
                return true;
        }
    }
    

    Add to your ASP.NET TextBox control as so:

    <asp:textbox id="Instructions" MaxLength="50" onkeydown="return ASPNETForm.CheckTextAreaLength(this,event,'50');" runat="server" textmode="MultiLine">
    </asp:textbox>
    

    I am hoping there will be a more elegant solution in ASP.NET 5, or even better, a fix. This problem has been lurking around since 2009!

  • Changing the contents of a robots.txt file when a site is moved from staging to a live environment is quite a manual and somewhat cumbersome process. I sometimes have the fear of forgetting to replace the "Disallow: /" line with correct indexable entries required for the website.

    To give me one less thing to remember during my pre-live deployments, all my current and upcoming ASP.NET MVC sites will use a dynamic robots.txt file containing different entries depending on whether a site is in stage or live. In order to do this, we need to let the ASP.NET MVC application serve up the robots.txt file. This can be done by the following:

    • Create a new controller called "SEOController"
    • Add a new FileContentResult action called "Robots".
    • Add a new route.
    • Modify web.config.

    SEOController

    I have created a new controller that renders our "Robots" action as a plain text file. As you can see, my controller is not a type of "ActionResult" but a "FileContentResult". The great thing about "FileContentResult" is that it allows us to return bytes from the controller.

    In this example, I am converting bytes from a string using Encoding.UTF8.GetBytes() method. Ideal for what we need to generate a robots.txt file.

    [Route("robots.txt")]
    [Route("Robots.txt")]
    public FileContentResult Robots()
    {
        StringBuilder robotsEntries = new StringBuilder();
        robotsEntries.AppendLine("User-agent: *");
    
        //If the website is in debug mode, then set the robots.txt file to not index the site.
        if (System.Web.HttpContext.Current.IsDebuggingEnabled)
        {
            robotsEntries.AppendLine("Disallow: /");
        }
        else
        {
            robotsEntries.AppendLine("Disallow: /Error");
            robotsEntries.AppendLine("Disallow: /resources");
            robotsEntries.AppendLine("Sitemap: http://www.surinderbhomra.com/sitemap.xml");
        }
    
        return File(Encoding.UTF8.GetBytes(robotsEntries.ToString()), "text/plain");
    }
    

    RouteConfig

    Since I add my routing at controller level, I add the "MapMvcAttributeRoutes" method to the RouteConfig.cs file. But if you prefer to add your routes directly here, then this method can be removed.

    public class RouteConfig
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
    
            routes.MapMvcAttributeRoutes(); //Add this line!
    
            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
            );
        }
    }
    

    Web.config

    Add a "runAllManagedModulesForAllRequests" attribute to the modules tag in the web.config file to allow our robot.txt text file to be rendered by ASP.NET.

    <system.webserver>
      <modules runallmanagedmodulesforallrequests="true"></modules>
    </system.webserver>
    
  • When running my website through Google Page Insights, one of things I didn't do was cache static content, such as CSS, JavaScript and site images. Since I am on a shared hosting plan, I didn't think it was possible to have the option to cache a specific directory without direct IIS access.

    Normally, when working on client sites hosted on a dedicated server, I set the cache header within "HTTP Response Headers" area in IIS. But all this actually does is generate a web.config file within the directory you wish to cache:

    <!--?xml version="1.0" encoding="UTF-8"?-->
    <configuration>
        <system.webServer>
            <httpProtocol>
                <customHeaders>
                    <add name="Cache-Control" value="public, max-age=604800" />
                </customHeaders>
            </httpProtocol>
        </system.webServer>
    </configuration>
    

    So if you too are on shared hosting, add a web.config file with similar settings. In this case, I have cached my files for a week.

    You can also set the cache settings in your main web.config file by wrapping a location path around the <system.webServer> node:

    <location path="resources">
      <system.webServer>
            <httpProtocol>
                <customHeaders>
                    <add name="Cache-Control" value="public, max-age=604800" />
                </customHeaders>
            </httpProtocol>
        </system.webServer>
     </location>
    
  • One of the many nice things of using ASP.NET MVC Razor is that you have full control over how you segregate your HTML markup when building a page through rendering PartialViews. Since becoming an avid MVC developer, I am increasingly noticing how easy it is to make nice neat reusable code, whether it is used server or client-side.

    Just today, I found something really useful that is a truly defines this, where markup within PartialViews can be output to a page as string:

    /// <summary>
    /// Controller extension class that adds controller methods
    /// to render a partial view and return the result as string.
    ///
    /// Based on http://craftycodeblog.com/2010/05/15/asp-net-mvc-render-partial-view-to-string/
    /// </summary>
    public static class ControllerExtension
    {
     
      /// <summary>
      /// Renders a (partial) view to string.
      /// </summary>
      /// <param name="controller">Controller to extend</param>
      /// <param name="viewName">(Partial) view to render</param>
      /// <returns>Rendered (partial) view as string</returns>
      public static string RenderPartialViewToString(this Controller controller, string viewName)
      {
        return controller.RenderPartialViewToString(viewName, null);
      }
     
      /// <summary>
      /// Renders a (partial) view to string.
      /// </summary>
      /// <param name="controller">Controller to extend</param>
      /// <param name="viewName">(Partial) view to render</param>
      /// <param name="model">Model</param>
      /// <returns>Rendered (partial) view as string</returns>
      public static string RenderPartialViewToString(this Controller controller, string viewName, object model)
      {
        if (string.IsNullOrEmpty(viewName))
          viewName = controller.ControllerContext.RouteData.GetRequiredString("action");
     
          controller.ViewData.Model = model;
     
          using (var sw = new StringWriter())
          {
            var viewResult = ViewEngines.Engines.FindPartialView(controller.ControllerContext, viewName);
            var viewContext = new ViewContext(controller.ControllerContext, viewResult.View, controller.ViewData, controller.TempData, sw);
            viewResult.View.Render(viewContext, sw);
     
            return sw.GetStringBuilder().ToString();
          }
        } 
    }
    

    I can't take credit for this code. But here is the guy who can: Jan Jonas.

    Being able to output PartialViews as a string is actually quite handy, since you could have a paginated news listings page that displays the first page of articles server-side and any additional pages could be loaded in via jQuery Ajax. Each article item would be a PartialView so you could serve the same markup client-side. My code below probably explains things a little better:

    Article Listing View

    This page will list all my News Articles. As you can see, I am using an "ArticleListItem" as my PartialView.

    @model List<Article>
    
    @if (Model.Any())
    {
        <div class="article-list">
        @foreach (var a in Model.Select((value, index) => new { value, index }))
        {
            Html.RenderPartial("/Views/Article/_ArticleListItem.cshtml", new ArticleListItemView { Article = a.value, CssClass = ArticleHtmlHelper.GetItemCssClass((a.index + 1)), IsFullWidth = false});
        }
        </div>
    }
    else
    {
        <div>
            No articles could be returned.
        </div>
    }
    

    Article List Item PartialView

    My PartialView has quite a bit going on to determine how the markup should be rendered and it's definitely something I wouldn't want to have to duplicate elsewhere just to load in client-side. Nice!

    @model Site.Web.Models.Views.ArticleListItemView
    @{
        string fullWidthClass = String.Empty;
    
        if (Model.IsFullWidth)
        {
            fullWidthClass = "full-width";
        }
    }
    <div class="article-summary @Model.CssClass @fullWidthClass">
        <a href="@Model.Article.PageUrl" class="img">
            @if (Model.CssClass == "large")
            {
            <img src="@Model.Article.Images.ImageCollection[1].Url" />
            }
            else
            {
            <img src="@Model.Article.Images.ImageCollection[0].Url" />
            }
        </a>
        @if (Model.Article.Category != null)
        {
        <span class="cat">@Model.Article.Category.Name</span>
        }
        @if (Model.Article.ReadTime != null)
        {
        <span class="time">@String.Format("{0} read", Model.Article.ReadTime)</span>
        }
        <h2 class="@Model.CssClass"><a href="@Model.Article.PageUrl">@Model.Article.Title</a></h2>
        @if (Model.Article.Author != null)
        {
        <a href="@Model.Article.Author.PageUrl.Url" class="author">
            <img src="@Model.Article.Author.Images.ImageCollection[0].Url" />
            <span>@String.Concat(Model.Article.Author.FirstName, " ", Model.Article.Author.LastName)</span>
        </a>
        }
    </div>
    

    GetArticleItems() Controller

    This is where the RenderPartialViewToString() method shines! This controller is called within my jQuery Ajax function to get the next page of news articles. I am then calling my "ArticleListItem" PartialView to return the HTML markup as a string through my client-side call.

    [HttpPost]
    public JsonResult GetArticleItems(DBContext ctx, int pageNo, int pageSize, string categoryId)
    {
        ApiDocumentInfo docInfo = DocumentHelper.SearchDocuments(ctx, true, "article", "category", categoryId, pageSize, pageNo, "articles", "date desc");
    
        List<Article> articles = docInfo.Documents.Select(doc => doc.ToArticle(ctx)).ToList();
    
        StringBuilder articleHtml = new StringBuilder();
    
        if (articles.Any())
        {
            for (int a = 0; a < articles.Count; a++)
                articleHtml.Append(this.RenderPartialViewToString("_ArticleListItem", new ArticleListItemView { Article = articles[a], CssClass = ArticleHtmlHelper.GetItemCssClass((a + 1)), IsFullWidth = false } ));
        }
    
        return Json(articleHtml.ToString());
    }
    
  • Published on
    -
    1 min read

    XML Parsing Error In A MVC Razor View

    If you set a Controller's response type to "text/xml", you may encounter an: "XML Parsing Error: XML or text declaration not at start of entity". Your View may look something like this:

    @{
        Layout = null;
    }
    
    <?xml version="1.0" encoding="utf-8" ?>
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
        @if (Model.Any())
        {
            foreach (SitemapNode node in Model)
            {
                <url>
                    <loc>@node.Location</loc>
                    <lastmod>@node.LastModified</lastmod>
                    <changefreq>monthly</changefreq>
                </url>
            }
        }
    </urlset>
    

    In this case, I was creating a sitemap for one of my websites. So I created a Controller and View as I normally would do. However, when generating an XML output, you'll have to do something a little different in MVC:

    @{
        Layout = null;
    }<?xml version="1.0" encoding="utf-8" ?>
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
        @if (Model.Any())
        {
            foreach (SitemapNode node in Model)
            {
                <url>
                    <loc>@node.Location</loc>
                    <lastmod>@node.LastModified</lastmod>
                    <changefreq>monthly</changefreq>
                </url>
            }
        }
    </urlset>
    

    Can you see what is the difference? You'd be forgiven for not seeing it. But if you look a little closer, you'll see that I pushed up my XML declaration right up next to where I set the Layout block. This is because Razor outputs extra lines within its markup.

    So when I left an empty line after my Layout block (as seen my my first code example), this gets rendered as an empty line when you run the page which would not be valid XML.

    Update - 28/08/2014

    Just found an even better way to get around the same issue from reading Joe Raczkowski blog. All that needs to be done is place the main XML declaration at the top of the page inside the @{} braces:

    @{
    Layout = null;
    Response.ContentType = "text/xml";
    Response.Write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
    }
    
  • I've been toying around with MVC for quite some time now. Initially, I couldn't imagine breaking away from the safety-net that is ASP.NET Web Forms. What many developers are not aware of when moving over to the ASP.NET MVC framework is that you have to write everything from scratch. You will not have the comfort of dragging and dropping event driven controls in a GUI-centric way.

    But nowadays, I am itching to build new sites in MVC. I like to be in control of the whole page lifecycle and the mark-up that is generated.

    Since there are no pre-built resusable controls, I decided start developing my own library of extensions that I could use in future MVC projects I work on. Ranging from pagination to tag clouds.

    Creating custom extensions is really easy. I started off by creating a Category Navigation that returns a IHtmlString (HTML-encoded string that should not be encoded again).

    public static IHtmlString CategoryNavigation(this WebViewPage wvp)
    {
        StringBuilder navBuilder = new StringBuilder();
    
        List<CustomCategory> categories = CustomCategoryLogic.GetCategories();
    
        if (categories.Count > 0)
        {
            navBuilder.Append("<ul class=\"nav\">");
            navBuilder.Append("<li><a href=\"/\">Home</a></li>");
    
            foreach (CustomCategory cc in categories)
                navBuilder.AppendFormat("<li><a href=\"/{0}\">{1}</a></li>", cc.Slug, cc.Name);
    
            navBuilder.Append("</ul>");
        }
    
        return MvcHtmlString.Create(navBuilder.ToString());
    }
    

    To display my category navigation in one of my Views, I just need to write:

    @this.CategoryNavigation()
    

    How easy is that!?