Image Image Image Image Image
Scroll to Top

To Top

AOP

[Gist] ASP.NET MVC bind String property as string.Empty instead of null

On 27, Jan 2013 | 3 Kommentare | inAOP | vonJohannes Hoppe

Currently I’m migrating a good-old ASP.NET MVC v1 project to v4.
In ASP.NET MVC 1.0 the default behavior of Model Binding was to initialize strings to String.Empty. Imagine this simple method:

public ActionResult Hello(string name)
{
    if (name.Contains("Bob"))
    {
        return Content("Hi my friend!");
    }
 
    return Content("Hi stranger!");
}

However, later versions of ASP.NET MVC initialize Strings to null. This results in some nasty NullReferenceExceptions all over the code. On the one hand this change of the framework might be reasonable. The default value of a String is null. But on the other hand we should try to avoid null values at all. As soon as we start to tolerate null values we are going to clutter the code with guards against them:

xCutting – AOP bei der .NET User Group Niederrhein – Video, Slides & Download

Johannes Hoppe spricht von seiner Sicht über Clean-Code und die Grenzen von objektorientierter Programmierung bei der .NET User Group Niederrhein. Anhand praktischer Bespiele zeigt er, wie man mit dem AOP-Framework Postsharp elegante Modularisierungsansätze erhält. Der Vortrag richtet sich an interessierte Einsteiger in das Thema Aspektorientierte Programmierung (AOP) mit .NET.

Alle relevanten Code-Fragmente sind weiter unten aufgelistet!

  1. ActionResult Edit
  2. MyConvertExeption
  3. LogTimeAspect
  4. SimpleCacheBaseAspect


Hier sind alle Code-Fragmente aus dem Video:

ActionResult Edit

[HandleError(ExceptionType = typeof(MyException))]
[AcceptVerbs(HttpVerbs.Post)]
[MyConvertExeption]
public ActionResult Edit(Note noteToEdit, int[] newCategories)
{
    NoteWithCategories changedNote = this.WebNoteService.Update(noteToEdit, newCategories);
    return View(changedNote);
}


MyConvertExeption

using PostSharp.Aspects;
 
[Serializable]
public class MyConvertExeption : OnExceptionAspect
{
    public override void OnException(MethodExecutionArgs args)
    {
        throw new MyException("Fehler", args.Exception);
    }
}

LogTimeAspect

namespace PostsharpAspects.Logging
{
    using System;
    using System.Diagnostics;
    using System.Reflection;
 
    using NLog;
 
    using PostSharp.Aspects;
    using PostSharp.Aspects.Dependencies;
 
    [Serializable]
    [ProvideAspectRole(StandardRoles.PerformanceInstrumentation)]
    [AspectRoleDependency(AspectDependencyAction.Order, AspectDependencyPosition.After, StandardRoles.Caching)]
    [AspectRoleDependency(AspectDependencyAction.Order, AspectDependencyPosition.After, StandardRoles.ExceptionHandling)]
    [AspectRoleDependency(AspectDependencyAction.Commute, StandardRoles.PerformanceInstrumentation)]
    public class LogTimeAspect : OnMethodBoundaryAspect
    {
        private const int SlowTotalMilliseconds = 250;
 
        private static readonly Logger Logger = LogManager.GetLogger("LogTimeAspect");
        private static readonly Stopwatch Stopwatch = new Stopwatch();
        private string instanceName;
 
        static LogTimeAspect()
        {
            Stopwatch.Start();
        }
 
        /// <summary>
        /// Method executed at build time.
        /// </summary>
        public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo)
        {
            this.instanceName = method.DeclaringType.FullName + "." + method.Name;
        }
 
        /// <summary>
        /// Saves the time method start
        /// </summary>
        [DebuggerStepThrough]
        public override void OnEntry(MethodExecutionArgs args)
        {
            args.MethodExecutionTag = Stopwatch.ElapsedTicks;
        }
 
        /// <summary>
        /// Stops the time on method end
        /// </summary>
        [DebuggerStepThrough]
        public override void OnExit(MethodExecutionArgs args)
        {
            long timeInTicks = Stopwatch.ElapsedTicks - (long)args.MethodExecutionTag;
            double totalMilliseconds = TimeSpan.FromTicks(timeInTicks).TotalMilliseconds;
 
            if (totalMilliseconds > SlowTotalMilliseconds)
            {
                Logger.Trace(String.Format("{0}ms\t- {1}", totalMilliseconds, this.instanceName));
            }
 
            base.OnExit(args);
        }
    }
}

SimpleCacheBaseAspect

namespace PostsharpAspects.Caching
{
    using System;
    using System.Reflection;
    using System.Text;
 
    using PostSharp.Aspects;
 
    using PostsharpAspects.Caching.CacheImplementation;
 
    [Serializable]
    public class SimpleCacheBaseAspect : OnMethodBoundaryAspect
    {
        protected ICache Cache { get; set; }
 
        public override void CompileTimeInitialize(MethodBase method, AspectInfo aspectInfo)
        {
            string prefix = method.DeclaringType.ToString();
            this.Cache = new Cache(prefix);
        }
 
        public override void OnEntry(MethodExecutionArgs args)
        {
            string cacheKey = GenerateCacheKey(args);
            object value = this.Cache.Get(cacheKey);
 
            if (value == null)
            {
                args.MethodExecutionTag = cacheKey;
                return;
            }
 
            args.ReturnValue = value;
            args.FlowBehavior = FlowBehavior.Return;
        }
 
        public override void OnSuccess(MethodExecutionArgs args)
        {
            string cacheKey = (string)args.MethodExecutionTag;
            this.Cache.Insert(cacheKey, args.ReturnValue);
        }
 
        protected static string GenerateCacheKey(MethodExecutionArgs args)
        {
            StringBuilder stringBuilder = new StringBuilder();
 
            for (int i = 0; i < args.Arguments.Count; i++)
            {
                if (i > 0)
                {
                    stringBuilder.Append("|");
                }
 
                stringBuilder.AppendFormat(
                    "{0}_{1}",
                    args.Method.GetParameters()[i].Name,
                    args.Arguments.GetArgument(i) ?? "null");
            }
 
            return stringBuilder.ToString();
        }
    }
}

Tags | ,

Vortrag zu AOP bei der .NET User Group Niederrhein

On 07, Apr 2012 | Ein Kommentar | inAOP | vonJohannes Hoppe

Als Entwickler sind wir täglich bemüht hochwertigen und sauberen Code zu produzieren. Für viele Probleme kennen wir bewährte Patterns und Vorgehensweisen. Doch manche Belange – wie etwa Logging, Exception Handling, Validierung oder Caching – liegen schnell unsauber verstreut im gesamten Projekt herum.

Bei dem Treffen der .NET Usergroup Niederrhein spreche ich von meiner Sicht über Clean-Code und die Grenzen von objektorientierter Programmierung. Anhand praktischer Bespiele zeige ich, wie man mit dem AOP-Framework Postsharp elegante Modularisierungsansätze erhält.

Der Vortrag richtet sich an interessierte Einsteiger in das Thema AOP mit .NET.
Sofern bereits Postsharp auf dem Laptop installiert ist, können alle Beispiele Anhand der ASP.NET MVC Demo-Applikation WebNoteAOP nachvollzogen werden.

Tags | , ,

PostSharp MVP

On 28, Okt 2011 | Keine Kommentare | inAOP | vonJohannes Hoppe

In 2011 I talked and blogged several times about Aspect Oriented Programming (AOP) with .NET and PostSharp.
I’m pleasantly amazed that SharpCrapfters rewarded me with the title:

PostSharp MVP

My blog was a bit pall in last time. That’s mainly because I was rushing from one project to the next one! However, I’m planning to retain that title with some new stuff for you! :-)

Tags |

[GERMAN] AOP @ .NET Usergroup Rhein-Neckar – Downloads

On 27, Jun 2011 | Ein Kommentar | inAOP | vonJohannes Hoppe

Hier sind die Folien sowie die Beispiel-Anwendung, welche ich während des Vortrags verwende:


Downloads:

 

Tags | , ,

[GERMAN] 8. Treffen der .NET Usergroup Rhein-Neckar am 27.06.2011

On 16, Jun 2011 | 3 Kommentare | inAOP | vonJohannes Hoppe

Als Entwickler sind wir täglich bemüht hochwertigen und sauberen Code zu produzieren. Für viele Probleme kennen wir bewährte Patterns und Vorgehensweisen. Doch manche Belange – wie etwa Logging, Exception Handling, Validierung oder Caching – liegen schnell unsauber verstreut im gesamten Projekt herum.

Bei dem 8. Treffen der .NET Usergroup Rhein-Neckar spreche ich von meiner Sicht über Clean-Code und die Grenzen von objektorientierter Programmierung. Anhand praktischer Bespiele zeige ich, wie man mit dem AOP-Framework Postsharp elegante Modularisierungsansätze erhält.

Der Vortrag richtet sich an interessierte Einsteiger in das AOP mit .NET.
Sofern bereits Postsharp auf dem Laptop installiert ist, können alle Beispiele Anhand der ASP.NET MVC Demo-Applikation WebNoteAOP nachvollzogen werden.

Tags | , ,

[GERMAN] VSone: AOP-Präsentation am 17.02.2011 in Unterschleißheim/München

On 09, Feb 2011 | 4 Kommentare | inAOP | vonJohannes Hoppe

Wenn Sie Teilnehmer der VSone sind,
dann lade ich sie herzlich zu meiner Session ein:

  • am Do. 17. Februar 2011, 15:15 Uhr
  • Track 6
  • Thema: Aspektorientierte
    Programmierung (AOP) mit .NET

SharpCrafters  (die Entwickler vom AOP-Framework PostSharp) haben in Begleitung zur Session ein interessantes Interview mit mir geführt!

Der Vortrag richtet sich an alle AOP-Interessierten und wird einen theoretischen u. praktischen (Live-Coding) Anteil beinhalten.

Zunächst werde ich über Clean Code und die Grenzen von OOP sprechen. Ich zeige, dass Nicht-Funktionale Anforderungen (Cross-Cutting Concerns) neue Ansätze verlangen! Anschließend demonstriere ich die Anwendung von Aspekten für Exception Handling, Logging, Validierung & Caching.

Tags | ,

Unit Tests – The Rent Is Too Damn High

On 06, Feb 2011 | 14 Kommentare | inAOP | vonJohannes Hoppe

Faking System.DateTime.Now

For sure: The rent is too damn high!

And if we are writing Unit Tests, we are often paying a damn high price, too! Let’s look at a inconspicuous property that every .NET programmer is using:

System.DateTime.Now

Getting the current time is really easy. But how can we mock that statement for our tests?!

Solution 1

The first solution would be the usage of our favorite dependency injection framework. We would write a wrapper for DateTime.Now and produce an interface like this:

public interface IDateTime
{
    DateTime Now { get; }
}

Tags | ,

19

Jan
2011

7 Kommentare

inAOP

vonJohannes Hoppe

FindStackOverlowAttribute vs. StackOverlowException

On 19, Jan 2011 | 7 Kommentare | inAOP | vonJohannes Hoppe

StackOverlowExceptions caused by recursive calls are evil bugs.

While developing on your local machine you have a high chance to jump right into the buggy line of code by attaching Visual Studio to the process. I’m talking about ASP.NET websites, so in my case it’s the w3wp.exe process.

But as soon as your code goes live your debugging possibilities are limited. Of course, you can do remote debugging with Msvsmon.exe, but you still need to know where to look at.* It’s a fact: Software-Bugs successfully hide themselves from developers. So as long as you hunt them, they won’t appear. Instead they like it to scare principals or end customers. For obvious reasons these peoples won’t provide you with a Strack Trace that could help you.

Tags | ,

Unity Application Block: Event Broker with ASP.NET MVC

For my colleagues at work I evaluated the Simple Event Broker from the Patterns and Practices team. In my opinion this extension is a very valuable piece of software!

To learn more about the Event Broker, you should read:

I made a small sample solution, based on my “WebNoteMvc” project.

The scenario is easy: I want my repositories (or services) to be loosely coupled. In my database foreign references are used. So before I delete data from one repository other repositories should get a notice. The related repositories are now forced to delete their own related data from the DB to keep the data integrity.

Tags |