All posts tagged c#

Joe Blogs Wrapper V2 – Help required

I’m on the verge of being able to release a second, much improved version of the Joe Blogs WordPress & MetaWeblog API Wrapper.

Some very brief details below, and a cry for help (or several cries!)

New Features / Improvements

Friendlier API
Instead of having to deal with the XML-RPC interfaces directly, I’ve added a “friendly” layer of classes on top.
The WordPressWrapper class has helper methods, with friendly properties, for doing things like uploading files etc…

  • More examples
    The sample project (console application) included in the project demonstrates all methods and features of the library.
  • Better documentation
    XML RPC Comments on all the public properties and methods

Help required

I need help with some of the following, both for this version, and subsequent versions

  • PHP WordPress Re-install script
    Script (configured as CRON job) to “refresh” test install of WordPress (every couple of hours or something)
  • Unit Tests
    Need better code coverage., and more integration tests
    I’m not TDD expert, so unfortunately, a lot of this will be retro-fitting unit tests into the current code.
  • WordPress Plugin development
    I plan to release an “extended” version of XML RPC – with some enhanced methods in, for use with JoeBlogs – for example “GetRecentPosts”
  • ASP.Net Demo Project
    Eventually, and ASP.net MVC “blog” project, running from WordPress – for no other reason than “it can be done”
  • Moving project to GitHub
    See below
  • General code improvement
    Refactoring, performance enhancements, etc…
  • Logo Designed
    ‘cos every cool open source project has to have a cool logo, right?
  • Website
    I’ve dipped my hand into my pocket, and bought joeblogswrapper.org (under £7 – GoDaddy)
    Will have a site dedicated to it on there soon. Obvious CMS choice would be WordPress, but if anyone can think of a better option for Wiki style pages, I’m all ears
    (Media wiki..? What are the benefits?)

Mailing List

I’ve created a Google Group – http://groups.google.com/group/joeblogs/
Please, sign up on there for announcements (I’ll announce when the next versions of the wrapper are available)

GitHub

I really like the idea of moving this project over to GitHub.

Problem is, I have absolutely no experience using Git.

I’ve tried following the instructions, and got as far as some files imported into my repository.. but I can’t get it to work, or commit my changes.

If anyone would like to offer their hand-holding expertise on getting this moved over (and training me on committing files etc…) then I’ll gladly move it to GitHub, which long term, I believe could be beneficial to the overall development of the project.

Get in touch

If you’d like to help with ANY of the above (or anything I’ve missed for that matter) please get in touch, or use the Google Group

C# – String.Concat vs String.Join

I had a quick Google search for a comparison between string.concat and string.join, but I couldn’t find anything.

Say you want to construct the sentence “The quick brown fox jumps over the lazy dog”

This is comprised of 9 words, 8 spaces.

Using string.concat:

public void CreateSentanceUsingStringConcat()
{
    string space = " ";
    string the = "the";
    string quick = "quick";
    string brown = "brown";
    string fox = "fox";
    string jumps = "jumps";
    string over = "over";
    string lazy = "lazy";
    string dog = "dog";

    var result = string.Concat(the, space, quick, space, brown, space, fox, space, jumps, space, over, space, the, space, lazy, space, dog);
}

Using string.join

public void CreateSentanceUsingStringJoin()
{
    var result = string.Join(space, the, quick, brown, fox, jumps, over, the, lazy, dog);
}

With string.concat, we must explicitly add the separator (in our case, space) between each string.

String.join however, allows us to specify the separator as the first parameter.

Performance

I wrote a small benchmark test on the two (see bottom of this post for code)

We can see string.concat consistently performs better

 string.join - 516ms / string.concat - 329ms

Benchmark Code:

class Program
{
    const int m = 1000000;

    const string space = " ";
    const string the = "the";
    const string quick = "quick";
    const string brown = "brown";
    const string fox = "fox";
    const string jumps = "jumps";
    const string over = "over";
    const string lazy = "lazy";
    const string dog = "dog";

    const string expected = "the quick brown fox jumps over the lazy dog";

    static void Main()
    {
        Console.WriteLine("Pass #1");
        Go();
        Console.WriteLine();
        Console.WriteLine("Pass #2");
        Go();
        Console.WriteLine();
        Console.WriteLine("Pass #3");
        Go();

        Console.Read();
    }

    private static void Go()
    {
        Stopwatch s1 = Stopwatch.StartNew();

        for (int i = 0; i < m; i++)
            string.Concat(the, space, quick, space, brown, space, fox, space, jumps, space, over, space, the, space, lazy, space, dog);

        s1.Stop();

        Stopwatch s2 = Stopwatch.StartNew();
        for (int i = 0; i < m; i++)
            string.Join(space, the, quick, brown, fox, jumps, over, the, lazy, dog);

        s2.Stop();

        Console.WriteLine("string.join - {0}", s1.ElapsedMilliseconds);
        Console.WriteLine("string.concat- {0}", s2.ElapsedMilliseconds);
    }
}

Implementing DataCash 3D Secure with ASP.net

This is an article I’ve been meaning to write for a while now…

Mainly, to help others out, who are struggling with the near non-existent documentation provided by Datacash, when trying to plug 3D Secure into my ASP.net application.

I’m sure you’re already familiar with what 3D Secure is, so I won’t go in to too much detail, nor will I go into much detail with regards to the process.

The purpose of this article is to get you familiar with how to send the details to the DataCash MPI, receive a response, and display and use the 3D Secure window in an iFrame (or framed window for that matter)

Please note:
This code is for tutorial purposes only. It’s dirty, crude, buggy, and not refactored in any way shape or form.
I simplified the code down to bare bones, in order to better explain each element.
Obviously, it comes without warranty… it should work as expected, but has no logging, error trapping or any of that good stuff… and when dealing with online payments, you really should take more care!

Code

Update – 8th September, 2011:

GitHubI’ve now hosted the code on GitHub

You will need to edit the web.config to add your own VTID and Password

Donate

btn_donate_SMI don’t normally do this, but this article took me literally months to pull together, so any small contribution would be gratefully received!


Payment Page

This is the functionality that processes payment – for example, allows the customer to enter their credit card details etc…

The mark-up is fairly straight forward.

Two things to note are the body, and the form tag:

<body id="myBody" runat="server">

Note that the body tag is runat server

<form id="MainForm" runat="server">

Note that  the name is “MainForm” – we will need this later.

Since in this tutorial, I’m showing how to use an iFrame, I have this bit of code, below the payBtn:

<asp:Panel ID="ACSFramePanel" runat="server" Visible="false">
    Please verify.....<br />
    <br />
    <iframe src="" name="ACSFrame" width="450" height="400" frameborder="0" />
</asp:Panel>

Line 4 of the above is basically where the 3D Secure frame will appear.

I wrapped it in a Panel, so that we can hide it, while the customer enters their card details etc…

Now, let’s look at some of the code-behind:

private Config config;
private Agent agent;

//this would be our order id / reference in production
private string ourReference = Guid.NewGuid().ToString("n").Substring(0, 8);

protected void Page_Load(object sender, EventArgs e)
{
    config = new Config(AppDomain.CurrentDomain.BaseDirectory + "datacash.conf"); // would probably need to come from web.config
    agent = new Agent(config);
}

In the above code, Config and Agent are both DataCash objects.

In the Page_Load event, we basically set these two objects up.

config is set from an xml file (located in the project root) called datacash.conf – this can of course be located anywhere you like (and called anything you like)

agent is then set using the defined config object.

The config file looks like this:

<Configuration>
  <logfile>datacash.log</logfile>
  <logging>5</logging>
  <Obscure>
    <element>Transaction.CardTxn.Card.pan</element>
    <element>Authentication.password</element>
    <element>Transaction.CardTxn.Card.Cv2Avs.cv2</element>
  </Obscure>

  <!--this would be for the live server-->
  <!--<host>https://mars.transaction.datacash.com/Transaction</host>-->

  <host>https://testserver.datacash.com/Transaction</host>
  <port>443</port>
  <timeout>90</timeout>
  <setstrict>true</setstrict>
</Configuration>

Of course, this doesn’t have to be done in Page_Load – in “the real world” this would all be part of a payment helper class. But for demo purposes, it’s fine in the Page_Load – just means we have to repeat ourselves on other pages…

Next, we assume the user fills out the form, and presses the Pay button.

Sending the request to DataCash

protected void payBtn_Click(object sender, EventArgs e)
{
    //so they don't press the button twice.
    payBtn.Enabled = false;

    //get browser info (for 3d secure stuff)
    var browser = Request.Browser.Browser;

    var request = buildAuthDataCashDocument(
        ourReference,
        cardNumber.Text,
        expiryMonth.Text,
        expiryYear.Text,
        startMonth.Text,
        startYear.Text,
        issueNumber.Text,
        secCode.Text,
        billingAddress1.Text,
        billingAddress2.Text,
        billingAddress3.Text,
        billingAddress4.Text,
        billingAddressPostCode.Text,
        browser);

    //send the request document to the agent.
    //todo: could implement some kind of error trapping / retry here
    var authResponse = agent.send(request);

    //get the datacash transaction reference (just in case we need to try authorizing the payment without 3D Secure)
    var datacashRef = authResponse.get("Response.datacash_reference");

    //get the response code
    var responseCode = authResponse.get("Response.status");

This code basically generates a XML document with the payment authorisation request, and submits it to DataCash.

I refactored buildAuthDataCashDocument as it was pretty large, and made the code a bit too dirty, even for this demo!

Couple of bits of note within buildAuthDataCashDocument are:

request.set("Request.Authentication.client", ConfigurationManager.AppSettings["DataCashVtid"]);
request.set("Request.Authentication.password", ConfigurationManager.AppSettings["DataCashPassword"]);

This basically sets the VTID and Password from config (in our case, web.config) which looks like:

<appSettings>
   <add key="DataCashVtid" value="99******"/>
   <add key="DataCashPassword" value="bK*******"/>
</appSettings>

Also, within buildAuthDataCashDocument is:

request.set("Request.Transaction.TxnDetails.ThreeDSecure.verify", "yes");
request.set("Request.Transaction.TxnDetails.ThreeDSecure.merchant_url", "www.crocus.co.uk"); //or whatever brand??
request.set("Request.Transaction.TxnDetails.ThreeDSecure.purchase_desc", "Items from Crocus"); //or some other short sumary
request.set("Request.Transaction.TxnDetails.ThreeDSecure.purchase_datetime", DateTime.Now.ToString("yyyyMMdd HH:mm:ss"));

This is important, for 3D Secure – Fairly self explanatory.

After building our request Document, we need to send it to DataCash, and get another Document back – as a response.

To do that, it’s as simple as:

var authResponse = agent.send(request);

This sets authResponse to the response Document.

We can then use the .get() method on authResponse to retrieve elements from it.

We are most interested in Response.datacash_reference and Response.status

The datacash_reference is unique to each and every transaction processed, so it is useful for later things like refunds, reporting etc…

Response.status is the DataCash status code for this transaction.

It’s from this, that we determine how to proceed.

switch (responseCode)
{
    //handle 3DS error responses....`
    //Basically, if it's one of these, the transaction is screwed, and shouldn't proceed....
    case "151": 		//	3DS Invalid Transaction type
    case "152": 		//	3DS Manual Authorization not supported
    case "153": 		//	3DS verify element missing
    case "154": 		//	3DS Invalid verify value
    case "155": 		//	3DS field missing
    case "156": 		//	3DS Invalid Browser.device_category
    case "157": 		//	3DS Merchant not enabled
    case "159": 		//	3DS No VERes from DS
    case "160": 		//	3DS Invalid VERes from DS
    case "161": 		//	3DS call auth centre

        //log the error here
        break; //- throw them out of transaction process. Should redirec

    case "56": //speed limit - too many transactions on that card number in short space of time
        break;

    //3ds payer verification required....
    case "60":
    case "150":
        show3DSIframe(authResponse);
        Response.Clear();
        break;
}

I won’t go in to too much detail, as the comments kind of speak for themselves…

Basically, if you get a 60 or 150 then the transaction requires you to show the 3D Secure window.

Showing the 3D Secure iFrame

I’ll spend a bit of time on show3DSIframe, as this is the part that caused me the most hassle – How to actually display the ACS in an iFrame, especially in ASP.net

private void show3DSIframe(Document doc)
{
    ACSFramePanel.Visible = true;

    //this is the data cash reference number for this transaction
    var dataCashReference = doc.get("Response.datacash_reference");

    //this is the url of the ACS - the page generated by the bank, that contains the
    //boxes where the customer enters information etc...
    var acsUrl = doc.get("Response.CardTxn.ThreeDSecure.acs_url");

    //this is a long message / code that is generated for the transaction
    var pareq = doc.get("Response.CardTxn.ThreeDSecure.pareq_message");

Ok, so in the markup from Part 1, you may remember I wrapped the iFrame in a Panel, called ACSFRamePanel. Now, we need to set the visibility to true.

These first few lines are self explanatory – we need to get the dataCashReference, acsUrl (the URL of the 3D Secure page – this is usually returned by the customers issuing bank) and the pareq – this is a long string, that’s a bit like a password for the transaction.

These elements are retrieved from the passed in DataCash Document.

We then need to create our Term URL – This is basically a URL that the 3D Secure window POSTs back to:

var termUrlPrefix = Request.ServerVariables["HTTPS"] == "ON" ? "https://" : "http://";

//termUrl is where the ACS page posts back to.
var termUrl = string.Format("{0}{1}",
    termUrlPrefix,
    Request.Url.Authority + "/3DSResponse.aspx");

In our demo case, it’s just on our local host machine – this could however, for example, be something like www.myUrl.com/checkout/3DSresponse.aspx

This next part is the important part.

This set’s the required hidden fields (PaReq and TermUrl) on our form.

We then register another hidden form – “MD” – This is our order number / reference for this transaction – so we can retrieve it from our database, and update the status when we come out the other side of 3D Secure.

The next line generates a little bit of JavaScript that basically causes this form to submit itself to the acs url.

The result of this, is then output to the target (parameter 3 in our string.format) – ACSFrame.

Remember we called our form “MainForm” :-)

Then, myBody.Attributes.Add inserts the resulting JavaScript to the onLoad function of our body tag.

Remember we made runat server earlier

//ClientScript.RegisterHiddenField adds a hidden field to the form...
ClientScript.RegisterHiddenField("PaReq", pareq);
ClientScript.RegisterHiddenField("TermUrl", termUrl);

//this is the data cash reference, and our reference -
//so we can update the order on the other side of the verification (paid, failed etc...)
ClientScript.RegisterHiddenField("MD", dataCashReference + "|" + ourReference);

var js = string.Format("javascript: document.{0}.action='{1}'; document.{2}.target=\"{3}\"; document.{4}.submit();",
    MainForm.ID,
    acsUrl,
    MainForm.ID,
    "ACSFrame",
    MainForm.ID
);

//since the body tag of this page is called myBody, and is runat=server, we can access
//it here, and inject our javascript.
myBody.Attributes.Add("onLoad", js);

And there we have it – the 3D Secure window is displayed in an iFrame

I’ll edit this post with a link to 3DSResponse.aspx when I finish that article…

Hope this helps! Feel free to ;-)

btn_donate_SM

Creating a new post in WordPress using the JoeBlogs library

A few people have recently been asking how the NewPost method works within JoeBlogs

First, you need to create an instance of Post.

Then, set the following properties:

dateCreated
Fairly self explanatory, but you should set this to today’s date (or whatever date you wish the post to be set as published)

title
The title of the post

description
The body of the post.
This can of course contain HTML

categories
This is a string array of categories to associate with the post

mt_keywords
Another string array, representing the tags for the post

Then, using your presumably already instantiated Wrapper class, you can call the NewPost method, which takes the above Post object as a parameter, and a boolean – indicating if the post is to be set as published. Note – if this is set to false, the post is set in draft mode.

Here’s some sample code:

//create a new post
var post = new Post();

//since this is a struct, we can't have a constructor that does this!
post.dateCreated=DateTime.Now;
post.title="This is a title";
post.description="this is the body of the post. it <strong>could</strong> be html.";

//create the post!
wp.NewPost(post,true);

Hope this helps!

NVelocity template with decimal to two decimal places

I wanted to be able to output a decimal value from an object in my NVelocity template.

For example, the value of the decimal was: 3.40000 to represent 3.4.

The end result:

Total Order Value: 3.40 GBP

I needed to display this as currency format. Sure, I could of used this String.Format method, but that adds £ or $ or whatever (depending on your environment setup) to the start of the resulting string.

In the end, I used ToString with “N2” formatter.

So, in my nVelocity template, here is what I would use:

Total Order Value: $Order.GrandTotal.ToString("N2") GBP

There are some other alternatives discussed here:
http://stackoverflow.com/questions/1048643/format-a-double-value-like-currency-but-without-the-currency-sign-c