Memory dumps of a developer

Articles and tutorials on .NET Core, ASP.NET MVC, Kendo UI, Windows 10, Windows Mobile, Orchard

  • Getting Started With ASP.NET Web API 2

     

    Recently Microsoft revamped the Web stack and now it has become a unified framework for writing server side web applications and APIs. One of the major change is renaming ASP.NET 5 to ASP.NET Core 1.0. There was considerable amount of confusion between ASP.NET 4.6 and ASP.NET 5, since ASP.NET 5 is a significant change from the past they decided to adopt a completely new name for it.

    ASP.NET MVC 6 is now part of ASP.NET Core and it’s a completely unified framework now.In the earlier version there was an WebApi framework which has got some code from the MVC framework and it was making life difficult for the developers at Microsoft. If they made some changes in one area then they needed to make the same in other area too there by maintaining it became a difficult task. So in MVC 6 they merged both these to create a unified one and takes a simple approach for developing web apps and API.

    Let’s see how we can create a new Web API using MVC 6.

    I am using Visual Studio Community 2015 with Update 1 for this post and depending on your installation, the screens and options may vary. Visual Studio Community 2015 a free version of Visual Studio and is available for download from here.

    Create a new project using the ASP.NET Web Application from the New Project Dialog box

    1


  • AutoMapper - NullSubstitution

    Sometimes you may want to provide default values if there are null values for a member in the source. Automapper has got a NullSubstitute method in configuration to specify a value for a memeber having null value.

    Syntax

    NullSubstitute("<provide default value for null>"

    Usage

    var config = new MapperConfiguration(cfg =>
                    {
    
                        cfg.CreateMap<ModelData, ViewModel>()
    						.ForMember(dest => dest.Name, opt => opt.NullSubstitute("Default Name"));
                    });
    

  • AutoMapper - Dynamic & ExpandoObjects

    Automapper supports dynamic and ExpandoObjects and will map to/from without any additional configuration. In the example given below, mapping is done from a ExpandoObject(viewModel) to an instance of ModelData class(model)

    The members for the source are dynamically created and AutoMapper maps it properly without any explicit configuration. You can see that which create the configuration object have an empty lambda expression.

    using System;
    using AutoMapper;
    using System.Dynamic;
    
    namespace AutoMapperSamples.Configuration
    {
        namespace AutoMapperSample
        {
    
            public class ModelData
            {
                public string Name { get; set; }
                public DateTime StartedOn { get; set; }
    
    
            }
            
            public class TestAutoMapper
            {
    
                public static void Main()
                {
    
                    dynamic viewModel = new ExpandoObject();
                    viewModel.Name = "Bridge Construction";
                    viewModel.StartedOn = DateTime.Now;
                    var config = new MapperConfiguration(cfg => { });
    
                    config.AssertConfigurationIsValid();
    
    
                    var model = new ModelData { StartedOn = DateTime.Now, Name = "Bridge Construction" };
    
                    model = config.CreateMapper().Map<modeldata>(viewModel);
                    Console.WriteLine("\nName " + model.Name);
                    Console.WriteLine("\nStart Date " + model.StartedOn);
    
    
    
                    Console.ReadKey();
                }
            }
        }
    }
    

    Output


  • AutoMapper - Property/Field Filtering

    By default Automapper will try to map not only public properties but also public fields found in source and destination.

    using System;
    using AutoMapper;
    
    namespace AutoMapperSamples.Configuration
    {
        namespace AutoMapperSample
        {
            
            public class ModelData
            {
                public string Name { get; set; }
                public DateTime StartedOn { get; set; }
    
                public string Location;
            }
    
    
    
            public class ViewModel
            {
                public string Name { get; set; }
                public DateTime StartedOn { get; set; }
    
                public string Location;
            }
    
    
            public class TestAutoMapper
            {
    
                public static void Main()
                {
                    var config = new MapperConfiguration(cfg =>
                    {
                        cfg.CreateMap<ModelData, ViewModel>();
                    });
    
                    config.AssertConfigurationIsValid();
    
                    var model = new ModelData { StartedOn = DateTime.Now, Name = "Bridge Construction", Location = "India" };
    
                    var viewModel = config.CreateMapper().Map<viewmodel>(model);
                    Console.WriteLine("\nName " + viewModel.Name);
                    Console.WriteLine("\nStart Date " + viewModel.StartedOn);
                    Console.WriteLine("\nLocation " + viewModel.Location);
    
    
                    Console.ReadKey();
                }
            }
        }
    }
    

    In this example Location is a public field and it will also get mapped automatically.

    Output


  • AutoMapper - Working with prefix and postfix

    Another configuration option we have is for recognizing prefixes or postfixes in the member names. In some scenarios we may have a prefix or postfix for all the properties in the source model and it's not there in the destination model. This cannot be handled by the default mapping rules in AutoMapper. For that we have RecognizePrefixes and RecognizePostfixes method in the MapperConfiguration class where we can specify postfix or prefix. If AutoMapper finds the prefix/postfix in the members in source instanace then it will be discarded and if it found a match in the destination instance then maps correctly.

    Syntax - Prefix

    RecognizePrefixes("<prefix name>");

    Syntax - Postfix

    RecognizePrefixes("<postfix name>");

     

    Sample Code - Prefix

    var config = new MapperConfiguration(cfg =>
    {
         cfg.RecognizePrefixes("Work");
         cfg.CreateMap<ModelData, ViewModel>();
    });
    

    Sample Code - Postfix

    var config = new MapperConfiguration(cfg =>
    {

    cfg.RecognizePostfixes("Work");
    cfg.CreateMap<ModelData, ViewModel>();
    });

  • AutoMapper - Replacing Member Names

    Another feature available in AutoMapper is the ability to replace characters or the complete name in the source member name while doing the mapping. This will become helpful when you deal with member names having different spelling or some special characters in it. It's normally done during the configuration for mapping and needs to do only once.

    Syntax 

    ReplaceMemberName("<orignial member name>","<matching property name>");

     var config = new MapperConfiguration(cfg =>
    {
    cfg.ReplaceMemberName("StartedOn", "Started_On");
    cfg.ReplaceMemberName("Name", "FirstName");

    cfg.CreateMap<ModelData, ViewModel>();
    });

    Here we are doing couple of replacements, one for adding a underscore to Started_On property and second one for completely using a new name for the property. One thing to note here is that you should specify the replacements before the CreateMap statement otherwise it will you invalid mapping exception at runtime.


  • AutoMapper - Profiles

    Profiles is another great feature from AutoMapper which helps you to mappings and it comes in handy when we need to apply different mapping rules for the same object. Let's take the case of a DateTime field being mapped to a String field and the requirements can be different based on the business requirements .

    In the below example I have a source model which has got a DateTime field and the destination model with a string property. In one instance I needs to show the data in mm/dd/yyyy format and another case I need to show only month and year.

    using System;
    using AutoMapper;
    
    namespace AutoMapperSamples.Configuration
    {
        namespace Profiles
        {
            public class DateTimeProfile1 : Profile
            {
                protected override void Configure()
                {
                    CreateMap<DateTime, String>().ConvertUsing<DateTimeToString1TypeConverter>();
                }
            }
    
            public class DateTimeProfile2 : Profile
            {
                protected override void Configure()
                {
                    CreateMap<DateTime, String>().ConvertUsing<DateTimeToString2TypeConverter>();
                }
    
            }
    
            public class DateTimeToString1TypeConverter : ITypeConverter<DateTime, String>
            {
                public string Convert(ResolutionContext context)
                {
                    return DateTime.Parse(((object)context.SourceValue).ToString()).ToString("dd/MMM/yyyy");
                }
            }
    
            public class DateTimeToString2TypeConverter : ITypeConverter<DateTime, String>
            {
                public string Convert(ResolutionContext context)
                {
                    return DateTime.Parse(((object)context.SourceValue).ToString()).ToString("MMMM - yyyy");
                }
            }
    
            public class Model1
            {
                public DateTime StartedOn { get; set; }
            }
    
            
    
            public class ViewModel
            {
                public String StartedOn { get; set; }
            }
    
    
            public class TestProfile
            {
    
                public static void Main()
                {
                    var config1 = new MapperConfiguration(cfg =>
                    {
                        cfg.AddProfile<DateTimeProfile1>();
                        cfg.CreateMap<Model1, ViewModel>();
                    });
    
                    var config2 = new MapperConfiguration(cfg1 =>
                    {
                        cfg1.AddProfile<DateTimeProfile2>();
                        cfg1.CreateMap<Model1, ViewModel>();
                    });
    
                    var model1 = new Model1{ StartedOn = DateTime.Now};
                    
                    var viewModel1 = config1.CreateMapper().Map<ViewModel>(model1);
                    Console.WriteLine(viewModel1.StartedOn);
                    viewModel2 = config2.CreateMapper().Map< ViewModel>(model1);
                    Console.WriteLine(viewModel2.StartedOn);
    
                    
                    Console.WriteLine(viewModel2.StartedOn);
                    Console.ReadKey();
                }
            }
        }
    }

  • AutoMapper - Custom Type Converters

    Another scenario where AutoMapper cannot do default mapping is when the types of the properties in both source and destination classes are different. Even though the names are same, there is no way AutoMapper can proceed in cases such as from String to Int32 or DateTime. If try to do mapping then AutoMapper will throw exception at the time of configuration or at the time of mapping itself.

    This problem can be solved using the Custom Type Converters available in AutoMapper. We can create custom type converters by extending the ITypeConverter interface and provide the logic needed for converting the source to the destination


  • AutoMapper - Updating Instances

    So far in this series we were dealing with mappings only with new instances of the source and destination classes. Automapper can also be used to do mapping for existing instances also, meaning instances that have data already in it before mapping. Typical example of this sceanario happens when we edit information, at that time our source will be the edited data and the destination data will be one stored in the data store.


  • AutoMapper - Projections

    So far we saw how to do mapping between simple objects that have same name and same type using AutoMapper. In the last post, I have explained the use of MapFrom method to do a custom mapping by concatnating values from two properties. In some case we may need to map properties between two fields with different property names and AutoMapper will be unable to do the mapping by default. Here also we are going to use the MapFrom method to determin which field needs to be picked up from the source for mapping the value in the destination object.