Technical articles on AI agents, Azure, .NET, architecture, and EV charging systems from Sydney.

Category: .NET & C# Page 2 of 7

Dotnet general

Automapper – Dynamic and Generic Mapping

In Automapper, we normally have 1 to 1 mapping defined but I have a case whereas the incoming stream as a json payload which then I cast it as a dynamic (using JObject parse) and in one of the property within the payload it defined which object that it needs to cast into. Lets take a look at the sample below

Input
Json payload to create a city

[code language=”javascript”]
{
"requestId": "C4910016-C30D-415C-89D3-D08D724429A6",
"messageType": "CITY_CREATED",
"categoryName": "categoryA",
"metadata": {
"city": "sydney",
"state": "NSW",
"postcode": "2000",
"country": "australia"
}
}
[/code]

at the same time we can also have a Json payload to create a staff

[code language=”javascript”]
{
"requestId":"C4910016-C30D-415C-89D3-D08D724429A6",
"messageType": "STAFF_CREATED",
"categoryName": "categoryB",
"staffDetail": {
"name": "fransiscus",
"dateOfBirth": "01/01/1950"
},
"location" : {
"cityId" : "1"
}
}
[/code]

So what we are doing in here, all the message will go into payload property (it can contain any object) and we add some extra information/header/metadata on the parent level
Desired Outputs

[code language=”javascript”]
{
"messageType": "CITY_CREATED",
"payload": {
"city": "sydney",
"state": "NSW",
"postcode": "2000",
"country": "australia"
},
"provider": "abc",
"providerRequestId": "C4910016-C30D-415C-89D3-D08D724429A6",
"receivedAt": "2015-09-30T23:53:58.6118521Z",
"lastUpdated": "2015-09-30T23:53:58.6128283Z",
"lastUpdater": "Transformer",
"attempt": 0
}
[/code]

[code language=”javascript”]
{
"messageType": "STAFF_CREATED",
"payload": {
"staffName": "fransiscus",
"dateOfBirth": "01/01/1950",
"cityId": "1"
},
"provider": "abc",
"providerRequestId": "C4910016-C30D-415C-89D3-D08D724429A6",
"receivedAt": "2015-09-30T23:53:58.6118521Z",
"lastUpdated": "2015-09-30T23:53:58.6128283Z",
"lastUpdater": "Transformer",
"attempt": 0
}
[/code]

To map this to a concrete class 1:1 mapping is straight forward and easy. The problem here is that the “messageType” is the one that decided which object that it should be

Automapper Configuration:

1. POCO object

abstract class that stores all the metadata

[code language=”csharp”]
public abstract class Metadata
{
public string MessageType { get; set; }

public string Provider { get; set; }

public string ProviderRequestId { get; set; }

public DateTime ReceivedAt { get; set; }

public DateTime LastUpdated { get; set; }

public string LastUpdater { get; set; }

public int Attempt { get; set; }

public List<string> Errors { get; set; }
}
[/code]

[code language=”csharp”]
public class City
{
public string CityName { get; set; }
public string State { get; set; }
public string PostCode { get; set; }
public string Country { get; set; }
}
[/code]

[code language=”csharp”]
public class StaffDetail
{
public string Name { get; set; }
public string DateOfBirth { get; set; }
public int CityId { get; set; }
}
[/code]

[code language=”csharp”]
public class Message<T> : Metadata where T : class
{
public T Payload { get; set; }
}
[/code]

2. Lets create a TypeConverter for the base class which is Metadata and from this converter it will return the derived class

[code language=”csharp”]
public class MetadataTypeConverter : TypeConverter<dynamic, Metadata>
{
protected override Metadata ConvertCore(dynamic source)
{
Metadata metadata;

var type = (string)source.messageType.Value;

switch (type)
{
case "STAFF_CREATED":
metadata = new Message<StaffDetail> { Payload = Mapper.Map<dynamic, StaffDetail>(source) };
break;
case "CITY_CREATED":
metadata = new Message<City> { Payload = Mapper.Map<dynamic, City>(source) };
break;

default: throw new Exception(string.Format("no mapping defined for {0}", source.messageType.Value));
}

metadata.ProviderRequestId = source.requestId;
metadata.Topic = string.Format("{0}.{1}.pregame",
producerTopicName,
source.categoryName ?? source.competition.categoryName);
metadata.Provider = "My Provider";
metadata.MessageType = source.messageType;
metadata.ReceivedAt = DateTime.UtcNow;
metadata.LastUpdated = DateTime.UtcNow;
metadata.LastUpdater = "Transformer";
metadata.Attempt = 0;

return metadata;
}
}
[/code]

3. Lets create a TypeConverter for the derived class which are Staff and City

[code language=”csharp”]
public class CityTypeConverter : TypeConverter<dynamic, City>
{
protected override City ConvertCore(dynamic source)
{
City city = new City();
city.CityName = source.metadata.city;
city.State = source.metadata.state;
city.Postcode = source.metadata.postcode;
city.Country = source.metadata.country;

return city;
}
}
[/code]

[code language=”csharp”]
public class StaffDetailTypeConverter : TypeConverter<dynamic, StaffDetail>
{
protected override StaffDetail ConvertCore(dynamic source)
{
StaffDetail staffdetail = new StaffDetail();
staffdetail.Name = source.staffDetail.name;
staffdetail.DateOfBirth = source.staffDetail.dateOfBirth;
staffdetail.CityId = source.location.cityId;

return staffdetail;
}
}
[/code]

3. Define the Automapper mapping in the configuration

[code language=”csharp”]
public class WhafflMessageMapping : Profile
{
public override string ProfileName
{
get
{
return this.GetType().Name;
}
}

protected override void Configure()
{
this.CreateMap()
.ConvertUsing(new MetadataTypeConverter());

this.CreateMap()
.ConvertUsing(new StaffDetailTypeConverter());

this.CreateMap()
.ConvertUsing(new CityTypeConverter());
}

private Metadata BuildWhafflMessage(dynamic context)
{
var type = ((string)context.messageType.Value);

switch (type)
{
case "STAFF_CREATED":
return new Message { Payload = Mapper.Map(context) };
case "CITY_CREATED:
return new Message { Payload = Mapper.Map(context) };

default: throw new Exception(string.Format("no mapping defined for {0}", context.messageType.Value));
}

}
}
[/code]

401 Unauthorized – WebRequest

I got this nasty 401 unauthorized error from my code all of sudden, I don’t really know why and what’s causing it. I used Fiddler as a proxy to see the request header and all of sudden it works but then removing the proxy again brings back the 401!!!

So after googling for a while i found something interesting about browser was requesting for authentication level etc therefore even if you pass the basic security header then it will just simply ignore it. So I played around with the code below and it fixes my issue

WebRequest request = WebRequest.Create(source);
request.AuthenticationLevel = System.Net.Security.AuthenticationLevel.MutualAuthRequested;

Penetration Testing Security Tool

There are few applications/tools out there that can be used to test the security of your application. Check below

Contrast
http://www.contrastsecurity.com/

Burp
https://portswigger.net/burp/

Zap – Free
https://www.owasp.org/index.php/OWASP_Zed_Attack_Proxy_Project

Action Filter in WebApi 2

Its been a while I haven’t blogged for sometime. To create an action filter in Web Api 2 and return the response directly you can use the code below

public class StepUpAttribute : ActionFilterAttribute
{
public IUserFactory CurrentUser { get; set; }

public override void OnActionExecuting(HttpActionContext filterContext)
{
if (CurrentUser.IsSteppedUp)
return;

// stop request process and return
filterContext.Response = filterContext.Request.CreateResponse(HttpStatusCode.OK,
ErrorResponseFactory.FromUnsafeActionDetectedResponse(),
filterContext.ControllerContext.Configuration.Formatters.JsonFormatter);

}
}

Replace Invisible Characters – Control Chars

You can use this function to replace the invisible chars

Regex.Replace(s, @"[^\x20-\x7F]", "");

Camel Case for Web Api 2

To convert your DTO to become Camel Case, you can use the code below

//Camel Case settings
var settings = GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings;
settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
settings.Formatting = Formatting.Indented;

Exporting Excel to XML: A mapped element’s relationship with other elements cannot be preserved

I have an Excel file that need to be exported into XML. I have a few files to be converted. One of them was complaining when I’m about to export it to XML and it throws an error of "A mapped element’s relationship with other elements cannot be preserved". Spend quite a few hours try to google it out and fix it but with no luck. So what I did to resolve this issue "Convert the excel into CSV and then open the CSV with Excel and applied my XSD and export it to XML again and it works fine!!"

Fusion Log – Assembly Logging

Another helpful debugging tool that can be used is FusionLog – it is already installed in your machine by default and what this tool does is basically logging and telling us where the assembly is loaded from either local or GAC or some other location and at the same time it tells you it couldn’t locate the assembly

-First create a folder called “FusionLog” on C drive or any location with any name

-Open your Regedit to add the key below

HKEY_LOCAL_MACHINESOFTWAREMicrosoftFusion

Add:

DWORD ForceLog set value to 1

DWORD LogFailures set value to 1

DWORD LogResourceBinds set value to 1

String LogPath set value to folder for logs (e.g. C:FusionLog)

Make sure you include the backslash after the folder name and that the Folder exists.

-Restart your computer

-Run your application

-Look the assembly name from c:fusionlog

-Open the file and it will tell you where the assembly is loaded from

REST API Versioning

There are a couple of ways in versioning your API

1. Through REST URL . domain.com/v1/Customers, domain.com/v2/Customers

2. Through HTTP Header – add the version as part of Content-type

3. Add the version on the REST object itself as one of the attribute/property

A few excellent articles:

http://stackoverflow.com/questions/389169/best-practices-for-api-versioning
http://codebetter.com/howarddierking/2012/11/09/versioning-restful-services/

Behavior Driven Development – BDD .NET

To me it looks like testing end to end scenario instead of modular function. A unit test might pass but it might fail or behaving differently when we start put into different context

What it is?

In software engineering, behavior-driven development (abbreviated BDD) is a software development process based on test-driven development (TDD).[Behavior-driven development combines the general techniques and principles of TDD with ideas from domain-driven design and object-oriented analysis and design to provide software developers and business analysts with shared tools and a shared process to collaborate on software development, with the aim of delivering “software that matters”.

Behavior-driven development was developed by Dan North as a response to the issues encountered teaching test-driven development:

Where to start in the process
What to test and what not to test
How much to test in one go
What to call the tests
How to understand why a test fails

At the heart of BDD is a rethinking of the approach to unit testing and acceptance testing that North came up with while dealing with these issues. For example, he proposes that unit test names be whole sentences starting with the word “should” and should be written in order of business value. Acceptance tests should be written using the standard agile framework of a User story: “As a [role] I want [feature] so that [benefit]”. Acceptance criteria should be written in terms of scenarios and implemented as classes: Given [initial context], when [event occurs], then [ensure some outcomes].

Framework .NET

http://nspec.org/
http://www.specflow.org/

Page 2 of 7

Powered by WordPress & Theme by Anders Norén