Showing posts with label CodeProject. Show all posts
Showing posts with label CodeProject. Show all posts

Monday, March 11, 2013

Creating a Generic List of Anonymous Types using Casting by Example

Consider the following scenario. You have two lists of data which are the result of separate queries. The select in the queries is identical and you want to merge the lists into a generic anonymous list to display the results in a control.

The code below receives a pipe delimited string, the string contains keywords. The code loops the string array and executes two separate queries against separate fields (coded this way for the purpose of this example) the biggest obstacle would be how to combine the results of the queries into a single list.

In order to merge the lists into one, it is possible to use a technique called Casting by Example, by creating an anonymous type that matches the intended select, it will be possible to cast this type into an array and then into a list. See below:

var result = new {Id = 1, CriteriaId = 0, MarketName = string.Empty};
var results = (new[] {result}).ToList();
Here is the complete code for your review:
var keywords = p.Split('|');
if (keywords.Length == 0)
    return;
           
var result = new {Id = 1, CriteriaId = 0, MarketName = string.Empty};
var results = (new[] {result}).ToList();
                
using (var ctxt = new MarketSearchDataContext())
{                
  foreach (var keyword in keywords)
  {
   var nameResults = ctxt.Markets.Where(m => m.MarketName.ToLower()
       .Contains(keyword.ToLower().Trim()))
       .Select(m => new {Id = m.Id, CriteriaId = 0, MarketName = m.MarketName})
       .ToList();

   var detailResults = ctxt.Markets.Where(m => m.HTML
       .Contains(keyword.ToLower().Trim()))
       .Select(m => new { Id = m.Id, CriteriaId = 0, MarketName = m.MarketName })
       .ToList();
   if (nameResults.Count > 0)
       results.AddRange(nameResults);

   if (detailResults.Count > 0)
        results.AddRange(detailResults);
}

//Raw results from the list - Duplicates will exist
results.RemoveAt(0); //Cast by Example row
var cleanResults = results.Distinct();

BindResultsGrid(cleanResults);

Monday, May 14, 2012

Implementing a JSON Feed with ASP.Net

Obtaining data from an external web site using a JSON (JavaScript Object Notation) feed is a relatively simple process.

JSON represents data structures using a JavaScript object notation which is human readable. It provides some advantages over XML because it is easier to obtain data from multilevel (nested) structures.

Below is an example of a JSON feed implementation to a service that provides quotes for precious metals at: http://drayah.no.de/metals/latest
The objective is to get the feed from the site in order to  obtain the price of Gold.

Step 1. Create a Class for JSON Feed 


You may want to use the JsonCSharp tool that helps you create a class based on the output from the feed. Check it out at  http://json2csharp.com/ 


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace JSONFeed
    {
        public class Gold
            {
            public double quote { get; set; }
            public double quoteKg { get; set; }
            }

        public class Silver
            {
            public double quote { get; set; }
            public double quoteKg { get; set; }
            }

        public class Platinum
            {
            public double quote { get; set; }
            public double quoteKg { get; set; }
            }

        public class Palladium
            {
            public double quote { get; set; }
            public double quoteKg { get; set; }
            }

        public class Metals
            {
            public Gold gold { get; set; }
            public Silver silver { get; set; }
            public Platinum platinum { get; set; }
            public Palladium palladium { get; set; }
            }

    }

Step 2. Creating a Method to invoke the Feed



using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net;
using System.Runtime.Serialization.Json;
using System.Web.Configuration;

namespace JSONFeed
    {
    public class GetFeed
        {

        public double GoldPrice()
            {
            try
                {

                //Get Precious Metals Pricess from Drayah feed 
                //http://drayah.no.de/metals/latest

                string url = "http://drayah.no.de/metals/latest";
                WebRequest request = WebRequest.Create(url);
                WebResponse ws = request.GetResponse();

                //Used http://json2csharp.com/ to auto-generate C# Class
                //for the Json feed.
                //DataContractJsonSerializer will Serialize based on another
                //class named Metals
                DataContractJsonSerializer jsonSerializer =
                             new DataContractJsonSerializer(typeof(Metals));
                Metals _metals =
                   (Metals)jsonSerializer.ReadObject(ws.GetResponseStream());

                if (_metals.gold.quote > 0)
                    return _metals.gold.quote;
                else
                    return 0;

                }
             //Add your exception code here.
            catch (Exception ex)
                {
                return 0;
                }
            }

        }
    }


Step 3. Test Class to run and test the feed

If you believe in using Visual Studio Automated Testing Classes, use the below.


using JSONFeed;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting.Web;

namespace JSONFeed.Test
{
        
    [TestClass()]
    public class GetFeedTest
        {

        private TestContext testContextInstance;

        ///


        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///

        public TestContext TestContext
            {
            get
                {
                return testContextInstance;
                }
            set
                {
                testContextInstance = value;
                }
            }

        #endregion


        [TestMethod()]
        public void GoldPriceTest()
            {
            GetFeed target = new GetFeed();
            double actual;

            actual = target.GoldPrice();
            Assert.AreNotEqual(0, actual);
           
            }
        }
}

The GoldPrice() Method, invokes the jsonSerializer which will try to match the output of the feed with the appropriate class which in this case is the class named Metals. The data will be filled into the corresponding subclass. If the data contains multiple rows of information, it needs to be defined as a list so the serializer knows that multiple rows are affected.

Below is a screenshot of the output after it's been serialized.



Hope this helps,
Happy coding.






Thursday, December 1, 2011

Show Indentation Lines in Visual Studio 2010

Have you found yourself wondering if your HTML tags have matching closing tags?
Wouldn’t it be great to have a visual aid to help you read your code and verify that is aligned properly and the tags match?

There is a great Visual Studio extension named Indent Guides which you can download from CodePlex, @ http://visualstudiogallery.msdn.microsoft.com/e792686d-542b-474a-8c55-630980e72c30 once installed, restart Visual Studio and you can easily notice that your source code has now a visual line that you can use to ensure indentation is correct and to match tags. See screenshot below.




Speaking of Visual Studio tips and tricks, here are another couple of tricks to improve the editor experience:

- You can use Ctrl+E, D to format the selected text. This would add indentation to your code so it is easier to read, although you may want to use with caution because the indentation can be excessive for some people. You can find this option on the Edit -> Advanced menu.
- A common question is how to display Line number on the Visual Studio 2010 editor. To do so, go to the Tools menu, click on Options -> Expand Text Editor, select a language, for example C# and click on General if is not selected automatically. Then on the last section of the window named “Display” enable the Line Numbers checkbox.
- What if the code you are reading is all collapsed because somebody else used the Outline feature? Well you can quickly turn off the Outline by pressing Ctrl+M, P, you can find all the Outline options on the Edit menu Outlining

Hope this helps somebody out there,
Will

Wednesday, November 23, 2011

Clearing Another User's Checkout in TFS

A long gone coworker has left a few objects checked out in TFS, now you discover that you need to clear the checkout in order to incorporate new changes. How can this be done?

Clearing out another user's check out is NOT supported from the GUI, however there is a command line option to accomplish this:

- From Visual Studio Tools in the Start menu, open the Visual Studio Command Prompt
- If you use TFS, your workstation should have the TF command available, then type:

C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC>TF undo /workspace:WorkstationName;UserName $/ProjectName/ObjectName.cs /s:http://YourTFSServer:8080

Once the command completes, refresh the Source Control Explorer to see the changes, you may also need to  get the latest version of the project if multiple objects have been locked for a long period of time.

Hope this helps,
Will

Tuesday, November 15, 2011

Using DotNetZip Library to Compress Data in ASP.Net

I recently worked on a project that involved creating encrypted Zip files. Data is captured on a web form and then written to a text file.
At first, the task sounded complex. However, if you are aware of the DotNetZip library existence, your task just got easier.

You can download the DotNetZip library from http://dotnetzip.codeplex.com/
Once you download and install the package, you will need to add a reference to Ionic.Zip.dll or copy the file to your \lib folder, this is all you need to start generating your own zip files.

The best part: DotNetZip is free!!

DotNetZip is well documented and is much easier to use than any other solutions out there including System.IO.Compression and SharpZipLib, after trying both methods I would highly recommend DotNetZip because is incredibly easy to use.

Below is a sample method to illustrate how to easily to compress content that is being passed as a string.
The method takes the file name and the content as arguments:

internal MemoryStream ZipString(string aZipFileName, string aContents, string aMode)
{
    try
    {
        //Add these to your AppSettings on Web.Config
        string sZipFilePassword = ConfigurationManager.AppSettings["ZipFilePassword"];
        string sZipFileEncryption = ConfigurationManager.AppSettings["ZipFileStrongEncryption"];

        //Stored the zippped data on this memory stream
        MemoryStream msZippedContent = new MemoryStream();
        // Creating Zip
        using (var zip = new ZipFile())
        {
            // Add the password protection
            zip.Password = sZipFilePassword;
            if (sZipFileEncryption == "N")
            {
                //PkZipWeak is not a string encryption method, but is supported by any UnZip utility
                zip.Encryption = EncryptionAlgorithm.PkzipWeak;
            }
            else
            {
                //WinZipAes128 and WinZipAes256 is NOT compatible with Windows ZIP
                zip.Encryption = EncryptionAlgorithm.WinZipAes256;
            }

            // Add the desired file to the Zip
            zip.AddEntry(aZipFileName, aContents, Encoding.ASCII);

            // Send the contents of the ZIP back to the output stream
            zip.Save(msZippedContent);
            return msZippedContent;
        }
    }
    catch (Exception genEx)
    {
        Response.Write(genEx.Message);
        return null;
    }

}//ZipString

The method declares a variable of type ZipFile which is available once you add a reference: "using Ionic.Zip;" That declaration creates the shell of the zip file. After that, the process to save the file is simple, add a password if needed, add an encryption method and you can proceed to add an entry to the Zip file by using AddEntry.
Of course, you could add multiple files to the same Zip archive. Finally, you can Save the contents of the Zip which in this case are returned by the method as a MemoryStream that could be used for other purpose such as creating an e-mail attachment.

Be aware that if you need to encrypt the contents of the zip, choosing the encryption method is important because the built-in Windows unzip feature can only decrypt PkZip.Weak content. You would need to have WinZip or WinRar Installed on the target workstation to unzip contents encrypted with the WinZipAes128 or WinZipAes256 methods.

Hope this is helpful and feel free to contact me if you have any questions,
Will




Saturday, November 12, 2011

How to clear a String Builder?

How to clear a StringBuilder?
By now you probably realized that rhere is no Clear method.

You can use the two lines below, the assumption is that you are going to reuse the StringBuilder several times in your code and you want to temporarily clear it to ensure is empty and ready for a new assignment.

sbSQL.Length = 0;
sbSQL.Capacity = 0;


This trims the contents but also shortens the capacity to zero. I was surprised to noticed that both Length and Capacity properties are writable.

Hope it helps,
Will




Thursday, November 3, 2011

Exporting Data as XML in a MemoryStream with Download Prompt

The below snippet demonstrates how to generate XML content on the fly and then storing the contents in memory. (MemoryStream)
This practice is useful if the output can't be saved on the server and avoids the hassle of dealing with permissions. Instead the XML is generated in memory and then the user will be automatically prompted to download the XML file to their local resource, similar to what happens when attempting to download a file.

protected bool GenerateExportFile()
{
           
    try
    {
            //Create Memory Stream to store XML Data
            MemoryStream ms = new MemoryStream();
            //Use a writer to greate the XML
            using (XmlWriter writer = XmlWriter.Create(ms))
            {
                writer.WriteStartDocument(); //Header
                writer.WriteComment("Comment goes here");
                {
                    writer.WriteStartElement("Root"); //<Root>
                    {
                            writer.WriteStartElement("Element1"); //<Element1>
                            writer.WriteAttributeString("Attribute1", "AtributeValue");

                            writer.WriteStartElement("Element2");
                            writer.WriteString("Element2Value");
                            writer.WriteEndElement(); //<Element2>

                    }
                    writer.WriteEndElement(); //<Root>
                    //Closed the Root Tag
                }
                writer.WriteEndDocument();
                writer.Close();

                //Convert Memory Stream to Byte Array
                byte[] data = ms.ToArray();
                //The Proposed FileName that will show when the user is prompted to save the file
                string xmlFileName = "OrdExp_" + DateTime.Today.Year.ToString() + DateTime.Today.Month.ToString("00") + DateTime.Today.Day.ToString("00");
                                               
                //Creating the Context
                HttpContext.Current.Response.Clear();
                //Heads up browser, here comes some XML
                HttpContext.Current.Response.ContentType = "text/xml";
                HttpContext.Current.Response.AddHeader("Content-Disposition:", "attachment;filename=" + HttpUtility.UrlEncode(xmlFileName));
                //Set the size of the file so the progress bar reports that correctly
                HttpContext.Current.Response.AddHeader("Content-Length", data.Length.ToString());
                //Download the file and prompt the user to save
                HttpContext.Current.Response.BinaryWrite(data);
                HttpContext.Current.Response.End();
                ms.Flush();
                ms.Close();


                return true;
            }
    }
    catch (Exception exc)
    {
        lblMsg.Text = "Error Generating File: " + exc.Message;
        return false;
    }           
    return true;  
}//Method



This code was used to generate XML data output and then added the ability to automatically export the data to a local machine.
Hope this helps,
Will




Thursday, October 20, 2011

Where is Microsoft Outlook Temp Folder? (Windows 7 and Outlook 2010)

Ever wondered where Microsoft Outlook stores temp files?

It is useful to know this location, so you can go there and delete the multiple copies of attachments and pictures and other Outlook files. It can also be useful if you are looking for an attachment contained in a message that you deleted by mistake.

For Outlook 2010 running under Windows 7 go to:
C:\Users\UserName\AppData\Local\Microsoft\Windows\Temporary Internet Files\Content.Outlook

In this folder you will find that there is one or multiple folders named with a random combination of numbers and letters, for example: 82UOSVIP
Inside this directory you will find attachments and pictures stored by Outlook.

If you are curious. This is stored in a registry entry:
HKEY_CURRENT_USER\Software\Policies\Microsoft\Office\14.0\Outlook\Security
Value Name: OutlookSecureTempFolder
Data Type: REG_SZ

If you need more info, or you are looking for the temp folder in previous versions of Outlook, go to:
http://support.microsoft.com/kb/817878





Wednesday, October 19, 2011

Executing a Stored Procedure from a WCF Service Method

Here is an example of a method that is used within a WCF Service to execute a Stored Procedure and  parse the return value (a success/failure string) to a local variable which can be manipulated to display a friendly success or failure message.

public String fSave (string aParm1, string aParm2, 
                             string aParm3, Int32 aParm4)
{
    SqlConnection lSQLConn = null;
    SqlCommand lSQLCmd = new SqlCommand();
    string lsResponse = "";
    string connStr = "";
 
    connStr = 
    ConfigurationManager.ConnectionStrings["MyConnStr"].ConnectionString;
 
    try
    {
        // create and open a connection object
        lSQLConn = new SqlConnection(connStr);
        lSQLConn.Open();
        //The CommandType must be StoredProcedure if we are using an ExecuteScalar
        lSQLCmd.CommandType = CommandType.StoredProcedure;
        lSQLCmd.CommandText = "sp_YourSPName"; 
        lSQLCmd.Parameters.Add(new SqlParameter("@Parm1", aParm1));
        lSQLCmd.Parameters.Add(new SqlParameter("@Parm2", aParm2));
        lSQLCmd.Parameters.Add(new SqlParameter("@Parm3", aParm3));
        lSQLCmd.Parameters.Add(new SqlParameter("@Parm4", aParm4));
               
        lSQLCmd.Connection = lSQLConn;
        //Executes the SP and returns the single select output to a variable
        lsResponse = Convert.ToString(lSQLCmd.ExecuteScalar());
    }
    catch (Exception Exc)
    {
        return "Error: " + Exc.Message;                
    }
    finally
    {
        lSQLCmd.Dispose();
        lSQLConn.Close();
    }
 
    if (String.IsNullOrEmpty(lsResponse))
    {
        return "Error: Unspecified problem while adding task.";                
    }
    return lsResponse;
}

Now, let's review the above method. There are a few interesting things:
Once the connection is open, the SQLCommand has to be defined as a CommandType = CommandType.StoredProcedure. This signals the type of action we need to execute.
Next, we define the Stored Procedure to be executed by defining the CommandText="sp_YourSPName".
To get the return value, we set the string variable to the results of a SQL Command, ExecuteScalar ()

But wait. What should we do if our Stored Procedure returns a result set rather than a single value?
Well, you need to make a slight change to the method, we need to add a DataAdapter and a DataSet to parse the result.
See below:

SqlConnection lSQLConn = null;
SqlCommand lSQLCmd = new SqlCommand();
//Declare a DataAdapter and a DataSet
SqlDataAdapter lDA = new SqlDataAdapter();
DataSet lDS = new DataSet();
 
//...Execution section
 
// create and open a connection object
lSQLConn = new SqlConnection(connStr);
lSQLConn.Open();
//The CommandType must be StoredProcedure if we are using an ExecuteScalar
lSQLCmd.CommandType = CommandType.StoredProcedure;
lSQLCmd.CommandText = "sp_YourSPName"; 
lSQLCmd.Parameters.Add(new SqlParameter("@Parm1", aParm1));
lSQLCmd.Parameters.Add(new SqlParameter("@Parm2", aParm2));
lSQLCmd.Parameters.Add(new SqlParameter("@Parm3", aParm3));
lSQLCmd.Parameters.Add(new SqlParameter("@Parm4", aParm4));
 
lSQLCmd.Connection = lSQLConn;
//Fill the DataAdapter with a SelectCommand
lDA.SelectCommand = lSQLCmd;
lDA.Fill(lDS);

Hope this is helpful,
Will




Thursday, October 13, 2011

Reading Keys from App.Config

I would like to share a small code snippet that is useful if you need to read entries from a configuration file, for example: App.config

Below are the entries I want to read from my App.config

<?xml version="1.0"?>
<configuration>
 <appSettings>
    <add key="MyServiceURL" value="http://10.12.64.190:8086/MyService"/>
  </appSettings>
<startup><supportedRuntime version="v2.0.50727"/></startup></configuration>

Below is the best way I've found so far to read these entries in C#:

//Scan Thru the keys and use the Configuration Manager to make this happen
foreach (string key in ConfigurationManager.AppSettings)
{
 //Get your key
 string value = ConfigurationManager.AppSettings[key];
 this.Url = value;
}

Keep in mind that you need to add a reference to the System.Manager assembly for this to work.
I've tested this with the .NET Framework 3.5 and 4.0
HTH,
Will




Saturday, October 8, 2011

Sample LINQ with Multiple Joins and Selected Columns

If you are like me, I sometimes find difficult remembering the syntax of LINQ statements because I jump from T-SQL to ASP.Net and C#.
I was searching for a sample that may show how to write a LINQ statement with multiple joins and I had little luck finding it, so finally after I put my few brain cells in action, I came up with the following:

var dbRegCourses = (from a in db.CourseRegistries
                    join b in db.Courses on a.courseid equals b.id
                    join c in db.aspnet_Users on a.userid equals c.UserId
                    where a.userid == sUserID
                    orderby a.regdate, b.code, b.description,
                            b.instructor, b.date, b.venue
                    select new
                    {
                      a.regdate, b.code, b.description,

                      b.instructor, b.date, b.venue});

if (dbRegCourses.Count() > 0)
{
    ResultLbl.Text =
"We found that you are registered to: " +     
                      dbRegCourses.Count().ToString() + " Courses.";
    return;
}

If you notice, here we are joining three tables, using a where statement and then pick and choosing columns from at least two tables.

I also added an if statement bottom to see if I got any rows back from the LINQ Statement and if that's the case return a message.

Hope this helps somebody out there,
Will