tisdag 29 maj 2018

Dynamic serverside validation of form data

public class FormValidationHelper
{
    public TValidationResult DoDynamicValidation(TModel model, string methodBody)
    {
        var result = CompileWebFormValidationScript(methodBody);
        return result.Assembly == null ? default(TValidationResult) : result.Assembly.ExecuteFromAssembly("DynamicValidator", "Validate", new object[] { model });
    }

    public static CompilationResult CompileWebFormValidationScript(string script)
    {
        var references = new[]
        {
            MetadataReference.CreateFromFile(typeof (object).Assembly.Location),
            MetadataReference.CreateFromFile(typeof (TValidationResult).Assembly.Location),
            MetadataReference.CreateFromFile(typeof (TModel).Assembly.Location)
        };
        var dynamicCompiler = new DynamicCompiler();
        var result = dynamicCompiler.CompileSourceRoslyn(references,
            @"using " + typeof (TModel).Namespace + @";
                    using " + typeof (TValidationResult).Namespace + @";

                    public class DynamicValidator
                    {
                        public " + typeof (TValidationResult).Name + @" Validate(" + typeof (TModel).Name + @" model)
                        {
                            " + script + @"
                        }
                    }
                ");
        return result;
    }
}

public class FormValidationResult
{
    public bool HasError { get; }
    public string Message { get; }
    public string FieldName { get; }

    public WebFormValidationResult()
    {
        HasError = false;
        Message = string.Empty;
        FieldName = string.Empty;
    }

    public WebFormValidationResult(bool hasError, string message, string fieldName)
    {
        HasError = hasError;
        Message = message;
        FieldName = fieldName;
    }

    public override string ToString()
    {
        return $"HasError: {HasError}, Message: {Message}, FieldName: {FieldName}";
    }
}
Use like so:
var validationScript = "return new FormValidationResult(model.FirstName == \"John\");"
var model = new FormModel { FirstName = "Lars", LastName = "Doe", Age = 61 };
var validationHelper = new FormValidationHelper();
var result = validationHelper.DoDynamicValidation(model, validationScript);

tisdag 10 juni 2014

Enum with DescriptionAttribute

public static class EnumExtensions
{
    public static T GetAttribute(this Enum enumeration) where T : Attribute
    {
        var type = enumeration.GetType();
        var memberInfos = type.GetMember(enumeration.ToString());
        var attribute = memberInfos[0].GetCustomAttributes(typeof (T), false);

        var attributes = attribute.Cast().ToList();
        
        return attributes.SingleOrDefault();
    }

    public static string Description(this Enum enumeration)
    {
        var attribute = GetAttribute(enumeration);
        if (attribute == null)
            return "";

        return attribute.Description;
    }
}

public enum GroundType
{
    [Description("Jord")]
    Soil = 1,
    [Description("Gräs")]
    Grass = 2
}

public class DescriptionAttribute : Attribute
{
    private readonly string _descr;

    public DescriptionAttribute(string descr) { _descr = descr; }

    public string Description
    {
        get { return _descr; }
    }

    public override string ToString() { return Description; }
}
Use like so:
var groundType = GroundType.Soil;
var desc = groundType.Description();

torsdag 24 april 2014

Small settings factory class

Public Class WidgetSettingsFactory
 Public Function GetItemSettings(Of T As ItemSettings)(ByVal externalName As String, ByVal doc As Document) As ItemSettings
        Dim retval As T = GetSettingsFromType(GetType(T))
        Dim helpers As New Helpers()
        Dim templateId As Integer = doc.TemplateId
        Dim nodeId As Integer = doc.NodeId
        Dim documentId As Integer = doc.DocumentId

        Dim itemProperties As Dictionary(Of String, String) = helpers.GetItemProperties(externalName, templateId)
        If Not itemProperties Is Nothing Then
            For Each item As KeyValuePair(Of String, String) In itemProperties
                retval.SetProperty(item.Key, helpers.ReplaceDynPropNameWithValue(item.Value, nodeId))
            Next
        End If

        Dim dataSettings As Dictionary(Of String, String) = helpers.GetDocumentDataSettings(externalName, templateId, documentId)
        If Not dataSettings Is Nothing Then
            For Each item As KeyValuePair(Of String, String) In dataSettings
                retval.SetProperty(item.Key, helpers.ReplaceDynPropNameWithValue(item.Value, nodeId))
            Next
        End If
        Return retval
    End Function

    ''' 
    ''' Returns a settings object that is inherited from ItemSettings
    ''' 
    ''' Type of Settings object
    ''' A new instance of the incoming type of object
    ''' 
    Public Shared Function GetSettingsFromType(ByVal settingsType As Type) As ItemSettings
        Return settingsType.Assembly.CreateInstance(settingsType.FullName)
    End Function
End Class

onsdag 19 september 2012

Print Properties of a Class

Private Sub PrintMemberClassInfo(ByVal memberClass As MemberClass)

    For Each propertyInfoItem As PropertyInfo In memberClass.GetType().GetProperties()
        Dim propValue = propertyInfoItem.GetValue(memberClass, Nothing)
        Dim value As String
        If Not propValue Is Nothing Then
            value = propValue.ToString()
            If propValue.ToString() = "MemberReg.Member" Then
                Dim member As Member = CType(propValue, Member)
                For Each propertyInfo2 As PropertyInfo In member.GetType().GetProperties()
                    Dim propValue2 = propertyInfo2.GetValue(member, Nothing)
                    Dim value2 As String
                    If Not propValue2 Is Nothing Then
                        value2 = propValue2.ToString()
                    Else
                        value2 = "Nothing"
                    End If
                    If value2 = "" Then value2 = """"""
                    Response.Write(" * " & propertyInfo2.Name & " : " & value2 & "
") Next End If Else value = "Nothing" End If If value = "" Then value = """""" Response.Write(propertyInfoItem.Name & " : " & value & "
") Next End Sub

måndag 9 juli 2012

PowerShell - Iterate folders and move items to parent

Get-ChildItem -Recurse | Where {$_.psIsContainer -eq $true} | Select-Object FullName | ForEach-Object {
    Set-Location $_.FullName;
    Move-Item *.* -Destination $loc;
    Set-Location $loc;
}

tisdag 19 juni 2012

VBScript - How to sort an array of objects

Function SortItemsByPubDate(items, intSort)
    Dim result : Set result = Server.CreateObject("Scripting.Dictionary")
    Dim objDict()
    Dim objKey
    Dim strKey,strItem, objItem
    Dim X,Y,itemCount
    Const DICT_KEY = 1
    Const DICT_ITEM = 2
    Dim oRssItem

    itemCount = items.Count
    
        If itemCount > 1 Then
        
        ReDim objDict(itemCount,2)
        X = 0
        
        ' Add key and the value to sort the array on
        For Each objKey In items
            objDict(X,DICT_KEY)  = CStr(objKey)
            objDict(X,DICT_ITEM) = items(objKey).pubDate
            X = X + 1
        Next
        
        
        For X = 0 to (itemCount - 2)
            For Y = X to (itemCount - 1)
                If StrComp(objDict(X,intSort),objDict(Y,intSort),vbTextCompare) > 0 Then
                    strKey  = objDict(X,DICT_KEY)
                    strItem = objDict(X,DICT_ITEM)
                    objDict(X,DICT_KEY)  = objDict(Y,DICT_KEY)
                    objDict(X,DICT_ITEM) = objDict(Y,DICT_ITEM)
                    objDict(Y,DICT_KEY)  = strKey
                    objDict(Y,DICT_ITEM) = strItem
                End If
            Next
        Next
        
        
        For X = 0 to (itemCount - 1)
            result.Add objDict(X,DICT_KEY), objDict(X,DICT_ITEM)
        Next

        Set SortItemsByPubDate = result
    Else

        Set SortItemsByPubDate = items
    End If
        
End Function

torsdag 3 maj 2012

JavaScript Scrapbook addition

A repeater with a nested GridView. All GridViews have their own UpdateProgress controls.
This hides all UpdateProgress divs but the one for the specific GridView that triggered the AJAX call.

$('.applicationRowAction').live("click", function () {
            var tableHeight = $(this).closest('table').height();
            var panelMarginTop = (tableHeight / 2)
            var appId = $(this).parent().parent().find('.divRowAppWrapperId').attr("id").substring(4);
            $('.updateProgress').css('margin-top', panelMarginTop + 'px');
            $('.updateProgress').each(function () {
                var divId = $(this).attr("id").substring(17)
                if (divId != appId) {
                    $(this).hide();
                }
            })
        });

tisdag 26 april 2011

DeSerialize XML file with namespaces

Given the following XML file, I wanted to iterate over all of the records and summarize the values of all elements named HANDLED.
Each LANGUAGE has 12 records so I wanted a summary for each language and then spit it out into a .csv file.




TELEPHONE__2011-01-26.XML
345

1
SWE
12
1
4533
2400
6292
204
2196




I got nice exceptions occurring because of the namespace prefix when I first tried the following code:


var stats = from stat in xd.Descendants("CRP:PHONE_STATISTICS")
where stat.Element("LANGUAGE").Value == language
select new
{
Handled = int.Parse(stat.Element("HANDLED").Value),
Abandoned = int.Parse(stat.Element("ABANDONED").Value),
Language = stat.Element("LANGUAGE").Value
};


So I then found out that I could prefix the element names with the actual namespace provided in the root element of the document, like this:


XNamespace ns = "http://somedomain/CR/PHONE";

var stats = from stat in xd.Descendants(ns + "PHONE_STATISTICS")


The end result looks like this:


namespace XMLSummarizer
{
class Program
{
static void Main(string[] args)
{
XNamespace ns = "http://somedomain/CR/PHONE";

string txtLogFileName = @"data.csv";
string XMLfolder = Directory.GetCurrentDirectory();

TextWriter tw = new StreamWriter(txtLogFileName);

tw.WriteLine("Date;Month;Handled;Abandoned;Language");

foreach (var file in System.IO.Directory.EnumerateFiles(XMLfolder,"*.xml"))
{
DateTime statsDate = DateTime.Parse(file.Substring(file.IndexOf("_PHONE") + 7, 10));
Console.WriteLine(statsDate.ToShortDateString());

XDocument xd = XDocument.Load(file);

string[] languages = new string[] { "SWE", "DAN", "NOR", "FIN" };

foreach (string language in languages)
{
SummarizeDataPerDay(ns, tw, xd, language, statsDate);
}
}

tw.Flush();
tw.Close();

Console.WriteLine("Operation completed successfully. Press [Enter] to close application.");
Console.ReadLine();
}

private static void SummarizeDataPerDay(XNamespace ns, TextWriter tw, XDocument xd, string language, DateTime dataDate)
{
var stats = from stat in xd.Descendants(ns + "PHONE_STATISTICS")
where stat.Element("LANGUAGE").Value == language
select new
{
Handled = int.Parse(stat.Element("HANDLED").Value),
Abandoned = int.Parse(stat.Element("ABANDONED").Value),
Language = stat.Element("LANGUAGE").Value
};

string lang = "";
int handledCalls = 0;
int abandonedCalls = 0;

foreach (var stat in stats)
{
handledCalls += stat.Handled;
abandonedCalls += stat.Abandoned;
lang = stat.Language;
}

tw.WriteLine(dataDate + ";" + dataDate.Month + ";" + handledCalls + ";" + abandonedCalls + ";" + lang);
}
}
}

måndag 21 mars 2011

Delete from MySQL with PHP


$logID = $_GET['id'];

open_db('mydb');

$query = "DELETE FROM conversionlog WHERE logID = '$logID'";
$result = mysql_query($query)
or die("Query failed: ".mysql_error());

close_db();

header("Location: page.php?action=viewcases&hl='$logID'");

måndag 17 januari 2011

Post numero uno

So the first order of business will be a move of this blog to our own which is under development, thanks to inspiration from Scott Hanselman over at hanselman.com and his colleagues.

I'm still honing my skills in C# and ASP.NET so bear with me. As a father of a 5 months old little girl it's hard to take time to dive into VS2010 and the bookshelf. :)

My level of coding the past 5 years have been sporadic and I've always feared for the day I'd have to move from the safe havens of ASP 2.0 and VBScript. Of course I always knew I would have to take the plunge but thanks to the Windows Phone 7 platform and the vast amount of tools and documentation that is available, together with a really strong breeze of fresh air from Microsoft I took the leap.

To my great surprise the Netduino, an open source hardware platform based on the .NET Micro framework saw the light in the second half of 2010.

So now my programming and electronics interests get their share of love and I have a few home automation project ccoking, but more on that later.

As I began searching for the ASP.NET File->New project equivalent of classic ASP I found out about a lot of cool people that are involved in the ASP.NET community and one of those people are Scott Hanselman, a great speaker and inspiration. And I must say I've (for now) found a favorite in the project templates, MVC 3 with the Razor view engine. Really neat stuff. Read more about it on Scott Guthrie's blog: weblogs.asp.net/scottgu/

I'd also like to thank Rob Miles of www.robmiles.com for his C# Yellow Book and brittish wit.

Last but not least, learnvisualstudio.com has tons of videos related to Visual Studio development, ranging from ASP.NET 2.0 up to the brand new features like Entity Framework 4 and MVC hands-on's. Give them a try, it's worth every penny.

P.S.
This could actually be the longest blog post I've ever written... :)