C-sharp Cache Image returned from asp.net webapi

Hey folks, well recently i developed some web service that return image as file from a web service method. User pass us a URL like below:

http://www.abc.com/api/downloadfile?fileid=100&type=user

This return image of user with id=100

Lets say we list 100 users on a page, and bind this URL to image src attribute, whenever the page loads, it will make 110 calls to the service and page stays busy until all images are loaded.

To tackle this, all i did was below HIGHLIGHTED IN BOLD:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
        [HttpGet]
        [EnableCors(origins: "*", headers: "*", methods: "get", PreflightMaxAge = 600)]
        [Route("DownloadFile")]
        [Microsoft.AspNetCore.Mvc.ResponseCache(Duration = 259200)]
        public async Task<httpresponsemessage> DownloadFile(int FileId)
        {
            var result = Task.Factory.StartNew(() =>
            {
                var regact = DownloadFileContent(FileId); //returns us the bytes of file based on Id provided.
                return regact;
            });
 
            await result;
 
            if (result.Result == null)
            {
                HttpResponseMessage resultNoFile = new HttpResponseMessage(HttpStatusCode.NoContent);
                return resultNoFile;
            }
            else
            {
                byte[] fileContent = Convert.FromBase64String(result.Result.DocumentBody);
 
                HttpResponseMessage results = new HttpResponseMessage(HttpStatusCode.OK);
                var stream = new System.IO.MemoryStream(fileContent);
                results.Content = new StreamContent(stream);
                results.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(result.Result.MimeType);
 
                results.Headers.CacheControl = new CacheControlHeaderValue
                {
                    Public = true,
                    MaxAge = TimeSpan.FromSeconds(259200)
                };
 
                results.Headers.Add("Cache-Control", "public, max-age=259200");
                return results;
            }
        }
</httpresponsemessage>

Added following attribute to method

[Microsoft.AspNetCore.Mvc.ResponseCache(Duration = 259200)]

and following chunk into the code block.

results.Headers.CacheControl = new CacheControlHeaderValue
{
Public = true,
MaxAge = TimeSpan.FromSeconds(259200)
};

results.Headers.Add(“Cache-Control”, “public, max-age=259200”);

After this first time we load images from service and next time from disk cache.

DateTime Start and End of Day Extension Methods

Another quick post with some useful extension methods for the System.DateTime struct. I’ve been working a lot with the DateTime type over the past couple of weeks. One particular use case has been to pass a “start” and an “end” DateTime to some SQL Server stored procedure. The stored procedure then returns some data based on some timestamp field that falls between the start and end DateTime’s passed in.

In the code I was maintaining, the previous developer had created a DateTime value using DateTime.Now, which returns a DateTime with the time part also populated to the current system time. So when passing this DateTime to the stored proc as a “start” DateTime, the proc was looking from the time-part onwards on the specific day represented by the DateTime. Likewise, when using a similarly created DateTime for the “end” DateTime, the stored proc only returned rows upto the time-part. This was undesired behaviour because the original intention was to retrieve all of the records between two specified days (inclusive of the start and end days).

I decided to tackle this at the application-level. This was mainly to keep the stored procedure flexible so that it can continue to handle retrieval of records at the more granular time level if required. I decided to implement this functionality by adding two extension methods on DateTime, namely, ResetTimeToStartOfDay and ResetTimeToEndOfDay. These return new DateTime values with the time part appropriately set. The idea is to call ResetTimeToStartOfDay on the “start” DateTime and ensure that the returned DateTime is sent to the stored procedure. Likewise, call ResetTimeToEndOfDay on the “end” DateTime. I’ve included the implementation of the two methods below – very simple but useful to have in your library.

public static DateTime ResetTimeToStartOfDay(this DateTime dateTime)
{
   return new DateTime(
      dateTime.Year, 
      dateTime.Month, 
      dateTime.Day, 
      0, 0, 0, 0);
}

public static DateTime ResetTimeToEndOfDay(this DateTime dateTime)
{
   return new DateTime(
      dateTime.Year, 
      dateTime.Month, 
      dateTime.Day, 
      23, 59, 59, 999);
}

The Generic Lazy Type

Lazy<T> is a monad type that was introduced in .NET 4 and provides an alternative mechanism for implementing lazy initialisation. Lazy initialisation is where you intentionally delay the creation of an object that is expensive to create.

You would typically want to use lazy initialisation in scenarios where the object (which is expensive to create) may or may not be used in the execution flow of your program. In this case, it makes sense to only initialise the object if it is required. One reliable place where you may have seen the lazy initialisation tactic being used is in an implementation of a singleton class – which will have a method or property that returns the singleton instance, for example:

public MySingletonClass GetInstance()
{
    if (_singleton == null)
        _singleton = new MySingletonClass();

    return _singleton;
}

The logic before the return statement is an example of lazy initialisation, where the singleton is only instantiated the first time GetInstance is called and never before it. Subsequent calls to GetInstance will then also return the same instance, hence we have an implementation of the singleton design pattern. In this particular case, we don’t know if MySingletonClass is expensive to create, and we don’t particularly care as we’re using lazy initialisation to prevent multiple instances of MySingletonClass from being created.

If we now go back to the mainstream use for lazy initialisation, where we want to delay instantiation of expensive-to-create objects, you could adopt the pattern above where you conditionally instantiate an instance of an object. However, since .NET 4, you have an alternative option with the use of Lazy<T>. An instance of Lazy<T> wraps around your expensive-to-create object, you pass this instance around in your code and when ever the underlying expensive-to-create object is required, you can call the Value property on Lazy<T> which will instantiate the object and return it to you.

The following contrived example should make it more clear. Imagine you have a Customer class and an Order class. A single customer can have many orders, so we’ll make use of composition and have the Customer class support a List of Order objects. The Customer class has one constructor that accepts a customer ID. Using the supplied ID, the constructor then goes and retrieves the orders for the customer from an order repository. Note that in reality your entity classes will usually be dumb and just support getter and setter properties and it’ll be the responsibility of your data access layer/framework (like Entity Framework) to instantiate and populate your entities appropriately. Continuing with our contrived example, our initial attempt may therefore look like:

public class Order { }

public class Customer
{
    public int Id { get; private set; }
    public string Name { get; set; }
    public List<Order> Orders { get; set; }

    public Customer(int id)
    {
        Id = id;
        Name = "Ms Foo Bar";

        // Simulate getting lots of orders from an
        // order repository
        Orders = Enumerable
            .Repeat<Order>(new Order(), 200)
                .ToList();
    }

    public override string ToString()
    {
        return string.Format(
            "I'm customer with id {0}", Id);
    }
}

As the code indicates, it would be expensive to instantiate a Customer object if we didn’t require the order information contained within it. This is where you would apply the concept of lazy initialisation. In this case, we’ll make use of the Lazy<T> type. The following code shows how the Customer class would look if we lazily instantiate the Orders list using Lazy<T>.

public class Customer
{
    public int Id { get; private set; }
    public string Name { get; set; }
    public Lazy<List<Order>> Orders { get; set; }

    public Customer(int id)
    {
        Id = id;
        Name = "Ms Foo Bar";

        Orders = new Lazy<List<Order>>(() => {
            // Simulate getting lots of orders from an 
            // order repository 
            return Enumerable
                .Repeat<Order>(new Order(), 200)
                    .ToList();
            }
        );

        Debug.WriteLine(this);
    }

    public override string ToString()
    {
        return string.Format(
            "I'm customer with id {0}", Id);
    }
}

As you can see, the constructor of the Customer class instantiates an instance of Lazy<T> that wraps around the List of Order objects. The constructor of Lazy<T> is passed a lambda expression that expresses what needs to be returned when the list of orders is requested for (our expensive logic). Notice I’ve also put a call to Debug.WriteLine so you can observe the output of the following code and see how this behaves.

var customer = new Customer(1);
                       
Debug.WriteLine("Are orders instantiated? {0}", 
    customer.Orders.IsValueCreated);

// Ok, we now want the orders...
var ordersForCustomer = customer.Orders.Value;

Debug.WriteLine("Are orders instantiated? {0}", 
    customer.Orders.IsValueCreated);

Debug.WriteLine("Customer {0} has {1} order(s)", 
    customer.Id, ordersForCustomer.Count);

If you execute the code above using the updated Customer class, you’ll find that instantiating a Customer object is no longer an expensive operation. The output you should see in your debug window is:

I'm customer with id 1
Are orders instantiated? False
Are orders instantiated? True
Customer 1 has 200 order(s)

Notice that when the Customer object was initialised, the runtime executed the constructor logic as expected (verifiable with the ToString output). We then check our Lazy objects IsValueCreated property to ensure it hasn’t yet created an instance of the list and populated it. The property returned False as expected. On the next line, we explicitly call the Value property on the Orders property (our Lazy object) – this forces our lazy object to instantiate. We re-query the IsValueCreated property which now returns True and finally we output the order count to show that the orders have been successfully lazily-loaded.

C# MongoDB Repository Implementation

I recently started a small project with a friend and we opted for MongoDB as our data store. One of the initial tasks was to write a repository class that allowed us to store, retrieve, update and search for entities in MongoDB. In the past, I’ve worked on codebases where there was one repository per entity, it didn’t take long to discover that this resulted in a lot of code duplication across the data layer. So the goal here was to write the repository generically enough so that we only have one implementation that can be reused for any entity within our application. This meant that each entity would have its own MongoDB collection (if you’re not familiar with MongoDB, a collection can be thought of as a table in the relational world – see this page for a comparison).

One of the first steps in this task was to write an interface for the repository – this is in case we decide to use a different data store in the future. A while back, I found a repository interface on the Redmondo blog which covers everything I’d want from a repository, so we’ll use a slightly modified version of that interface (I’ve removed comments for brevity, you can download the code using a link further below and that’ll contain the comments):

public interface IRepository<TEntity> where TEntity : EntityBase
{
bool Insert(TEntity entity);
bool Update(TEntity entity);
bool Delete(TEntity entity);
IList<TEntity>
SearchFor(Expression<Func<TEntity, bool>> predicate);
IList<TEntity> GetAll();
TEntity GetById(Guid id);
}

To paraphrase the code, this is a generic repository interface for an entity of type TEntity that must derive from a base class called EntityBase. The EntityBase class is a very simple abstract class and contains just one property, the identifier property:

/// <summary>
/// A non-instantiable base entity which defines 
/// members available across all entities.
/// </summary>
public abstract class EntityBase
{
public Guid Id { get; set; }
}

The idea is for any entity that we want to manage in our data store, that entity must derive from EntityBase. So the infrastructure is all in place for our “MongoDbRepository”. I used the official 10gen MongoDB C# driver (available as a NuGet package) and arrived at the following repository implementation:

/// <summary>
/// A MongoDB repository. Maps to a collection with the same name
/// as type TEntity.
/// </summary>
/// <typeparam name=”T”>Entity type for this repository</typeparam>
public class MongoDbRepository<TEntity> :
IRepository<TEntity> where
TEntity : EntityBase
{
private MongoDatabase database;
private MongoCollection<TEntity> collection;

public MongoDbRepository()
{
GetDatabase();
GetCollection();
}

public bool Insert(TEntity entity)
{
entity.Id = Guid.NewGuid();
return collection.Insert(entity).Ok;
}

public bool Update(TEntity entity)
{
if (entity.Id == null)
return Insert(entity);

return collection
.Save(entity)
.DocumentsAffected > 0;
}

public bool Delete(TEntity entity)
{
return collection
.Remove(Query.EQ(“_id”, entity.Id))
.DocumentsAffected > 0;
}

public IList<TEntity>
SearchFor(Expression<Func<TEntity, bool>> predicate)
{
return collection
.AsQueryable<TEntity>()
.Where(predicate.Compile())
.ToList();
}

public IList<TEntity> GetAll()
{
return collection.FindAllAs<TEntity>().ToList();
}

public TEntity GetById(Guid id)
{
return collection.FindOneByIdAs<TEntity>(id);
}

#region Private Helper Methods
private void GetDatabase()
{
var client = new MongoClient(GetConnectionString());
var server = client.GetServer();

database = server.GetDatabase(GetDatabaseName());
}

private string GetConnectionString()
{
return ConfigurationManager
.AppSettings
.Get(“MongoDbConnectionString”)
.Replace(“{DB_NAME}”, GetDatabaseName());
}

private string GetDatabaseName()
{
return ConfigurationManager
.AppSettings
.Get(“MongoDbDatabaseName”);
}

private void GetCollection()
{
collection = database
.GetCollection<TEntity>(typeof(TEntity).Name);
}
#endregion
}

In case you’re interested, a while ago I wrote a separate blog post on how to perform CRUD operations against MongoDB using the C# driver. To use the repository implementation, you’ll need two application configuration settings defined – one that stores the name of the MongoDB database and the other that contains the MongoDB connection string (with a placeholder for the database name). You should have something like:

<appSettings>
<add key=“MongoDbDatabaseName” value=“MyCarsDatabase” />
<add key=“MongoDbConnectionString”
value=“mongodb://localhost/{DB_NAME}?safe=true” />
</appSettings>

 

CSharp – ExpandoObject Stringified

I had a requirement to output some data as part of a number of pages in an e-commerce site. This data would change from page to page and typically get richer as a user would go through an order path in the application. The data needed to be in JSON format and was going to be used by the marketing guys to help track information about user behaviour across the order process. The data was also subject to change regularly depending on what the marketing team wanted to track. In short, I had to construct a JSON string on the server side in C#.

I had seen something like this done before where a StringBuilder was used to construct a large JSON string which was then pushed out in the response with the rest of the page markup. This approach seemed messy and difficult to maintain. I did a bit of research on some approaches to constructing a potentially complex and changing JSON object using C# and came across the ExpandoObject class. MSDN has a nice succinct explanation of ExpandoObject:

Represents an object whose members can be dynamically added and removed at run time.

You can find this class in .NET 4 in the System.Dynamic namespace. ExpandoObject lets you effectively “model” an object on the fly with properties that don’t really exist (just like using the ViewBag in ASP.NET MVC). In my case, it saved me from writing a number of classes or complex strings just to hold data that was to be output in page responses. Instead, I could use ExpandoObject and then use a JSON serializer to stringify the object.

The example below shows how easy and flexible it is to use ExpandoObject with the Newtonsoft .NET JSON library (available as a NuGet package):

dynamic orderInfo = new ExpandoObject();

orderInfo.OrderDate = DateTime.Today;

orderInfo.ProductTypesAdded = new List<dynamic>();
orderInfo.ProductTypesAdded.Add(“Radio”);
orderInfo.ProductTypesAdded.Add(“Television”);
orderInfo.ProductTypesAdded.Add(“Recorder”);

orderInfo.ReachedCheckout = true;
orderInfo.PaymentMethod = “Card”;

orderInfo.DeliveryInfo = new ExpandoObject();
orderInfo.DeliveryInfo.Method = “First”;
orderInfo.DeliveryInfo.Country = “UK”;

var json = JsonConvert.SerializeObject(orderInfo);

The resulting JSON is:

{
“OrderDate”:”2013-10-11T00:00:00+01:00″,
“ProductTypesAdded”:[
“Radio”,
“Television”,
“Recorder”
],
“ReachedCheckout”:true,
“PaymentMethod”:”Card”,
“DeliveryInfo”:{
“Method”:”First”,
“Country”:”UK”
}
}

Empty Collections

It is better to return empty collections rather than null when writing methods. The reason being that any code calling your method then doesn’t need to explicitly handle a special null case. Returning an empty collection makes the null check redundant and results in much cleaner method calling code. In C#, the System.Linq.Enumerable class has a useful generic method called Empty. When called with a type parameter, this method returns an empty instance of IEnumerable<T> (where T is your type parameter).

An example use:

public class House
{
public IEnumerable<Person> CurrentOccupants { get; set; }

public House()
{
CurrentOccupants = Enumerable.Empty<Person>();
}
}

I also find that this method of instantiating (or returning) a collection states my intent more clearly than something like:

CurrentOccupants = new List<Person();

The MSDN documentation for Enumerable.Empty states that it caches the returned empty sequence of type TResult – so using this consistently for the same types can give (probably negligible) performance or memory usage advantages.

This pattern also reduces the chances of null reference errors from being raised in calling code. As mentioned above, the calling code then doesn’t need to go through the usual boiler-plate null check code on the returned collection. Naturally, this leads to cleaner code as the calling code can process the collection the same way if it has items or doesn’t have items within it.

CsQuery – JQuery for .NET

I’m currently working on a personal use utility application which requires some web scraping to extract data (from HTML) which can be locally processed by the application. Getting the raw HTML was straightforward enough using the HttpWebRequest and HttpWebResponse classes in the System.Net namespace.

I then reached the point where I had some raw HTML in a string that I needed to parse. After doing a quick search I found CsQuery (available as a NuGet package) which is an open source JQuery port for .NET. I was able to easily extract the data I required from the HTML using the familiar JQuery-like selectors. There is an example code snippet below which shows just how easy it is to use CsQuery.

var html = new StringBuilder();
html.Append(“<html><body>”);
html.Append(“<h1>Hello, world!</h1>”);
html.Append(“<p class=’intro’>This program is using CsQuery.</p>”);
html.Append(“<p id=’author’>CsQuery is a library written by James Treworgy.</p>”);
html.Append(“</body></html>”);var dom = CsQuery.CQ.Create(html.ToString());

// Get the inner text of an element by element name selector
Console.WriteLine(dom[“h1”].Text());

// Get the inner text of an element by class name selector
Console.WriteLine(dom[“.intro”].Text());

// Get the inner text of an element by id selector
Console.WriteLine(dom[“#author”].Text());

// Add a class to an element
dom[“h1”].AddClass(“title”);

// Update the title text using new class in selector
dom[“.title”].Text(“CSQuery – a JQuery port for .NET”);

// Now retrieve the new title by a class selector
Console.WriteLine(dom[“.title”].Text());

// Pause console
Console.ReadLine();

 

CSharp – Zip Compression and Decompression .NET 4 and Earlier

Quick post about a useful third-party zip compression library if you’re working in .NET framework version 4 or earlier.

I had been working on a SQL Server Integration Services (SSIS) package. One of the steps in the package is to decompress a set of zip archives. Unfortunately, .NET script tasks in the SSIS package can only target .NET framework version 4 and earlier. This means that I couldn’t make use of the new zip compression classes introduced in .NET 4.5 (see System.IO.Compression).

Fortunately though, there are a handful of open source .NET zip libraries available. The one I opted for is called DotNetZip. DotNetZip has an intuitive API and is working well with a large number of files (I am decompressing approximately 15,000 archives). The library is available as a NuGet package. The two snippets below show just how easy it is to compress and decompress files using zip.

To compress a file into a zip archive:

using (var zipFile = new ZipFile())
{
// The empty string parameter ensures the file is archived to the 
// root of the archive
zipFile.AddFile(@“C:\Test\Data.txt”string.Empty);
zipFile.Save(@“C:\Test\Data.zip”);
}

To decompress files out of a zip archive:

using (var zipFile = new ZipFile(@“C:\Test\Data.zip”))
{
zipFile.ExtractAll(@“C:\Test\Output”);
}

CSharp How To: Create Text File And Write To It

Continuing with my new C# “how-to” theme, the code snippet below shows how to create a text file and write content to it using the StreamWriter class. Remember to add the “using System.IO;” directive at the top. Note that there is a StreamWriter constructor which supports a Boolean parameter “append” – if you pass true for this parameter and the file already exists, the StreamWriter will append content to the file rather than overwrite the existing content.

const string TextFilePath = @“C:\WriteTest.txt”;

using (StreamWriter writer = new StreamWriter(TextFilePath))
{
writer.WriteLine(“Hello, world”);
writer.WriteLine(“Bye, world”);
}

Csharp How To: Start a Program/Process

To start a program in C#, you can use the Process class. The Process class has a static method called Start which accepts a filename as a parameter. The example below shows how easy it is to start Microsoft Notepad from a C# application. Remember to include the “using System.Diagnostics;” directive at the top.

const string ProgramPath = “Notepad”;

Process.Start(ProgramPath);

Note that if you need to start a program which accepts command line arguments, then you can use an overload of the Start method which accepts a ProcessStartInfo object. The following snippet shows how to open a file within notepad from your C# application.

const string ProgramPath = “Notepad”;

Process.Start(new ProcessStartInfo
{
FileName = ProgramPath,
Arguments = @”C:\WriteTest.txt”
}
);

Csharp CSV Library and HTTP Handlers

A colleague and I was recently looking at some old ASP.NET WebForms code which generated a potentially large CSV string and returned it in a response to a HTTP request. The original code was placed in a standard ASP.NET WebForms page in the OnLoad event handler. As the code was working with the HttpResponse object and writing the CSV directly to the HTTP output stream, we determined that this code was better placed in a HTTP Handler. The primary advantage of using a HTTP handler to generate the file is that we can bypass the unnecessary ASP.NET WebForms page life cycle.

The existing code was using a StringBuilder to generate the CSV string in the page OnLoad event handler. As you may imagine, this looked messy and was a pain to maintain. To abstract the CSV string creation logic, my colleague introduced me to a useful CSV library called LINQ to CSV. The project page link for this library is here and the library is available as a NuGet package.

The LINQ to CSV library enabled us to decorate some properties in a model class with attributes that specify how to output the property in CSV form. The example below (from the library project page) shows how to apply the attributes:

public class Product
{
[CsvColumn(Name = “ProductName”, FieldIndex = 1)]
public string Name { get; set; }
[CsvColumn(FieldIndex = 2, OutputFormat = “dd MMM HH:mm:ss”)]
public DateTime LaunchDate { get; set; }
[CsvColumn(FieldIndex = 3, CanBeNull = false, OutputFormat = “C”)]
public decimal Price { get; set; }
[CsvColumn(FieldIndex = 4)]
public string Country { get; set; }
[CsvColumn(FieldIndex = 5)]
public string Description { get; set; }
}
Once your model class is decorated, you can then use other classes of the library to generate a CSV representation of a collection containing your model instances. This representation can be output to disk as demonstrated in the code example below:

IList products = new List();
products.Add(
new Product
{
Name = “Samung Galaxy S6”,
LaunchDate = DateTime.Today,
Price = 500,
Country = “United Kingdom”,
Description = “This is a Samsung phone product”
}
);

products.Add(
new Product
{
Name = “Apple iPhone 5”,
LaunchDate = DateTime.Today,
Price = 600,
Country = “United States”,
Description = “This is an Apple phone product”
}
);

CsvFileDescription inputFileDescription = new CsvFileDescription();
inputFileDescription.SeparatorChar = ‘,’;
inputFileDescription.FirstLineHasColumnNames = true;

CsvContext csvContext = new CsvContext();
csvContext.Write(products, @”C:\Products.csv”);

Usefully, the CsvContext class of the library also supports an overload to the Write method which accepts a TextWriter stream. Passing a TextWriter stream to this overload results in the library outputing the CSV representation to your stream rather than a file on disk. In our case, we used a StreamWriter that wrote to a MemoryStream. Once the CSV file content was in the MemoryStream instance, we sent the stream contents in the HTTP response from the HTTP handler. The full HTTP handler code is below (using the example product data).

public class ProductsExportHandler : IHttpHandler
{
public bool IsReusable { get { return true; } }

public void ProcessRequest(HttpContext context)
{
context.Response.AddHeader(
“content-disposition”,
“attachment;filename=BulkExport.csv”
);
context.Response.Cache.SetCacheability(HttpCacheability.NoCache);
context.Response.ContentType = “application/vnd.text”;

IList products = new List();
// Add products…

var inputFileDescription = new CsvFileDescription();
inputFileDescription.SeparatorChar = ‘,’;
inputFileDescription.FirstLineHasColumnNames = true;

using (var memoryStream = new MemoryStream())
{
using (var streamWriter = new StreamWriter(memoryStream))
{
var csvContext = new CsvContext();
csvContext.Write(products, streamWriter);

streamWriter.Flush();

context.Response.BinaryWrite(memoryStream.GetBuffer());
}
}
}
}

Azure App Service – Forcefully redirecting from HTTP to HTTPS the easy way!

The easiest, non techie way is to add the ‘Redirect HTTP to HTTPS’ Extension kindly created by Greg Hogan (https://github.com/gregjhogan)

In the Azure Portal, select ‘Extensions’ in the App Service blade

azure-redirect-1

Add a new Extension by clicking on the ‘+Add’ button at the top
Select the ‘Redirect HTTP to HTTPS’ extension from the list given.

azure-redirect-2

Agree to the T&C’s
Wait till it’s installed and then restart the service (which you can find in the ‘Overview’)

After this when you access the website with http or without http/https, it will automatically redirect to https.

Dynamics CRM, set status of activity as Complete/Open using CSharp

In dynamics CRM, Task, phonecalls or any activity can be marked as complete which indicate its status as done.

To programatically, do it from C#, below code is required. Lets first make a generic entity model to be used.

1
2
3
4
5
6
7
8
9
    public class ActivityStatusInputEntity
    {
        public string Email { get; set; }
        public string Password { get; set; }
        public string ActivityId { get; set; }
        public string ActivityType{get;set;} //task, phonecall, meeting ..
        public int StatusCode { get; set; } // 5 if its a tasks, 2 if its a call, 3 if its a meeting
        public int StateCode { get; set; } // 0 to set it as open activity, 1 to make it Completed
    }

StatusCode and StateCode are the major key points here. As we cannot update these fields directly into the entity, we can do this with the SetStateRequest class.

StatusCode: 5 if its a tasks, 2 if its a call, 3 if its a meeting
StateCode: 0 to set it as open activity, 1 to make it Completed

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 
public Response UpdateTaskStatus(ActivityStatusInputEntity activityStatusEntity)
        {
            try
            {
                var crmService = GetCRMService(activityStatusEntity.Email, activityStatusEntity.Password);
                SetStateRequest setStateRequest = new SetStateRequest();
 
                // In my case i'm updating Task Activity
                setStateRequest.EntityMoniker = new EntityReference(activityStatusEntity.ActivityType, new Guid(activityStatusEntity.ActivityId));
 
                // Set the State and Status OptionSet Values.
                setStateRequest.State = new OptionSetValue(taskStatusEntity.StateCode);
                setStateRequest.Status = new OptionSetValue(taskStatusEntity.StatusCode);
 
                // Execute the Response
                SetStateResponse setStateResponse = (SetStateResponse) crmService.Execute(setStateRequest);
                return new Response() {Message = "success"};
            }
            catch (Exception err)
            {
                return new Response() {Message = "failure"};
            }
 
        }

This way we can set status of activities to either complete, or reopen an activity for editing programatically in C#.

Dynamics CRM, Update Task using C#

In dynamics CRM, a task, phone call, meeting are termed as activities performed on an entity. Like if there is an entity “Lead”, under a certain lead there can be multiple activities like tasks, phonecalls, appointments e.t.c

Let us update a task in dynamics CRM created in prior post.

First we will define a task DTO(Data transformation Object) or model

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
public class UpdateTaskEntity
    {        
        public string Id { get; set; }
        public string RegardingObjectName { get; set; }
        public string RegardingObjectId { get; set; }
        public string Email { get; set; }
        public string Password { get; set; }
        public string OwnerId { get; set; }
        public string Subject { get; set; }
        public string Description { get; set; }
        public DateTime ScheduledStart { get; set; }
        public DateTime ScheduledEnd { get; set; }
        public string Priority { get; set; }
        public double Duration { get; set; }
    }

GetCRMService object can be referenced from following post LINK TO PART 1

Property Id represents the Id (guid) of the task
ReferenceObjectId and ReferenceObjectName are important, as they represents the object to which this task will be added under. Like if you are to add a task under a Lead, then type referenceobjectname as “lead” and ReferenceObjectId as Id of the lead entity object.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
public Response AddTask(UpdateTaskEntity task)
        {
            try
            {
                var crmService = GetCRMService(task.Email, task.Password);
                var setupTask = new Entity("task");
                setupTask.Id = new Guid(task.Id);
                setupTask.Attributes["ownerid"] = new EntityReference("systemuser", new Guid(task.OwnerId));
                setupTask.Attributes["regardingobjectid"] = new EntityReference(task.RegardingObjectName,
                    new Guid(task.RegardingObjectId));
                setupTask.Attributes["subject"] = task.Subject;
                setupTask.Attributes["description"] = task.Description;
                setupTask.Attributes["createdon"] = DateTime.Now.ToLocalTime();
 
                //setupTask.Attributes["scheduledstart"] = task.ScheduledStart;
                setupTask.Attributes["scheduledend"] = task.ScheduledEnd.AddHours(23).AddMinutes(59).AddSeconds(59);
                setupTask.Attributes["prioritycode"] =
                    new Microsoft.Xrm.Sdk.OptionSetValue(Convert.ToInt32(task.Priority));
                setupTask.Attributes["actualdurationminutes"] = Convert.ToInt32(task.Duration);
                crmService.<strong>Update</strong>(setupTask);
                return new Response() { Message = "success" };
            }
            catch (Exception err)
            {
                return new Response() { Message = "failure" };
            }
        }

Dynamics CRM, Create a task using C#

In dynamics CRM, a task, phone call, meeting are termed as activities performed on an entity. Like if there is an entity “Lead”, under a certain lead there can be multiple activities like tasks, phonecalls, appointments e.t.c

Let us create a task in dynamics CRM.

First we will define a task DTO(Data transformation Object) or model

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
public class TaskEntity
    {        
        public string RegardingObjectName { get; set; }
        public string RegardingObjectId { get; set; }
        public string Email { get; set; }
        public string Password { get; set; }
        public string OwnerId { get; set; }
        public string Subject { get; set; }
        public string Description { get; set; }
        public DateTime ScheduledStart { get; set; }
        public DateTime ScheduledEnd { get; set; }
        public string Priority { get; set; }
        public double Duration { get; set; }
    }

GetCRMService object can be referenced from following post LINK TO PART 1

ReferenceObjectId and ReferenceObjectName are important, as they represents the object to which this task will be added under. Like if you are to add a task under a Lead, then type referenceobjectname as “lead” and ReferenceObjectId as Id of the lead entity object.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 
public Response AddTask(TaskEntity task)
        {
            try
            {
                var crmService = GetCRMService(task.Email, task.Password);
                var setupTask = new Entity("task");
 
                setupTask.Attributes["ownerid"] = new EntityReference("systemuser", new Guid(task.OwnerId));
                setupTask.Attributes["regardingobjectid"] = new EntityReference(RegardingObjectName,
                    new Guid(task.RegardingObjectId));
                setupTask.Attributes["subject"] = task.Subject;
                setupTask.Attributes["description"] = task.Description;
                setupTask.Attributes["createdon"] = DateTime.Now.ToLocalTime();
                setupTask.Attributes["scheduledstart"] = task.ScheduledStart;
                setupTask.Attributes["scheduledend"] = task.ScheduledEnd.AddHours(23).AddMinutes(59).AddSeconds(59); // Adding end time as one day ahead of current time
                setupTask.Attributes["prioritycode"] =
                    new Microsoft.Xrm.Sdk.OptionSetValue(Convert.ToInt32(task.Priority));
                setupTask.Attributes["actualdurationminutes"] = Convert.ToInt32(task.Duration);
                crmService.Create(setupTask);
                return new Response() {Message = "success"};
            }
            catch (Exception err)
            {
                return new Response() {Message = "failure"};
            }
        }

Increase Visual Studio build times

Although compiling is still the #1 programmer excuse for slacking off, you still probably don’t want to spend more time on it than you absolutely have to.

If your Visual Studio builds take longer than you would like, there are a couple of things you can do. First, if you’re still using a spinning-metal disk drive, upgrade to an SSD.

Ok, now that we’re all using an SSD, check and see if your antivirus software is slowing down your builds. If you’re using the default Windows software, you’re going to be looking for Windows Defender. Open up Task Manager and watch it while you go into your Visual Studio solution and choose “Rebuild All”. Do you see something like this?

Notice that Windows Defender, also known as Antimalware Service Executable, is taking up almost as much CPU time as Visual Studio, and quite a bit more than MSBuild.exe or the VB/C# compiler service (VBCSCompiler.exe). Assuming your build takes more than a second or two, note how long it takes to run under these conditions.

Exclude Visual Studio from Windows Defender

As a quick check, run a scan to make sure you don’t have anything currently infecting your system, and then go to Windows Defender -> Settings and disable Real-time protection:

Rebuild your solution in Visual Studio, noting the total time it takes and observing in Task Manager to see if the Antimalware Service Executable appears to be consuming significant processor time. Assuming your build is faster and your CPU less busy, congratulations, you’ve identified one cause of your performance problems. The next step is to responsibly tell Windows Defender to leave Visual Studio alone without turning it off completely.

First, turn Real-time protection back on. Then, scroll down to Exclusions and choose Add an exclusion.

We’re going to exclude the devenv.exe process and your projects folder(s). First, click Exclude a folder and choose the folder(s) where your development projects reside. Next, choose Exclude a .exe process and add devenv.exe. When you’re finished, the Add An Exclusion menu should look something like this:

Close the window and return to Visual Studio. Rebuild your solution and confirm that the build times are similar to when Real-time protection was off, and that you’re no longer seeing the Antimalware Service Executable process consuming processor time during your build.

If you’re using another antivirus tool, it should provide you with similar steps for excluding certain files and programs.

Now share this with your team – they should love you for it.

Asp.net core outperforms nodejs

https://github.com/aspnet/benchmarks

Although above links says it all, but for the lazy guys who do not want to go to that link, here are the highlights.

Tests were performed on below servers.

b0

Results are below.

b1

b2

Clearly asp.net core outshines nodeJS setup and class asp.net as well. Should be the perfect choice for asp.net fellows.

C# – Website security – Hide Connection strings from code

Your application probably needs to communicate with a database of some kind. Naturally, that database isn’t open to the world – it needs to be protected and secured. The typical solution to this is to create a username and password combination (ideally, specific to each application or user that requires access) and configure the application with these credentials. In many cases, they’re simply stored in configuration, such as the section of web.config for an ASP.NET application. By default, such settings are stored in plaintext, and are checked into source control, which can have disastrous consequences (note: if you use GitHub and accidentally expose a secret publicly, you need to change it. Just deleting it isn’t enough). There are many different kinds of secrets an application might require, from database connection strings to API keys.

Including connection strings in the code is not a very good practice as your code can be de-compiled and it will be more prone to hijacking the website as well as database server.

To protect this, a good practice would be to encrypt the connection string and decrypt it while accessing the connection string in the code.

Use below code to encrypt and decrypt connection strings using key and hash.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
 
namespace EncodingDecodingMain
{
    public static class EncDec
    {
        public static string Encrypt(string toEncrypt, string SecurityKey ,bool useHashing)
        {
            byte[] keyArray;
            byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);
 
            string key = SecurityKey;
 
            //If hashing use get hashcode regards to your key
            if (useHashing)
            {
                MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
                keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
                //Always release the resources and flush data
                // of the Cryptographic service provide. Best Practice
 
                hashmd5.Clear();
            }
            else
                keyArray = UTF8Encoding.UTF8.GetBytes(key);
 
            TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
            //set the secret key for the tripleDES algorithm
            tdes.Key = keyArray;
            //mode of operation. there are other 4 modes.
            //We choose ECB(Electronic code Book)
            tdes.Mode = CipherMode.ECB;
            //padding mode(if any extra byte added)
 
            tdes.Padding = PaddingMode.PKCS7;
 
            ICryptoTransform cTransform = tdes.CreateEncryptor();
            //transform the specified region of bytes array to resultArray
            byte[] resultArray =
              cTransform.TransformFinalBlock(toEncryptArray, 0,
              toEncryptArray.Length);
            //Release resources held by TripleDes Encryptor
            tdes.Clear();
            //Return the encrypted data into unreadable string format
            return Convert.ToBase64String(resultArray, 0, resultArray.Length);
        }
 
        public static string Decrypt(string cipherString, string SecurityKey, bool useHashing)
        {
            byte[] keyArray;
            //get the byte code of the string
 
            byte[] toEncryptArray = Convert.FromBase64String(cipherString);
 
            string key = SecurityKey;
 
            if (useHashing)
            {
                //if hashing was used get the hash code with regards to your key
                MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
                keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
                //release any resource held by the MD5CryptoServiceProvider
 
                hashmd5.Clear();
            }
            else
            {
                //if hashing was not implemented get the byte code of the key
                keyArray = UTF8Encoding.UTF8.GetBytes(key);
            }
 
            TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
            //set the secret key for the tripleDES algorithm
            tdes.Key = keyArray;
            //mode of operation. there are other 4 modes. 
            //We choose ECB(Electronic code Book)
 
            tdes.Mode = CipherMode.ECB;
            //padding mode(if any extra byte added)
            tdes.Padding = PaddingMode.PKCS7;
 
            ICryptoTransform cTransform = tdes.CreateDecryptor();
            byte[] resultArray = cTransform.TransformFinalBlock(
                                 toEncryptArray, 0, toEncryptArray.Length);
            //Release resources held by TripleDes Encryptor                
            tdes.Clear();
            //return the Clear decrypted TEXT
            return UTF8Encoding.UTF8.GetString(resultArray);
        }
 
    }
}

Make a separate tool that will encode and decode a string using above code, encode your connection strings and place in the web.config file the encrypted connection strings. This way even if someone views your code, he would not be able to easily reach out to your data source without the secret key which only you have access to.

Add note [annotation] in Dynamics CRM using Csharp

Notes in Dynamics CRM can be associated to any entity like Account, Sales Order, Order, Contact, Opportunity e.t.c; To programatically attach a note to an entity please follow the code below:

Annotation object in CRM has the following structure

Note:
has title, description and an attachment.

Following class holds an object that represents a note object in CRM.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
    public class NoteGeneric
    {
        public string ReferenceId { get; set; }
        public string Email { get; set; }
        public string Password { get; set; }
        public System.Web.HttpPostedFileBase file { get; set; }
        public string Description { get; set; }
        public string NoteText { get; set; }
        public string DocumentBody { get; set; }
        public string Subject { get; set; }
        public string FileName { get; set; }
        public string FileType { get; set; }
        public bool HasDocument { get; set; }
 
    }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 
        public Response AddNotes(NoteGeneric note, string EntityName)
        {
            try
            {
                var crmService = GetCRMService(note.Email, note.Password);
 
                var annotation = new Entity("annotation");
 
                annotation.Attributes["objectid"] = new EntityReference(EntityName,
                    new Guid(note.ReferenceOpportunityId));
                annotation.Attributes["objecttypecode"] = EntityName;
                annotation.Attributes["subject"] = note.Subject;
                annotation.Attributes["notetext"] = note.NoteText;
                annotation.Attributes["createdon"] = DateTime.Now.ToLocalTime();
                if (note.HasDocument)
                {
                    annotation.Attributes["mimetype"] = note.FileType;
                    annotation.Attributes["documentbody"] = note.DocumentBody;
                    annotation.Attributes["filename"] = note.FileName;
                }
 
                crmService.Create(annotation);
                return new Response() {Message = "success"};
            }
            catch (Exception err)
            {
                return new Response() {Message = "failure"};
            }
        }

For GetCRMService method, see this post. LINK TO PART 1

Above method will attach the document only if HasDocument property is set to true, in other case, it will at a note without the attachment.

crmService.Create method saves/associated the annotation to the entity.

Part 3-b – Dynamic CRM Series – Fetch some data using CRM SDK in C#

LINK TO PART 1 – Connection

LINK TO PART 2 – Authentication

LINK TO PART 3 – Fetch Data through Fetch XML

LINK TO PART 4 – Fetch Data through CRM SDK

In the last post we fetched some account list using FETCH XML technique, in this blog post, we will do the same but using CRM SDK, utilising this method is more familiar to C# developers.

Below is the method to fetch accounts list from dynamics CRM using CRM SDK

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
 
    public class BasicAccountInfo
    {
        public string code { get; set; }
        public string name { get; set; }
    }
 
        /// <summary>
        /// Get all user accounts in CRM
        /// </summary>
        /// <param name="email"></param>
        /// <param name="password"></param>
        /// <param name="searchphrase"></param>
        /// <returns></returns>
        public List<BasicAccountInfo> GetUserAccountsWeb(string email, string password)
        {
            var finalResult = new List<BasicAccountInfo>();
            var crmService = GetCRMService(email, password);
 
            var query = new QueryExpression("account") {ColumnSet = new ColumnSet("name", "accountid")};
 
            ConditionExpression condition = new ConditionExpression
            {
                AttributeName = "name",
                Operator = ConditionOperator.NotNull
            };
 
            FilterExpression filter = new FilterExpression();
            filter.FilterOperator = LogicalOperator.And;
            filter.Conditions.Add(condition);
 
            query.Criteria.AddFilter(filter);
            query.Distinct = true;
 
            EntityCollection result = crmService.RetrieveMultiple(query);
            var finalResult = (from data in result.Entities
                                       select new
                                       {
                                           code = ((Microsoft.Xrm.Sdk.Entity)(data)).Attributes["accountid"].ToString(),
                                           name = ((Microsoft.Xrm.Sdk.Entity)(data)).Attributes["name"].ToString()
                                       }).ToList();
 
 
            return finalResult;
        }