Html helper for list of hidden Inputs from Name Value Pair string

Share on Facebook

Recently, while working on a project to integrate a payment provider via the hosted payment page approach embedded within an Iframe, I needed a simple Html Helper for ASP.Net MVC which took in a name value pair string like FIRSTNAME=Mike&LASTNAME=Teye&Age=25 and generated a list of html hidden input tags for use as part of a form post whose response was then rendered in an Iframe tag.

I admit it's a specialised helper and so I don't forsee many people needing it, but then again should you be one of those few who needed it, the below class represents my attempt at such a helper:

using System;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Web.Mvc;

namespace Kraft.Web.Models.Extensions
{
    public static class HtmlHelperExtensions
    {
        public static MvcHtmlString HiddenFieldsListFor(this HtmlHelper htmlHelper, Expression> expression)
        {
            var name = ExpressionHelper.GetExpressionText(expression);
            var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
            return HiddenFieldsList(htmlHelper, name, metadata.Model as string);
        }

        private static MvcHtmlString HiddenFieldsList(this HtmlHelper helper, string nameValuePairPropertyName, string nameValuePairPayload)
        {
            var stringBuilder = new StringBuilder();
            var nameValuePairs = nameValuePairPayload.Split('&').ToList();
            nameValuePairs.ForEach(nvp => stringBuilder.Append(CreateHiddenInput(nvp).ToString(TagRenderMode.SelfClosing)));
            var div = new TagBuilder("div");
            div.MergeAttribute("class", "hiddenFields");
            div.InnerHtml = stringBuilder.ToString();
            return MvcHtmlString.Create(div.ToString());

        }

        private static TagBuilder CreateHiddenInput(string nameValuePair)
        {
            var hiddenInput = new TagBuilder("input");
            var nvpPortions = nameValuePair.Split('=');
            hiddenInput.MergeAttribute("type", "hidden");
            hiddenInput.MergeAttribute("id", nvpPortions[0]);
            hiddenInput.MergeAttribute("name", nvpPortions[0]);
            hiddenInput.MergeAttribute("value", nvpPortions[1]);
            return hiddenInput;
        }
    }
}

You can use the helper in an MVC razor view like so (where NvpPayload is a view model property containing your name value pair string):

@Html.HiddenFieldsListFor(model => model.NvpPayload)

Hope you find it helpful.


Integrating SandCastle Help File Builder with TFS 2012 build

Share on Facebook

Sandcastle has been around for a while. Its usage has however been dificult and unappealing until Sandcastle Help File Builder codeplex project came into the picture.

The recent version of Sandcatsle help file builder makes it even more easier by providing a Visual Studio plugin which facilitates the management of the help file generation through familiar visual studio project properties and also allows referencing projects which are part of your solution in your SHFB project.

The only piece of the puzzle missing is the integration of the build of the document project as part of a CI build on Team Foundation Server TFS. There are a few outdated approaches to this available online when I googled. I felt there should be an easier integration now that there is a VS plugin, so I set out to check this out and in turns out it is very easy. So the below is how I did the simple integration:

To Create a visual studio SHFB project, download and install SHFB on your development machine using the guided installer. You will have to install the Visual Studio plugin as part of the install. Create a new project in Visual Studio by using the documentation subsection of your choice language. The details of configuring the help file builder are the same as that for the standalone Sandcastle Help file builder GUI.

First of all you will need to download the latest version of Sandcastle Help File builder (which ships with the VS plugin).

Extract the files from the zip archive and use the guided installer from the root folder to install sandcastle and help file compiler onto

the build controller machine.

You will have to restart the build controller machine to reload new path environment variables created by the installer (SHFBROOT).

This environment variable is used within a sandcastle help file project to locate the help file compiler executables and serves the same purpose on the build agent machine as it does on a local development machine.

You will need one final modification to the help file builder project. First unload the project by right clicking on the project name in solution explorer and select unload project. Then open the project file xml by right clicking and selecting open with xml editor. As per this post, replace the line immediately below the following line:


With the following code:

  

.\Help\
$(OutDir)

Ignore SignalR Persistent Connections in New Relic

Share on Facebook

I had a problem recently at work where the SignalR.Hosting.AspNet.AspNetHandler was displaying high response times in our New Relic monitoring. I came across this SO blog post which offerred some workarounds for the problem. I was however using an older version of SignalR (a pre 1.0 release) and the options listed in the blog post failed to resolve my particular case.

What worked for me eventually was to hook into the PostMapRequestHandler event of the Application class in global.asax and then check for the handler. Because that event fires after a handler has been selected to process the request, we are able to tell what type of handler has been selected and then use the NewRelic Agent API (You will need to add this to your project via Nuget, search for NewRelic.Api.Agent) to ignore monitoring as per the code below:

 protected void Application_PostMapRequestHandler()
 {
     if (HttpContext.Current.Handler is SignalR.Hosting.AspNet.AspNetHandler)
     {
          NewRelic.Api.Agent.NewRelic.IgnoreTransaction();
     }
}

This approach works even for later versions of SignalR (1.0+) in which case you have to match the OWIN based handler as shown below:

protected void Application_PostMapRequestHandler()
{
     if (HttpContext.Current.Handler is Microsoft.Owin.Host.SystemWeb.OwinHttpHandler)
     {
          NewRelic.Api.Agent.NewRelic.IgnoreTransaction();
     }
} 

Happy coding!


Custom Validator IsValid Overload Precedence

Share on Facebook

 

When you derived a Custom DataAnnotations Validator from the default ValidationAttribute class, you have a choice of two overrides to implement your custom validation logic. You may override one of the following methods depending on your objectives.

  • public bool IsValid(object value)
  • protected ValidationResult(object value, ValidationContext validationContext)

Recently, I had a situation where I implemented custom validation (ie. The validator did not use the built in MVC DefaultModelBinder which implemented validation). I hooked up a custom model binder and also needed an accompanying custom validator. I ended up using the DataAnnotations Validator from within my code like so:

 var context = new ValidationContext(wizardBindModel, null, null) {MemberName = item.PropertyInfo.Name};
                        var validationResults = new Collection();
                        if (!Validator.TryValidateValue(value, context, validationResults, new Collection(){validationAttribute}))
                        {
                            validationResults.ToList().ForEach(r => modelState.AddModelError(r.MemberNames.First(), r.ErrorMessage));
                        }    
I was then wondering, what happened if my validation attribute implemented both IsValid(object) and IsValid(object, ValidationContext). I did not find an explanation through google, so I tried the code and found out by experience that the IsValid(object,ValidationContext) has precedence over the IsValid(object) method. If you override both methods, only the IsValid(object,ValidationContext) version will be invoked by the DataAnnotations TryValidateValue method. HTH.

Styling Asp.Net MVC validation errors as tooltips

Share on Facebook

I recently had to find a way of styling asp.net Mvc validation errors as tooltips/speech bubbles/hints in order to preserve consistency of the UI on a legacy system. I was able to achieve this with some simple jquery, some css modification and a very handy jquery plugin called jquery validation hooks. The css and javascript code are listed below. Follow the instructions at the linked jquery validation hooks page.

 $(document).ready(function () {
        $('form').addTriggersToJqueryValidate().triggerElementValidationsOnFormValidation();
        $('form').formValidation(function (element, result) {
            $(".field-validation-error").each(function (e) {
                var errorSpan = $(this);
                var relatedInput = $(this).parent().children("input:first");
                relatedInput.hover(
                        function () {
                            errorSpan.show();
                        },
                        function () {
                            errorSpan.hide();
                        }
                    );
                 errorSpan.hide();
            });
        });
    });
/* VALIDATION ERROR SPAN */

.field-validation-error span
{
  color:#ffffff;
  margin-left: 5px;
  display:none;
  font-size:12px;
  font-family:arial;
  padding:.5em 1em;
  padding-top:5px;
  position:relative;
  text-align:center;
  vertical-align:middle;
  border:1px solid silver;
  background-color:#ff0000;
}

.field-validation-error span:after 
{
 content:"";
  display:inline-block;
  font-size:2em;
  height:20px;
  width:20px;
  position:absolute;
  left:-0.4em;
  top:0.1em;
 background: url(pointer.gif) left center no-repeat;
}

The pointer image is attached for your convenience. Fell free to improve the css appropriately.


Unity Interception Behavior - Crucial point

Share on Facebook

I tend to forget the reason for the abnormal syntax when invoking the intercepted method in a Unity interception behavior class. I mean this:

IMethodReturn msg = getNext()(input, getNext);

The quote below reminds me of the reason. The getNext parameter is a delegate which returns a delegate, but also takes that original delegate as an input: "The Invoke method has two parameters: input and getNext. The input parameter rapresents the current call to the original method, the getNext parameter is a delegate to execute to get the next delegate in the behavior chain".


using knockout.mapping with MVC Models

Share on Facebook

This little syntax below will help convert an MVC Model object into a knockout observable viewModel.

    @{
string data = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(Model);
}




IQueryable Extension For OrderBy with string parameter

Share on Facebook

This little extension method will order an IQueryable sequence by a string parameter which matches a property name.

public static class IQueryableExtensions
    {
        public static IQueryable OrderBy(this IQueryable source, string ordering, params object[] values)
        {
            var type = typeof(T);
            var property = type.GetProperty(ordering);
            var parameter = Expression.Parameter(type, "p");
            var propertyAccess = Expression.MakeMemberAccess(parameter, property);
            var orderByExp = Expression.Lambda(propertyAccess, parameter);
            var resultExp = Expression.Call(typeof(Queryable), "OrderBy", new Type[] { type, property.PropertyType }, source.Expression, Expression.Quote(orderByExp));
            return source.Provider.CreateQuery(resultExp);
        }
    }

Kill all Connections to Sql Sever Database

Share on Facebook

This script will kill all active connections to a given Sql Server Database. Simply set the database name to the @DBName Parameter.

USE master
GO

SET NOCOUNT ON
DECLARE @DBName varchar(50)
DECLARE @spidstr varchar(8000)
DECLARE @ConnKilled smallint
SET @ConnKilled=0
SET @spidstr = ''
Set @DBName = 'DATABASENAME'

SELECT SPID, STATUS, PROGRAM_NAME, LOGINAME=RTRIM(LOGINAME), HOSTNAME, CMD FROM MASTER.DBO.SYSPROCESSES WHERE DB_NAME(DBID) = @DBName AND DBID != 0

IF db_id(@DBName) < 4
BEGIN
PRINT 'Connections to system databases cannot be killed'
RETURN
END
SELECT @spidstr=coalesce(@spidstr,',' )+'kill '+convert(varchar, spid)+ '; '
FROM master..sysprocesses WHERE dbid=db_id(@DBName)

IF LEN(@spidstr) > 0
BEGIN
EXEC(@spidstr)
SELECT @ConnKilled = COUNT(1)
FROM master..sysprocesses WHERE dbid=db_id(@DBName)
END




Authorization Attribute for use with MvcSitemapProvider

Share on FacebookThis is a simple Authorization attribute which will work with the codeplex Asp.Net MvcSiteMapProvider.

public class SiteMapAuthorizeAttribute : AuthorizeAttribute
    {
        public string Action { get; set; }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (!httpContext.User.Identity.IsAuthenticated)
                return false;

            var node = SiteMap.CurrentNode;

            // If the node is null, then it was not loaded into memory 
            // because this user was not authorized to view this node
            if (node == null)
                return false;

            // Check the node's accessibility regardless in case we got passed the above check
            return node.IsAccessibleToUser(HttpContext.Current);
        }

        public override void OnAuthorization(AuthorizationContext filterContext)
        {
            base.OnAuthorization(filterContext);
        }

        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            // If user is not authenticated allow default handling
            if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
            {
                base.HandleUnauthorizedRequest(filterContext);
                return;
            }

            string customErrorPage = GetCustomError("403");
            if (customErrorPage == null)
            {
                base.HandleUnauthorizedRequest(filterContext);
                return;
            }

            // Redirect to 403 (Access Denied) page
            filterContext.Result = new RedirectResult(customErrorPage);
        }

        private string GetCustomError(string statusCode)
        {
            CustomErrorsSection customErrorsSection = ConfigurationManager.GetSection("system.web/customErrors") as CustomErrorsSection;

            if (customErrorsSection != null)
            {
                CustomError customErrorPage = customErrorsSection.Errors[statusCode];

                if (customErrorPage != null)
                    return customErrorPage.Redirect;
            }
            return null;
        }
    }

About Me

When not scratching my head for solutions to software challenges, I spend my time playing with my little boy - Michael Jnr.

Quotations

"A fanatic is one who can't change his mind and won't change the subject."
Sir Winston Churchill

Donate with PayPal - it

Calendar

<<  April 2014  >>
MoTuWeThFrSaSu
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

View posts in large calendar

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2005 - 2014

Search