Gunnar Peipman's ASP.NET blog

ASP.NET, C#, SharePoint, SQL Server and general software development topics.

Sponsors

News

 
 
 
DZone MVB

Links

Social

May 2010 - Posts

ASP.NET MVC: MVC Time Planner is available at CodePlex

I get almost every week some e-mails where my dear readers ask for source code of my ASP.NET MVC and FullCalendar example. I have some great news, guys! I ported my sample application to Visual Studio 2010 and made it available at CodePlex. Feel free to visit the page of MVC Time Planner.

NB! Current release of MVC Time Planner is initial one and it is basically conversion sfrom VS2008 example solution to VS2010. Current source code is not any study material but it gives you idea how to make calendars work together. Future releases will introduce many design and architectural improvements. I have planned also some new features.

How MVC Time Planner looks?

MVC Time PlannerImage on right shows you how time planner looks like. It uses default design elements of ASP.NET MVC applications and jQueryUI. If I find some artist skills from myself I will improve design too, of course. :)

Currently only day view of calendar is available, other views are coming in near future (I hope future will be week or two).

Important links

And here are some important links you may find useful.

If you have any questions or you are interested in new features then please feel free to contact me through MVC Time Planner discussion forums.

Posted: May 31 2010, 10:40 AM by DigiMortal | with 13 comment(s)
Filed under: ,
Using ExcelPacke to create Excel sheets on server

In one of my community projects I needed to output some listings as Excel file. As installing Excel to server is non-sense that I was easily able to avoid I found simple solution for Excel 2007 files – open-source project called ExcelPackage. In this posting I will show you hot to create simple event attendees report in Excel 2007 format using ExcelPackage.

Cautions

Although ExcelPackage works well for me here are some things you should be aware of.

  • ExcelPackage needs file system access because compression library it uses is designed so.
  • There is only very old source code available and it is published under GPL. So if you are writing application to your customers then you cannot use this library unless you make your whole application open-source.
  • ExcelPackage has also some technical problems and it is not very easy to use in simple cases. Authors have not provided any new releases since the beginning of 2007 so I have good reason to consider this project as abandoned.
  • You may find the extensive package EPPlus also useful as there are new versions coming over time. EPPlus is also published under GPL (because ExcelPackage is under GPL), so you can use it only on very limited manner.

If you don’t afraid some s*itfight with technology and GPL is okay for your system then let’s go on.

Exporting event attendees list to Excel

Suppose we have list with event attendees and we want to export it to Excel. We are behaving normally and we don’t install Excel desktop software to our web server. Here is the code.


void ExportToExcel(Event evt)

{

    var fileInfo = new FileInfo(Path.GetTempPath() + "\\"
                                DateTime.Now.Ticks + ".xlsx");

 

    using (var xls = new ExcelPackage(fileInfo))

    {

        var sheet = xls.Workbook.Worksheets.Add(evt.Title);

 

        sheet.Cell(1, 1).Value = "First name";

        sheet.Cell(1, 2).Value = "Last name";

        sheet.Cell(1, 3).Value = "E-mail";

        sheet.Cell(1, 4).Value = "Phone";

        sheet.Cell(1, 5).Value = "Registered";

        sheet.Cell(1, 6).Value = "Live Meeting";

 

        var i = 1;

        foreach(var attendee in evt.Attendees)

        {

            i++;

 

            var profile = attendee.Profile;

            sheet.Cell(i, 1).Value = profile.FirstName;

            sheet.Cell(i, 2).Value = profile.LastName;

            sheet.Cell(i, 3).Value = profile.Email;

            sheet.Cell(i, 4).Value = profile.Phone;

            sheet.Cell(i, 5).Value = att.Created.ToString();

            sheet.Cell(i, 6).Value = att.LiveMeeting.ToString();

        }

 

        xls.Save(); 

    }

 

    Response.Clear();

    Response.ContentType = "application/vnd.openxmlformats";

    Response.AddHeader("Content-Disposition",
                       "attachment; filename=" + fileInfo.Name);

    Response.WriteFile(fileInfo.FullName);

    Response.Flush();

 

    if (fileInfo.Exists)

        fileInfo.Delete();
}


And here is the result.

Event attendees list

Although it is possible to make this list more effective and nice it works and users can start using it until all the nice bells and whistles are coming.

Conclusion

After some fighting with technology it was not very hard to get nice Excel 2007 sheets coming out from our server. We used ExcelPackage library to create list of event attendees and our event organizers can now simply download data to Excel if they need to contact with attendees or manage their data using Excel tools.

Posted: May 30 2010, 01:29 PM by DigiMortal | with 11 comment(s)
Filed under: ,
JavaScript: Creating timestamps with time zone offsets

I was converting the example code of my Windows Azure session to Visual Studio 2010 solution called MVC Time Planner when I discovered some date and time offset issues in my JavaScript code. In this posting I will show you some useful tricks you can use to convert JavaScript dates and times to timestamps.

Date.getTime() returns UTC

When you call getTime method on Date object you get the number of milliseconds from Unix epoch. Although your current Date object keeps time with some offset getTime gives seconds in UTC. Keep this in mind when creating timestamps if you are not living on zero-meridian.


var currentDate = selectedDate;          // current date with offset

var currentTime = currentDate.getTime(); // offset is ignored


This is pretty awkward, unexpected and unintuitive behavior but you have to keep in mind that all date and time calculations must use same time system to give appropriate results.

Date.getTimezoneOffset()

getTimezoneOffset method returns you the amount of minutes you have to add to your current timestamp to convert it to UTC time. If your time zone is UTC+3 then getTimezoneOffset returns you –180 because:

UTC + 3 hours + (-180) minutes = UTC

If your time zone is UTC-3 then

UTC - 3 hours + 180 minutes = UTC

Pretty simple math but confusing at first place.

Getting timestamp with time zone

In my application I have to give timestamp for selected dates and times to server. I need to find correct amount of seconds from Unix epoch so users can save times based on their region and not by UTC. Here is how calculate timestamps.


var currentDate = selectedDate;

var currentTime = currentDate.getTime();

var localOffset = (-1) * selectedDate.getTimezoneOffset() * 60000;

var stamp = Math.round(new Date(currentTime + localOffset).getTime() / 1000);


On server side I use the following method to convert timestamp to date. This method is borrowed from CodeClimber blog posting Convert a Unix timestamp to a .NET DateTime.


private static DateTime ConvertFromUnixTimestamp(double timestamp)

{

    var origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);

    return origin.AddSeconds(timestamp);

}


Conclusion

Playing with dates and times is always interesting thing to do because there are many different time zones in the world and supporting them all is not easy thing to do. Inside the system we must be able to keep all dates in appropriate system and usually it is UTC. This posting showed you some tricks about how to play with local times in JavaScript.

Code Contracts: validating arrays and collections

Validating collections before using them is very common task when we use built-in generic types for our collections. In this posting I will show you how to validate collections using code contracts. It is cool how much awful looking code you can avoid using code contracts.

Failing code

Let’s suppose we have method that calculates sum of all invoices in collection. We have class Invoice and one of properties it has is Sum. I don’t introduce here any complex calculations on invoices because we have another problem to solve in this topic. Here is our code.


public static decimal CalculateTotal(IList<Invoice> invoices)

{

    var sum = invoices.Sum(p => p.Sum);

    return sum;

}


This method is very simple but it fails when invoices list contains at least one null. Of course, we can test if invoice is null but having nulls in lists like this is not good idea – it opens green way for different coding bugs in system. Our goal is to react to bugs ASAP at the nearest place they occur.

There is one more way how to make our method fail. It happens when invoices is null. I thing it is also one common bugs during development and it even happens in production environments under some conditions that are usually hardly met.

Now let’s protect our little calculation method with code contracts. We need two contracts:

  1. invoices cannot be null
  2. invoices cannot contain any nulls

Our first contract is easy but how to write the second one?

Solution: Contract.ForAll

Preconditions in code are checked using Contract.Ensures method. This method takes boolean value as argument that sais if contract holds or not. There is also method Contract.ForAll that takes collection and predicate that must hold for that collection. Nice thing is ForAll returns boolean. So, we have very simple solution.


public static decimal CalculateTotal(IList<Invoice> invoices)

{

    Contract.Requires(invoices != null);

    Contract.Requires(Contract.ForAll<Invoice>(invoices, p => p != null));

 

    var sum = invoices.Sum(p => p.Sum);

    return sum;

}


And here are some lines of code you can use to test the contracts quickly.


var invoices = new List<Invoice>();

invoices.Add(new Invoice());

invoices.Add(null);

invoices.Add(new Invoice());

//CalculateTotal(null);

CalculateTotal(invoices);


If your code is covered with unit tests then I suggest you to write tests to check that these contracts hold for every code run.

Conclusion

Although it seemed at first place that checking all elements in collection may end up with for-loops that does not look so nice we were able to solve our problem nicely. ForAll method of contract class offered us simple mechanism to check collections and it does it smoothly the code-contracts-way.

P.S. I suggest you also read devlicio.us blog posting Validating Collections with Code Contracts by Derik Whittaker.

Clean Code: A Handbook of Agile Software Craftsmanship – book review

Clean Code: A Handbook of Agile Software Craftsmanship  
Clean Code: A Handbook of Agile Software Craftsmanship
Writing code that is easy read and test is not something that is easy to achieve. Unfortunately there are still way too much programming students who write awful spaghetti after graduating. But there is one really good book that helps you raise your code to new level – your code will be also communication tool for you and your fellow programmers.

“Clean Code: A Handbook of Agile Software Craftsmanship” by Robert C. Martin is excellent book that helps you start writing the easily readable code. Of course, you are the one who has to learn and practice but using this book you have very good guide that keeps you going to right direction.

You can start writing better code while you read this book and you can do it right in your current projects – you don’t have to create new guestbook or some other simple application to start practicing. Take the project you are working on and start making it better!

My experience

Well, telling good words about book has no point without experimenting. When I read the book I took one of my not-so-hurry projects and started to apply practices from this book. Well, there is some mindshift, yes, but it is easy to get over it if you don't take too large steps. Go with small steps and repeat them. Pretty soon you have your first experiences and new coding rhythm. The important thing is - practice every day and don't hurry because your own style must be worked out in thoughtful way.

I started with writing some unit tests the way Clean Code showed. Same time I also modified code that has some smells. Then I modified the members of my classes so they had better names. I moved some logic to subclasses and made some other refactoring tasks. Don't be surprised if you don't achieve super good results at first time, you have to practice, practice, practice. But you will find it pretty easy and fun if you take small steps at first place.

The first results I achieved was really a big step towards to clean and testable code. I mean I did no complex things or any time consuming things. I just took small steps like Clean Code suggests and I was able to get move quickly. First small steps on code cleaning give you experiences you need on making your second and your third step. Continuous practicing makes you very good on clean code pretty soon. By example, I am pretty happy with the code that I cleaned to level the book told me. I took some volunteer over-hours just to try things out on real stuff. And it worked, okay, still works. :)

Threading guide

Besides writing clean code the author also introduces testing problems. Besides usual TDD stuff which was interesting reading there is very well discussion about testing threaded code and what kind of dangers there are and how to get over them. This far I consider threading part of this book as one of the best essays on threading I have ever read. It is not hard to read scientific story, even beginners should be able to read it although some help from Google/Bing may be needed.

My special thanks to Robert C. Martin

I want to say my special thanks to Robert C. Martin for this book. There are many books that teach you different stuff and usually you have markable learning curve to go before you start getting results. There are many books that show you the direction to go and then leave you alone figuring out how to achieve all that stuff you just read about.

Clean Code gives you a lot more – the mental tools to use so you can go your way to clean code being sure you will be soon there. I am reading books as much as I have time for it. Clean Code is top-level book for developers who have to write working code. Before anything else take Clean Code and read it. You will never regret your decision. I promise.

Fragment of editorial review

“Even bad code can function. But if code isn’t clean, it can bring a development organization to its knees. Every year, countless hours and significant resources are lost because of poorly written code. But it doesn’t have to be that way.

What kind of work will you be doing? You’ll be reading code—lots of code. And you will be challenged to think about what’s right about that code, and what’s wrong with it. More importantly, you will be challenged to reassess your professional values and your commitment to your craft.

Readers will come away from this book understanding

  • How to tell the difference between good and bad code
  • How to write good code and how to transform bad code into good code
  • How to create good names, good functions, good objects, and good classes
  • How to format code for maximum readability
  • How to implement complete error handling without obscuring code logic
  • How to unit test and practice test-driven development
This book is a must for any developer, software engineer, project manager, team lead, or systems analyst with an interest in producing better code.”

Table of contents

  1. Clean code
  2. Meaningful names
  3. Functions
  4. Comments
  5. Formatting
  6. Objects and data structures
  7. Error handling
  8. Boundaries
  9. Unit tests
  10. Classes
  11. Systems
  12. Emergence
  13. Concurrency
  14. Successive refinement
  15. JUnit internals
  16. Refactoring SerialDate
  17. Smells and heuristics
  1. A Concurrency II
  2. org.jfree.date.SerialDate
  3. Cross references of heuristics
  • Epilogue
  • Index
ASP.NET: Using pickup directory for outgoing e-mails

Sending e-mails out from web applications is very common task. When we are working on or test our systems with real e-mail addresses we don’t want recipients to receive e-mails (specially if we are using some subset of real data9. In this posting I will show you how to make ASP.NET SMTP client to write e-mails to disc instead of sending them out.

SMTP settings for web application

I have seen many times the code where all SMTP information is kept in app settings just to read them in code and give to SMTP client. It is not necessary because we can define all these settings under system.web => mailsettings node.

If you are using web.config to keep SMTP settings then all you have to do in your code is just to create SmtpClient with empty constructor.


var smtpClient = new SmtpClient();


Empty constructor means that all settings are read from web.config file.

What is pickup directory?

If you want drastically raise e-mail throughput of your SMTP server then it is not very wise plan to communicate with it using SMTP protocol. it adds only additional overhead to your network and SMTP server. Okay, clients make connections, send messages out and it is also overhead we can avoid.

If clients write their e-mails to some folder that SMTP server can access then SMTP server has e-mail forwarding as only resource-eager task to do. File operations are way faster than communication over SMTP protocol. The directory where clients write their e-mails as files is called pickup directory.

By example, Exchange server has support for pickup directories. And as there are applications with a lot of users who want e-mail notifications then .NET SMTP client supports writing e-mails to pickup directory instead of sending them out.

How to configure ASP.NET SMTP to use pickup directory?

Let’s say, it is more than easy. It is very easy. This is all you need.


<system.net>

  <mailSettings>

    <smtp deliveryMethod="SpecifiedPickupDirectory">

      <specifiedPickupDirectory pickupDirectoryLocation="c:\temp\maildrop\"/>

    </smtp>

  </mailSettings>

</system.net>


Now make sure you don’t miss come points:

  1. Pickup directory must physically exist because it is not created automatically.
  2. IIS (or Cassini) must have write permissions to pickup directory.
  3. Go through your code and look for hardcoded SMTP settings. Also take a look at all places in your code where you send out e-mails that there are not some custom settings used for SMTP!

Also don’t forget that your mails will be written now to pickup directory and they are not sent out to recipients anymore.

Advanced scenario: configuring SMTP client in code

In some advanced scenarios you may need to support multiple SMTP servers. If configuration is dynamic or it is not kept in web.config you need to initialize your SmtpClient in code. This is all you need to do.


var smtpClient = new SmtpClient();

smtpClient.DeliveryMethod = SmtpDeliveryMethod.SpecifiedPickupDirectory;

smtpClient.PickupDirectoryLocation = pickupFolder;


Easy, isn’t it? i like when advanced scenarios end up with simple and elegant solutions but not with rocket science.

Note for IIS SMTP service

SMTP service of IIS is also able to use pickup directory. If you have set up IIS with SMTP service you can configure your ASP.NET application to use IIS pickup folder. In this case you have to use the following setting for delivery method.


SmtpDeliveryMethod.PickupDirectoryFromIis


You can set this setting also in web.config file.


<system.net>

  <mailSettings>

    <smtp deliveryMethod="PickupDirectoryFromIis" />

  </mailSettings>

</system.net>


Conclusion

Who was still using different methods to avoid sending e-mails out in development or testing environment can now remove all the bad code from application and live on mail settings of ASP.NET. It is easy to configure and you have less code to support e-mails when you use built-in e-mail features wisely.

Posted: May 27 2010, 09:17 PM by DigiMortal | with 9 comment(s) |
Filed under:
Code Contracts: How they look after compiling?

When you are using new tools that make also something at code level then it is good idea to check out what additions are made to code during compilation. Code contracts have simple syntax when we are writing code at Visual Studio but what happens after compilation? Are our methods same as they look in code or are they different after compilation? In this posting I will show you how code contracts look after compiling.

In my previous examples about code contracts I used randomizer class with method called GetRandomFromRangeContracted.


public int GetRandomFromRangeContracted(int min, int max)

{

    Contract.Requires<ArgumentOutOfRangeException>(

        min < max,

        "Min must be less than max"

    );

 

    Contract.Ensures(

        Contract.Result<int>() >= min &&

        Contract.Result<int>() <= max,

        "Return value is out of range"

    );

 

    return _generator.Next(min, max);

}


Okay, it is nice to dream about similar code when we open our assembly with Reflector and disassemble it. But… this time we have something interesting. While reading this code don’t feel uncomfortable about the names of variables. This is disassembled code. .NET Framework internally allows these names. It is our compilators that doesn’t accept them when we are building our code.


public int GetRandomFromRangeContracted(int min, int max)

{

    int Contract.Old(min);

    int Contract.Old(max);

    if (__ContractsRuntime.insideContractEvaluation <= 4)

    {

        try

        {

            __ContractsRuntime.insideContractEvaluation++;

            __ContractsRuntime.Requires<ArgumentOutOfRangeException>(
               min < max,
               "Min must be less than max", "min < max");

        }

        finally

        {

            __ContractsRuntime.insideContractEvaluation--;

        }

    }

    try

    {

        Contract.Old(min) = min;

    }

    catch (Exception exception1)

    {

        if (exception1 == null)

        {

            throw;

        }

    }

    try

    {

        Contract.Old(max) = max;

   

    catch (Exception exception2)

    {

        if (exception2 == null)

        {

            throw;

        }

    }

    int CS$1$0000 = this._generator.Next(min, max);

    int Contract.Result<int>() = CS$1$0000;

    if (__ContractsRuntime.insideContractEvaluation <= 4)

    {

        try

        {

            __ContractsRuntime.insideContractEvaluation++;

            __ContractsRuntime.Ensures(
               (Contract.Result<int>() >= Contract.Old(min)) &&
               (Contract.Result<int>() <= Contract.Old(max)),
               "Return value is out of range",
               "Contract.Result<int>() >= min && Contract.Result<int>() <= max");

        }

        finally

        {

            __ContractsRuntime.insideContractEvaluation--;

        }

    }

    return Contract.Result<int>();

}


As we can see then contracts are not simply if-then-else checks and exceptions throwing. We can see that there is counter that is incremented before checks and decremented after these whatever the result of check was.

One thing that is annoying for me are null checks for exception1 and exception2. Is there really some situation possible when null is thrown instead of some instance that is Exception or that inherits from exception?

Conclusion

Code contracts are more complex mechanism that it seems when we look at it on our code level. Internally there are done more things than we know. I don’t say it is wrong, it is just good to know how our code looks after compiling. Looking at this example it is sure we need also performance tests for contracted code to see how heavy is their impact to system performance when we run code that makes heavy use of code contracts.

ASP.NET MVC: Using jQuery context menu with tables

I needed to add context menus to some tables of my intranet application. After trying some components I found one that does everything I need and has no overhead. In this posting I will show you how to use jQuery context menu plug-in and how to attach it to tables.

I found context menu plug-in by Chris Domigan and it was very easy to integrate to my application (when comparing some other plug-ins that work only on demo pages and in simple scenarios). Thanks, Chris, for great work! Now let’s use this context menu plug-in with table.

Before we go on let’s see what we are trying to achieve. The following screenshot fragment shows simple context menu that we want to attach to our table.

Table with jQuery context menu

And when we click some menu option then something should happen too. :)

Installing context menu plug-in

  1. Download plug-in (if download link is broken then open demo page and I think you know how to get plug-in from there).
  2. Copy jquery.contextmenu.js to your scripts folder.
  3. Include it in your masterpage or in the page where you plan to use context menus.
  4. Make sure plug-in is included correctly (use Firebug or some other tool you like).
  5. Save the page.

Defining context menu

Now let’s define context menu. Here is fragment on context menu definition from my code.


<div class="contextMenu" id="myMenu1">

    <ul>

    <li id="email"><img src="/img/e-mail.png" />E-mail</li>

    <li id="homepage"><img src="/img/homepage.png" />Homepage</li>

    </ul>

</div>


div with id myMenu1 is container of context menu. Unordered list inside container defines items in context menu – simple and elegant!

Adding context menu to table

I have table with persons. It is simple HTML. I omitted commands column from this and the next table to keep them simple and more easily readable.


<table>

  <tr>

    <th>Name</th>

    <th>Short</th>

    <th>Address</th>

    <th>Mobile</th>

    <th>E-mail</th>

  </tr>

  <% foreach(var person in Model.Results) { %>

  <tr>

    <td><%=person.FullName %></td>

    <td><%=person.ShortName %></td>

    <td><%=person.FullAddress %></td>

    <td><%=person.Mobile %></td>

    <td><%=person.Email %></td>

  </tr>

  <% } %>

</table>


To get context menu linked to table rows first cells we need to specify class for cells and ID. We need ID because we have to know later which ID has the row on which user selected something from context menu.


<table>

  <tr>

    <th>Name</th>

    <th>Short</th>

    <th>Address</th>

    <th>Mobile</th>

    <th>E-mail</th>

  </tr>

  <% foreach(var person in Model.Results) { %>

  <tr>

    <td class="showContext" id="<%= person.Id %>"><%=person.FullName %></td>

    <td><%=person.ShortName %></td>

    <td><%=person.FullAddress %></td>

    <td><%=person.Mobile %></td>

    <td><%=person.Email %></td>

  </tr>

  <% } %>

</table>

Now we have only one thing to do – we have to write some code that attaches context menu to table cells.

Catching context menu events

Now we will make everything work. Relax, it is only couple of lines of code, thank to jQuery.


<script type="text/javascript">

  $(document).ready(function () {

    $('td.showContext').contextMenu('myMenu1', {

 

      bindings: {

        'email': function (t) {

          document.location.href = '/contact/sendmail/' + t.id;

        },

        'homepage': function (t) {

          document.location.href = '/contact/homepage/' + t.id;

        }

      }

    });

  });

</script>


I think that first lines doesn’t need any comments. Take a look at bindings. We gave ID to table cells because it is carried also to bound events. We can use also more complex ID-s if we have more than one table with context menus on our form.

Now we are done. Save all files, compile solution, run it and try out how context menu works.

Conclusion

We saw than using jQuery with context menu component allows us easily create powerful context menus for our user interfaces. Context menu was very easy to define. We were also able to attach context menu to table and use ID of current row entity also in events of context menu. To achieve this we needed only some minor modifications in view and couple of lines of JavaScript.

Posted: May 22 2010, 09:43 PM by DigiMortal | with 12 comment(s)
Filed under: , ,
Creating vCard action result

I added support for vCards to one of my ASP.NET MVC applications. I worked vCard support out as very simple and intelligent solution that fits perfectly to ASP.NET MVC applications. In this posting I will show you how to send vCards out as response to ASP.NET MVC request.

We need three things:

  1. some vCard class,
  2. vCard action result,
  3. controller method to test vCard action result.

Everything is very simple, let’s get hands on.

vCard class

As first thing we need vCard class. Last year I introduced vCard class that supports also images. Let’s take this class because it is easy to use and some dirty work is already done for us.

NB! Take a look at ASP.NET example in the blog posting referred above. We need it later when we close the topic.

Now think about how useful blogging and information sharing with others can be. With this class available at public I saved pretty much time now. :)

vCardResult

As we have vCard it is now time to write action result that we can use in our controllers. Here’s the code.


public class vCardResult : ActionResult

{

    private vCard _card;

 

    protected vCardResult() { }

 

    public vCardResult(vCard card)

    {

        _card = card;

    }

 

    public override void ExecuteResult(ControllerContext context)

    {

        var response = context.HttpContext.Response;

        response.ContentType = "text/vcard";

        response.AddHeader("Content-Disposition", "attachment; fileName=" + _card.FirstName + " " + _card.LastName + ".vcf");

 

        var cardString = _card.ToString();

        var inputEncoding = Encoding.Default;

        var outputEncoding = Encoding.GetEncoding("windows-1257");

        var cardBytes = inputEncoding.GetBytes(cardString);

 

        var outputBytes = Encoding.Convert(inputEncoding,

                                outputEncoding, cardBytes);

 

        response.OutputStream.Write(outputBytes, 0, outputBytes.Length);

    }

}


And we are done. Some notes:

  1. vCard is sent to browser as downloadable file (user can save or open it with Outlook or any other e-mail client that supports vCards),
  2. File name is made of first and last name of contact.
  3. Encoding is important because Outlook may not understand vCards otherwise (don’t know if this problem is solved in Outlook 2010).

Using vCardResult in controller

Now let’s tale a look at simple controller method that accepts person ID and returns vCardResult.


public class ContactsController : Controller

{
 

    // ... other controller methods ...

 
    public
vCardResult vCard(int id)

    {

        var person = _partyRepository.GetPersonById(id);

        var card = new vCard

                {

                    FirstName=person.FirstName,

                    LastName = person.LastName,

                    StreetAddress = person.StreetAddress,

                    City = person.City,

                    CountryName = person.Country.Name,

 

                    Mobile = person.Mobile,

                    Phone = person.Phone,

                    Email = person.Email,

                };

 

        return new vCardResult(card);
    }

}


Now you can run Visual Studio and check out how your vCard is moving from your web application to your e-mail client.

Conclusion

We took old code that worked well with ASP.NET Forms and we divided it into action result and controller method that uses vCard as bridge between our controller and action result. All functionality is located where it should be and we did nothing complex. We wrote only couple of lines of very easy code to achieve our goal. Do you understand now why I love ASP.NET MVC? :)

Posted: May 22 2010, 05:45 PM by DigiMortal | with 5 comment(s)
Filed under: , ,
Using Sandcastle to build code contracts documentation

In my last posting about code contracts I showed how code contracts are documented in XML-documents. In this posting I will show you how to get code contracts documented with Sandcastle and Sandcastle Help File Builder.

Before we start, let’s download Sandcastle tools we need:

Install Sandcastle first and then Sandcastle Help File Builder. Because we are generating only HTML based documentation we upload to server we don’t need any other tools. Of course, we need Cassini or IIS, but I expect it to be already there in your machine.

Open your project and turn on XML-documentation for project and contracts.

Now let’s run Sandcastle Help File Builder. We have to create new project and add our Visual Studio solution to this project. Now set the HelpFileFormat parameter value to be Website and let builder build the help.

Sandcastle Help File Builder

You have to wait about two or three minutes until help is ready. Take a look at your documentation that Sandcastle generated – you see not much information there about code contracts and their rules.

Enabling code contracts documentation

Now let’s include code contracts to documentation. Follow these steps:

  1. Open Sandcastle folder and make copy of vs2005 folder.
  2. Open CodeContracts folder (c:\program files\microsoft\contracts\) and unzip the archive from sandcastle folder.
  3. Copy all unzipped files to Sandcastle folder.
  4. Create (yes, create new) and build your Sandcastle Help File Builder documentation project again.
  5. Open help.

In my case I see something like this now.

Code contracts are documented

As you can see then contracts are documented pretty well. We can easily turn on code contracts XML-documentation generation and all our contracts are documented automatically. To get documentation work we had to use Sandcastle help file fixes that are installed with code contracts and if we had previously Sandcastle Help File Builder project we had to create it from start to get new rules accepted. Once the documentation support for contracts works we have to do nothing more to get contracts documented.

More Posts Next page »