Rails Flash Messages in MVC4

Hey everyone,

Coming from Rails I’d grown quite fond of flash messages. Unfortunately there isn’t a built in way of doing this in MVC4. Luckily, there’s a five minute solution posted on StackOverflow: http://stackoverflow.com/a/11809178/522859

Once implemented, it works just like in Rails:

this.Flash("We need you to login before you can edit anything.", FlashEnum.Warning);

Definitely worth checking out if you’ve got time, even more so if you’ve come over from Rails!

Working IPN Handler with Parallel Payments – PayPal Adaptive Payments

Hey everyone,

Just a dummy implementation of a Parallel Payment and an accompanying IPN Handler using the C#/.NET SDK. Feel free to use it however you like.

//Handles PayPal IPN
        public String IPN()
        {
            //Post back to either sandbox or live
            string strSandbox = "https://www.sandbox.paypal.com/cgi-bin/webscr";
            //string strLive = "https://www.paypal.com/cgi-bin/webscr";
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(strSandbox);

            ////Set values for the request back
            req.Method = "POST";
            req.ContentType = "application/x-www-form-urlencoded";
            byte[] param = Request.BinaryRead(Request.ContentLength);
            string strRequest = Encoding.ASCII.GetString(param);
            strRequest += "&cmd=_notify-validate";
            req.ContentLength = strRequest.Length;

            //Send the request to PayPal and get the response
            StreamWriter streamOut = new StreamWriter(req.GetRequestStream(), System.Text.Encoding.ASCII);
            streamOut.Write(strRequest);
            streamOut.Close();
            StreamReader streamIn = new StreamReader(req.GetResponse().GetResponseStream());
            string strResponse = streamIn.ReadToEnd();
            streamIn.Close();

            if (strResponse == "VERIFIED")
            {
                //check the payment_status is Completed
                //check that txn_id has not been previously processed
                //check that receiver_email is your Primary PayPal email
                //check that payment_amount/payment_currency are correct
                //process payment
            }
            else if (strResponse == "INVALID")
            {
                //log for manual investigation
            }
            else
            {
                //log response/ipn data for manual investigation
            }


            return "";
        }

        //Pay for an order
        public void Pay(int OrderId)
        {
            RequestEnvelope envelopeRequest = new RequestEnvelope();
            envelopeRequest.errorLanguage = "en_US";
            PaySample paySample = new PaySample();
           
            List listReceiver = new List();
            // Amount to be credited to the receiver's account
            Receiver receiverA = new Receiver(Convert.ToDecimal("4.00"));

            // A receiver's email address
            receiverA.email = "test_buyer1@learnerlessons.com.au";
            listReceiver.Add(receiverA);

            // Amount to be credited to the receiver's account
            Receiver receiverB = new Receiver(Convert.ToDecimal("2.00"));

            // A receiver's email address
            receiverB.email = "test_buyer2@learnerlessons.com.au";
            listReceiver.Add(receiverB);

            ReceiverList receiverList = new ReceiverList(listReceiver);

            PayRequest requestPay = new PayRequest(envelopeRequest, "PAY", "http://localhost:53034/orders/cancel", "AUD", receiverList, "http://localhost:53034/orders/return");
            requestPay.reverseAllParallelPaymentsOnError = true;
            requestPay.ipnNotificationUrl = "http://123.123.123.123/Orders/IPN";

            //Send request to paypal, retrieve payKey
            PayResponse payResponse = paySample.PayAPIOperations(requestPay);

            Response.Redirect("https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_ap-payment&paykey=" + payResponse.payKey);
        }

Missing Partial (JSON Response) – Ruby on Rails

Hey everyone,

I’ve just added pagination (Kaminari) to make an infinite scroll list a little easier to use. Unfortunately, I ran into the following error – had me stumped for a while:

Missing partial /contents/content_list_item with {:locale=>[:en], :formats=>[:json], :handlers=>[:erb, :builder, :coffee]}. Searched in:  * "/home/chris/funny/app/views"  * "/home/chris/.rvm/gems/ruby-1.9.3-p327/gems/kaminari-0.14.1/app/views"

The solution was fairly simple, but adding a few things at once had me looking at it the wrong way. Because I was using the same nested partials for an HTML response as my JSON one, the file extensions weren’t what rails was expecting. To get around this, all I needed to do was fully qualify the partial filenames. For instance:

#The original
 '/contents/content_list_item', :locals => { :@content_item =>  content} %>

#Became this
 '/contents/content_list_item.html.erb', :locals => { :@content_item => content} %>

Warning: S3::putObject(): RequestTimeTooSkewed – CarrierWave (Ruby on Rails)

Hey everyone,

Another issue I came across while working with CarrierWave. After rebooting a VM Amazon started too complain “request time too skewed”:

Warning: S3::putObject(): RequestTimeTooSkewed The difference between the request time and the current time is to large. in x on line 14

This one is another simple fix, just make sure your system time is correct. I’d been using a VM and it had run forward by a few hours. Setting it back manually resolved the error.

Amazon S3 Images Expiring – CarrierWave (Ruby on Rails)

Hey everyone,

After working with CarrierWave for a couple of days a few of my images started disappearing. It took a while to work out what was causing it, but thankfully the fix is pretty easy:


#Set fog_public in your initialiser to true
config.fog_public = false

#Should be
config.fog_public = true

Alternatively, if you’d like them to keep expiring but want to adjust their availability you can use the following config option:

#Number of seconds
config.fog_authenticated_url_expiration = 60000 

There’s a bit of info in the following StackOverflow post: http://stackoverflow.com/a/13757841/522859

Excon::Errors::SocketError Broken pipe (Errno::EPIPE) – Ruby on Rails

Hey everyone,

I was having a bit of trouble with CarrierWave on Amazon S3 today. When attempting to upload files that were larger than ~150kb I received one of the following errors (depending on config):

getaddrinfo: Name or service not known carrierwave
Excon::Errors::SocketError in PhotosController#create
Broken pipe (Errno::EPIPE)

 

Despite the vague error, the solution was fairly simple. The region configured in my initialiser was different to the one my bucket was created in.

In order to find out which region you need, logon to your AWS console and browse to an uploaded image. Check the endpoint URL (properties > static website hosting) and simply copy the region. For examples:

Endpoint: testbucket123321.s3-website-us-west-2.amazonaws.com
Region: us-west-2

A couple of final tips if this doesn’t work for you:

  • You need the region codes, not the name. For instance, “Oregon” won’t work
  • Don’t forget to restart your app after making changes to the initialiser
  •  

    Remote JSON Source – Ruby on Rails

    Hey everyone,

    Just a quick post on how to retrieve a remote JSON source so I don’t forget.

    require 'open-uri'
    require 'json'
    
    #Retrieve source (controller/model)
    @results = JSON.parse(open("http://www.myjsonsource.com/jsonfeed_num1").read)
    
    
    #In view
    
       
    
    

    That’s all there is to it, let me know if you have any problems!

    Simple Staging/Test Environment with Heroku – Ruby on Rails

    Hey everyone,

    This is just a quick guide on how to create a test/staging environment with Heroku.

    -- Create staging environment
    heroku create --remote staging
    
    -- Push to staging app
    heroku push staging master
    
    -- Run rake db:migrate on staging app
    heroku run rake db:migrate --remote staging
    
    -- Add pgbackups add ons
    heroku addons:add pgbackups --remote staging
    heroku addons:add pgbackups --remote heroku
    
    -- Create backup of production data
    heroku pgbackups:capture --remote heroku
    
    -- Copy to staging environemnt
    heroku pgbackups:restore DATABASE `heroku pgbackups:url --remote heroku` --remote staging
    
    -- Create a new config file called staging.rb (/config/environments/staging.rb)
    
    -- Add environment variables
    heroku config:add RACK_EVN=staging RAILS_ENV=staging --remote staging
    
    -- Ready to go !
    

    For those of you using git branches etc, the following may come in handy as well:

    -- Create local development branch
    git branch development
    
    -- Switch to dev branch
    git checkout development
    
    -- Make your changes and commit them
    git init
    git add .
    git commit -m "My changes"
    
    -- Push to staging environment (local development branch to staging environment master branch)
    git push staging development:master
    

    If you run into any trouble, I found the following links pretty helpful:

    http://stackoverflow.com/a/6931462/522859
    https://devcenter.heroku.com/articles/pgbackups#transfer
    https://devcenter.heroku.com/articles/multiple-environments

    Let me know if you’ve got anything to add.

    Assets:Precompile (Rake Aborted) – Heroku

    Hey everyone,

    I ran into the following error over the weekend while trying to push to heroku:

    Running: rake assets:precompile
    rake aborted!
    could not connect to server: Connection refused
    Is the server running on host “127.0.0.1” and accepting
    TCP/IP connections on port 5432?

    This stackoverflow post helped to solve the issue. All you need to do is add the following line to your application.rb file:

    #Applicication.rb
    config.assets.initialize_on_precompile = false
    

    Let me know if you have any problems.