Rectangle 27 37

Here is an alternative approach that I used to detect the text blocks:

  • Applied threshold (simple binary threshold, with a handpicked value of 150 as the threshold value)
  • Applied dilation to thicken lines in image, leading to more compact objects and less white space fragments. Used a high value for number of iterations, so dilation is very heavy (13 iterations, also handpicked for optimal results).
  • Identified contours of objects in resulted image using opencv findContours function.
  • Drew a bounding box (rectangle) circumscribing each contoured object - each of them frames a block of text.
  • Optionally discarded areas that are unlikely to be the object you are searching for (e.g. text blocks) given their size, as the algorithm above can also find intersecting or nested objects (like the entire top area for the first card) some of which could be uninteresting for your purposes.

Below is the code written in python with pyopencv, it should easy to port to C++.

import cv2

image = cv2.imread("card.png")
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) # grayscale
_,thresh = cv2.threshold(gray,150,255,cv2.THRESH_BINARY_INV) # threshold
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))
dilated = cv2.dilate(thresh,kernel,iterations = 13) # dilate
_, contours, hierarchy = cv2.findContours(dilated,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE) # get contours

# for each contour found, draw a rectangle around it on original image
for contour in contours:
    # get rectangle bounding contour
    [x,y,w,h] = cv2.boundingRect(contour)

    # discard areas that are too large
    if h>300 and w>300:
        continue

    # discard areas that are too small
    if h<40 or w<40:
        continue

    # draw rectangle around contour on original image
    cv2.rectangle(image,(x,y),(x+w,y+h),(255,0,255),2)

# write original image with added contours to disk  
cv2.imwrite("contoured.jpg", image)

The original image is the first image in your post.

After preprocessing (grayscale, threshold and dilate - so after step 3) the image looked like this:

Below is the resulted image ("contoured.jpg" in the last line); the final bounding boxes for the objects in the image look like this:

You can see the text block on the left is detected as a separate block, delimited from its surroundings.

Using the same script with the same parameters (except for thresholding type that was changed for the second image like described below), here are the results for the other 2 cards:

The parameters (threshold value, dilation parameters) were optimized for this image and this task (finding text blocks) and can be adjusted, if needed, for other cards images or other types of objects to be found.

For thresholding (step 2), I used a black threshold. For images where text is lighter than the background, such as the second image in your post, a white threshold should be used, so replace thesholding type with cv2.THRESH_BINARY). For the second image I also used a slightly higher value for the threshold (180). Varying the parameters for the threshold value and the number of iterations for dilation will result in different degrees of sensitivity in delimiting objects in the image.

For example, decreasing the dilation to 5 iterations in the first image gives us a more fine delimitation of objects in the image, roughly finding all words in the image (rather than text blocks):

Knowing the rough size of a word, here I discarded areas that were too small (below 20 pixels width or height) or too large (above 100 pixels width or height) to ignore objects that are unlikely to be words, to get the results in the above image.

You are amazing! I will try this in the morning.

I added another step for discarding uninteresting objects; also added example for identifying words or other types of objects (than blocks of text)

cv2.findContours
ValueError: too many values to unpack

The issue is the function cv2.findContours returns 3 arguments, and the original code captures only 2.

c++ - Extracting text OpenCV - Stack Overflow

c++ opencv image-processing text bounding-box
Rectangle 27 37

Here is an alternative approach that I used to detect the text blocks:

  • Applied threshold (simple binary threshold, with a handpicked value of 150 as the threshold value)
  • Applied dilation to thicken lines in image, leading to more compact objects and less white space fragments. Used a high value for number of iterations, so dilation is very heavy (13 iterations, also handpicked for optimal results).
  • Identified contours of objects in resulted image using opencv findContours function.
  • Drew a bounding box (rectangle) circumscribing each contoured object - each of them frames a block of text.
  • Optionally discarded areas that are unlikely to be the object you are searching for (e.g. text blocks) given their size, as the algorithm above can also find intersecting or nested objects (like the entire top area for the first card) some of which could be uninteresting for your purposes.

Below is the code written in python with pyopencv, it should easy to port to C++.

import cv2

image = cv2.imread("card.png")
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) # grayscale
_,thresh = cv2.threshold(gray,150,255,cv2.THRESH_BINARY_INV) # threshold
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(3,3))
dilated = cv2.dilate(thresh,kernel,iterations = 13) # dilate
_, contours, hierarchy = cv2.findContours(dilated,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE) # get contours

# for each contour found, draw a rectangle around it on original image
for contour in contours:
    # get rectangle bounding contour
    [x,y,w,h] = cv2.boundingRect(contour)

    # discard areas that are too large
    if h>300 and w>300:
        continue

    # discard areas that are too small
    if h<40 or w<40:
        continue

    # draw rectangle around contour on original image
    cv2.rectangle(image,(x,y),(x+w,y+h),(255,0,255),2)

# write original image with added contours to disk  
cv2.imwrite("contoured.jpg", image)

The original image is the first image in your post.

After preprocessing (grayscale, threshold and dilate - so after step 3) the image looked like this:

Below is the resulted image ("contoured.jpg" in the last line); the final bounding boxes for the objects in the image look like this:

You can see the text block on the left is detected as a separate block, delimited from its surroundings.

Using the same script with the same parameters (except for thresholding type that was changed for the second image like described below), here are the results for the other 2 cards:

The parameters (threshold value, dilation parameters) were optimized for this image and this task (finding text blocks) and can be adjusted, if needed, for other cards images or other types of objects to be found.

For thresholding (step 2), I used a black threshold. For images where text is lighter than the background, such as the second image in your post, a white threshold should be used, so replace thesholding type with cv2.THRESH_BINARY). For the second image I also used a slightly higher value for the threshold (180). Varying the parameters for the threshold value and the number of iterations for dilation will result in different degrees of sensitivity in delimiting objects in the image.

For example, decreasing the dilation to 5 iterations in the first image gives us a more fine delimitation of objects in the image, roughly finding all words in the image (rather than text blocks):

Knowing the rough size of a word, here I discarded areas that were too small (below 20 pixels width or height) or too large (above 100 pixels width or height) to ignore objects that are unlikely to be words, to get the results in the above image.

You are amazing! I will try this in the morning.

I added another step for discarding uninteresting objects; also added example for identifying words or other types of objects (than blocks of text)

cv2.findContours
ValueError: too many values to unpack

The issue is the function cv2.findContours returns 3 arguments, and the original code captures only 2.

c++ - Extracting text OpenCV - Stack Overflow

c++ opencv image-processing text bounding-box
Rectangle 27 3

The alternative approach is by editing your web server configuration.

Apache's rewrite rules can do this. You most likely have a .htaccess file in the root directory of your blog. Append the text below to it. If there is no such file, create one.

RewriteEngine On
RewriteCond %{HTTP_HOST} sub.mysite.com
RewriteRule ^(.*)$ http://mysite.com/sub$1 [R=permanent,L]

Your web server has to be configured to accept this configuration from a .htaccess file. It can also be placed in the configuration directly. The procedure for this differs depending on your web host.

thanks so much. i tried the .htaccess method you mentioned, but the old link still redirects to mysite.com/sub (the root - not the full url). i setup the subdomain initially in my hosting control panel. originally i pointed it to a subfolder, and now I'm pointing it to mysite.com/sub. could that be causing it to always go to the root and not the original post?

More likely the web server is not accepting these new rules. Usually you need to restart the web server. If the hosting company has disallowed it, you're out of luck too. I just tested the rules I wrote, they do work.~$ curl -I sub.mysite.com/1/2/3 HTTP/1.1 301 Moved Permanently Location: mysite.com/sub/1/2/3

ok, i reset my subdomain settings on my hosting to point to root. now the rule you posted above does redirect mysite.com/sub to sub.mysite.com, but does not retain the full urls. for example if someone goes to sub.mysite.com/1/2/3 the get a 404 error.

wordpress - redirect subdomain and retain url structure - Stack Overfl...

wordpress .htaccess redirect subdomain
Rectangle 27 5

if one wants to check $exists with in $cond an alternative approach is to use $not with $cond

{$project: {MyKey: {$cond: [{$not: ["$A"]}, "$B", "$A"]}}}

and truth table for $not is as

mongodb - Conditional grouping with $exists inside $cond - Stack Overf...

mongodb mongodb-query
Rectangle 27 4

An alternative approach would be to pass the name of the derived type to ConfigurationManager:

template<typename Derived>
class ConfigurationManager
{
  public:
    static boost::shared_ptr<ConfigurationManager> create();

  template<typename T>
  T getOption(const std::string& name)
  {
    // call Derived::getOption
    return static_cast<Derived*>(this)->getOption(name);
  }
};

The derived type Foo would then be defined like this:

class Foo : public ConfigurationManager<Foo>
{
  template<typename T>
  T getOption(const std::string& name)
  {
    // do something Foo-specific here
  }
};

The end result is something similar to an abstract virtual function. This idiom is referred to as the curiously recurring template pattern.

I know this is old, but what's the point of the ConfigurationManager class in this usage of CRTP? We can't use that type to store Foo.

c++ - Any way to have a template function in an abstract base class? -...

c++ virtual abstract-class
Rectangle 27 34

[Update2] Another simpler alternative approach is to use the autoload-dev directive in composer.json (reference). The benefit is that you don't need to maintain two bootstrap.php (one for prod, one for dev) just in order to autoload different classes.

{
  "autoload": {
    "psr-4": { "MyLibrary\\": "src/" }
  },
  "autoload-dev": {
    "psr-4": { "MyLibrary\\Tests\\": "tests/" }
  }
}

[Update] Wouter J's answer is more complete. But mine can help people who want to set up PSR-0 autoloading in tests/ folder. Phpunit scans all files with this pattern *Test.php. So we don't need to autoload them ourselves. But we still want to autoload other supporting classes under tests/ such as fixture/stub or some parent classes.

An easy way is to look at how Composer project itself is setting up the phpunit test. It's actually very simple. Note the line with "bootstrap".

<?xml version="1.0" encoding="UTF-8"?>

<phpunit backupGlobals="false"
         backupStaticAttributes="false"
         colors="true"
         convertErrorsToExceptions="true"
         convertNoticesToExceptions="true"
         convertWarningsToExceptions="true"
         processIsolation="false"
         stopOnFailure="false"
         syntaxCheck="false"
         bootstrap="tests/bootstrap.php"
>
    <testsuites>
        <testsuite name="Composer Test Suite">
            <directory>./tests/Composer/</directory>
        </testsuite>
    </testsuites>

    <groups>
        <exclude>
            <group>slow</group>
        </exclude>
    </groups>

    <filter>
        <whitelist>
            <directory>./src/Composer/</directory>
            <exclude>
                <file>./src/Composer/Autoload/ClassLoader.php</file>
            </exclude>
        </whitelist>
    </filter>
</phpunit>
<?php

/*
* This file is part of Composer.
*
* (c) Nils Adermann <naderman@naderman.de>
* Jordi Boggiano <j.boggiano@seld.be>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

error_reporting(E_ALL);

$loader = require __DIR__.'/../src/bootstrap.php';
$loader->add('Composer\Test', __DIR__);

The last line above is autoloading phpunit test classes under the namespace Composer\Test.

Also use "require-dev" block instead of "require" block to add phpunit packages in composer.json. You don't want phpunit code installed in production. See composer doc for more info.

namespaces - Autoloading classes in PHPUnit using Composer and autoloa...

php namespaces phpunit autoload composer-php
Rectangle 27 119

Yield gives you a generator.

def get_odd_numbers(i):
    return range(1, i, 2)
def yield_odd_numbers(i):
    for x in range(1, i, 2):
       yield x
foo = get_odd_numbers(10)
bar = yield_odd_numbers(10)
foo
[1, 3, 5, 7, 9]
bar
<generator object yield_odd_numbers at 0x1029c6f50>
bar.next()
1
bar.next()
3
bar.next()
5

As you can see, in the first case foo holds the entire list in memory at once. It's not a big deal for a list with 5 elements, but what if you want a list of 5 million? Not only is this a huge memory eater, it also costs a lot of time to build at the time that the function is called. In the second case, bar just gives you a generator. A generator is an iterable--which means you can use it in a for loop, etc, but each value can only be accessed once. All the values are also not stored in memory at the same time; the generator object "remembers" where it was in the looping the last time you called it--this way, if you're using an iterable to (say) count to 50 billion, you don't have to count to 50 billion all at once and store the 50 billion numbers to count through. Again, this is a pretty contrived example, you probably would use itertools if you really wanted to count to 50 billion. :)

This is the most simple use case of generators. As you said, it can be used to write efficient permutations, using yield to push things up through the call stack instead of using some sort of stack variable. Generators can also be used for specialized tree traversal, and all manner of other things.

python - What does the "yield" keyword do? - Stack Overflow

python iterator generator yield coroutine
Rectangle 27 113

Yield gives you a generator.

def get_odd_numbers(i):
    return range(1, i, 2)
def yield_odd_numbers(i):
    for x in range(1, i, 2):
       yield x
foo = get_odd_numbers(10)
bar = yield_odd_numbers(10)
foo
[1, 3, 5, 7, 9]
bar
<generator object yield_odd_numbers at 0x1029c6f50>
bar.next()
1
bar.next()
3
bar.next()
5

As you can see, in the first case foo holds the entire list in memory at once. It's not a big deal for a list with 5 elements, but what if you want a list of 5 million? Not only is this a huge memory eater, it also costs a lot of time to build at the time that the function is called. In the second case, bar just gives you a generator. A generator is an iterable--which means you can use it in a for loop, etc, but each value can only be accessed once. All the values are also not stored in memory at the same time; the generator object "remembers" where it was in the looping the last time you called it--this way, if you're using an iterable to (say) count to 50 billion, you don't have to count to 50 billion all at once and store the 50 billion numbers to count through. Again, this is a pretty contrived example, you probably would use itertools if you really wanted to count to 50 billion. :)

This is the most simple use case of generators. As you said, it can be used to write efficient permutations, using yield to push things up through the call stack instead of using some sort of stack variable. Generators can also be used for specialized tree traversal, and all manner of other things.

python - What does the "yield" keyword do? - Stack Overflow

python iterator generator yield coroutine
Rectangle 27 51

An alternative approach to the one offered above by Mark Longair is to use an alias that will run any git command, on any remote, with an alternative SSH key. The idea is basically to switch your SSH identity when running the git commands.

Advantages relative to the host alias approach in the other answer:

  • Will work with any git commands or aliases, even if you can't specify the remote explicitly.
  • Easier to work with many repositories because you only need to set it up once per client machine, not once per repository on each client machine.

I use a few small scripts and a git alias admin. That way I can do, for example:

git admin push

To push to the default remote using the alternative ("admin") SSH key. Again, you could use any command (not just push) with this alias. You could even do git admin clone ... to clone a repository that you would only have access to using your "admin" key.

Step 1: Create the alternative SSH keys, optionally set a passphrase in case you're doing this on someone else's machine.

Step 2: Create a script called ssh-as.sh that runs stuff that uses SSH, but uses a given SSH key rather than the default:

#!/bin/bash
exec ssh ${SSH_KEYFILE+-i "$SSH_KEYFILE"} "$@"

Step 3: Create a script called git-as.sh that runs git commands using the given SSH key.

#!/bin/bash
SSH_KEYFILE=$1 GIT_SSH=${BASH_SOURCE%/*}/ssh-as.sh exec git "${@:2}"
# Run git commands as the SSH identity provided by the keyfile ~/.ssh/admin
git config --global alias.admin \!"PATH_TO_SCRIPTS_DIR/git-as.sh ~/.ssh/admin"
$@
"$@"

@sinelaw Does this still work? I get Permission denied error all the time

Specify an SSH key for git push for a given domain - Stack Overflow

git ssh gitolite
Rectangle 27 50

An alternative approach to the one offered above by Mark Longair is to use an alias that will run any git command, on any remote, with an alternative SSH key. The idea is basically to switch your SSH identity when running the git commands.

Advantages relative to the host alias approach in the other answer:

  • Will work with any git commands or aliases, even if you can't specify the remote explicitly.
  • Easier to work with many repositories because you only need to set it up once per client machine, not once per repository on each client machine.

I use a few small scripts and a git alias admin. That way I can do, for example:

git admin push

To push to the default remote using the alternative ("admin") SSH key. Again, you could use any command (not just push) with this alias. You could even do git admin clone ... to clone a repository that you would only have access to using your "admin" key.

Step 1: Create the alternative SSH keys, optionally set a passphrase in case you're doing this on someone else's machine.

Step 2: Create a script called ssh-as.sh that runs stuff that uses SSH, but uses a given SSH key rather than the default:

#!/bin/bash
exec ssh ${SSH_KEYFILE+-i "$SSH_KEYFILE"} "$@"

Step 3: Create a script called git-as.sh that runs git commands using the given SSH key.

#!/bin/bash
SSH_KEYFILE=$1 GIT_SSH=${BASH_SOURCE%/*}/ssh-as.sh exec git "${@:2}"
# Run git commands as the SSH identity provided by the keyfile ~/.ssh/admin
git config --global alias.admin \!"PATH_TO_SCRIPTS_DIR/git-as.sh ~/.ssh/admin"
$@
"$@"

Specify an SSH key for git push for a given domain - Stack Overflow

git ssh gitolite
Rectangle 27 50

An alternative approach to the one offered above by Mark Longair is to use an alias that will run any git command, on any remote, with an alternative SSH key. The idea is basically to switch your SSH identity when running the git commands.

Advantages relative to the host alias approach in the other answer:

  • Will work with any git commands or aliases, even if you can't specify the remote explicitly.
  • Easier to work with many repositories because you only need to set it up once per client machine, not once per repository on each client machine.

I use a few small scripts and a git alias admin. That way I can do, for example:

git admin push

To push to the default remote using the alternative ("admin") SSH key. Again, you could use any command (not just push) with this alias. You could even do git admin clone ... to clone a repository that you would only have access to using your "admin" key.

Step 1: Create the alternative SSH keys, optionally set a passphrase in case you're doing this on someone else's machine.

Step 2: Create a script called ssh-as.sh that runs stuff that uses SSH, but uses a given SSH key rather than the default:

#!/bin/bash
exec ssh ${SSH_KEYFILE+-i "$SSH_KEYFILE"} "$@"

Step 3: Create a script called git-as.sh that runs git commands using the given SSH key.

#!/bin/bash
SSH_KEYFILE=$1 GIT_SSH=${BASH_SOURCE%/*}/ssh-as.sh exec git "${@:2}"
# Run git commands as the SSH identity provided by the keyfile ~/.ssh/admin
git config --global alias.admin \!"PATH_TO_SCRIPTS_DIR/git-as.sh ~/.ssh/admin"
$@
"$@"

Specify an SSH key for git push for a given domain - Stack Overflow

git ssh gitolite
Rectangle 27 2

Alternative approach for a virtual host would be the following

<VirtualHost *:80>
    ServerAdmin info@DOMAIN.com
    ServerName DOMAIN.com
    ServerAlias www.DOMAIN.com
    ProxyRequests off

    <Proxy *>
            Order deny,allow
            Allow from all
    </Proxy>

    <Location />
            ProxyPass http://localhost:3000/
            ProxyPassReverse http://localhost:3000/
    </Location>

</VirtualHost>

To fix the Internal Server ERROR just enable the right apache extension.

sudo a2enmod proxy_http
sudo service apache2 restart

node.js - Avoid the conflict on port 80 between nodejs and apache - St...

apache node.js port express
Rectangle 27 460

Others have pointed out the deleteCharAt method, but here's another alternative approach:

String prefix = "";
for (String serverId : serverIds) {
  sb.append(prefix);
  prefix = ",";
  sb.append(serverId);
}

Alternatively, use the Joiner class from Guava :)

As of Java 8, StringJoiner is part of the standard JRE.

@Coronatus: No, because "" is the absence of any characters, not a single character.

@Harish: Possibly, a tiny, tiny bit - very unlikely to be significant though.

@Harish - and possibly not at all, if the optimizer unrolls the first loop iteration.

Joiner
StringUtils

java - Remove last character of a StringBuilder? - Stack Overflow

java stringbuilder
Rectangle 27 1

Just as an alternative approach to you can do:

WITH inner_table AS
(SELECT A.identifier
    , A.name
    , TO_NUMBER(DECODE( A.month_no
      , 1, 200803 
      , 2, 200804 
      , 3, 200805 
      , 4, 200806 
      , 5, 200807 
      , 6, 200808 
      , 7, 200809 
      , 8, 200810 
      , 9, 200811 
      , 10, 200812 
      , 11, 200701 
      , 12, 200702
      , NULL)) as MONTH_NO
    , TO_NUMBER(TO_CHAR(B.last_update_date, 'YYYYMM')) as UPD_DATE
  FROM table_a A
    , table_b B
  WHERE A.identifier = B.identifier)

    SELECT * FROM inner_table 
    WHERE MONTH_NO > UPD_DATE

Also you can create a permanent view for your queue and select from view.

CREATE OR REPLACE VIEW_1 AS (SELECT ...);
SELECT * FROM VIEW_1;

sql - Using an Alias in a WHERE clause - Stack Overflow

sql oracle alias decode ora-00904
Rectangle 27 3

An alternative approach would be to use Restful Urls to invoke the appropriate controller action and view.

This makes the urls reflect what you are seeing on the screen and makes the design more extensible; should you need to add other views of the data in the future (summary, latest, etc) you add the new view, no need for partials unless the main body of the view gets more complicated and has to be factored out to a partial view.

~/product/1/detail

~/product/1/thumbnail
public ActionResult Detail(String id)
{
    var products = productRepository.GetProducts(id).ToList();
    return View("Detail", products);
}

public ActionResult Thumbnail(string id)
{
    var products = productRepository.GetProducts(id).ToList();
    return View("Thumbnail", products);
}

You enable the routing with a route like:

{controller}/{id}/{action}

ASP.Net MVC Passing multiple parameters to a view - Stack Overflow

asp.net-mvc views partial-views
Rectangle 27 13

Since this question asked almost 2 years ago. Things are getting different or there are alternative approaches to multithreading problem on Node.JS

According to below blog post, using the incoming 'task' extension, some can benefit from other available cores directly.

node.js - Grasping the Node JS alternative to multithreading - Stack O...

multithreading node.js
Rectangle 27 13

Since this question asked almost 2 years ago. Things are getting different or there are alternative approaches to multithreading problem on Node.JS

According to below blog post, using the incoming 'task' extension, some can benefit from other available cores directly.

node.js - Grasping the Node JS alternative to multithreading - Stack O...

multithreading node.js
Rectangle 27 15

There is an alternative approach, which does not have I18n problems (allowing ',' or '.' but not both): Decimal.TryParse.

Just try converting, ignoring the value.

bool IsDecimalFormat(string input) {
  Decimal dummy;
  return Decimal.TryParse(input, out dummy);
}

(The overload of Decimal.TryParse can be used for finer control.)

Code (PerformanceHelper.Run is a helper than runs the delegate for passed iteration count and returns the average TimeSpan.):

using System;
using System.Text.RegularExpressions;
using DotNetUtils.Diagnostics;

class Program {
    static private readonly string[] TestData = new string[] {
        "10.0",
        "10,0",
        "0.1",
        ".1",
        "Snafu",
        new string('x', 10000),
        new string('2', 10000),
        new string('0', 10000)
    };

    static void Main(string[] args) {
        Action parser = () => {
            int n = TestData.Length;
            int count = 0;
            for (int i = 0; i < n; ++i) {
                decimal dummy;
                count += Decimal.TryParse(TestData[i], out dummy) ? 1 : 0;
            }
        };
        Regex decimalRegex = new Regex(@"^[0-9]([\.\,][0-9]{1,3})?$");
        Action regex = () => {
            int n = TestData.Length;
            int count = 0;
            for (int i = 0; i < n; ++i) {
                count += decimalRegex.IsMatch(TestData[i]) ? 1 : 0;
            }
        };

        var paserTotal = 0.0;
        var regexTotal = 0.0;
        var runCount = 10;
        for (int run = 1; run <= runCount; ++run) {
            var parserTime = PerformanceHelper.Run(10000, parser);
            var regexTime = PerformanceHelper.Run(10000, regex);

            Console.WriteLine("Run #{2}: Decimal.TryParse: {0}ms, Regex: {1}ms",
                              parserTime.TotalMilliseconds, 
                              regexTime.TotalMilliseconds,
                              run);
            paserTotal += parserTime.TotalMilliseconds;
            regexTotal += regexTime.TotalMilliseconds;
        }

        Console.WriteLine("Overall averages: Decimal.TryParse: {0}ms, Regex: {1}ms",
                          paserTotal/runCount,
                          regexTotal/runCount);
    }
}

Thats not only faster, its much cleaner.

c# - Regular expression for decimal number - Stack Overflow

c# regex decimal
Rectangle 27 41

I'm not sure if this refers to exactly the same dialog but here is an alternative approach from Raymond Chen:

DWORD dwMode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
SetErrorMode(dwMode | SEM_NOGPFAULTERRORBOX);

Yes, calling SetErrorMode like that prevents the WER dialog mentioned by the OP.

The problem I have with SetErrorMode and the SEM_NOGPFAULTERRORBOX flag is that it doesn't create a dump file and make an entry in the Windows Event Log. Your program will just disappear without a trace when it crashes. For this reason I think the registry solution is better.

testing - How do I disable the 'Debug / Close Application' dialog on W...

windows testing windows-vista crash-reports windows-error-reporting
Rectangle 27 122

My original answer (below) was over 3 years old, so I thought I would update as I no longer create files on the server when downloading files via AJAX however, I have left the original answer as it may be of some use still depending on your specific requirements.

A common scenario in my MVC applications is reporting via a web page that has some user configured report parameters (Date Ranges, Filters etc.). When the user has specified the parameters they post them to the server, the report is generated (say for example an Excel file as output) and then I store the resulting file as a byte array in the TempData bucket with a unique reference. This reference is passed back as a Json Result to my AJAX function that subsequently redirects to separate controller action to extract the data from TempData and download to the end users browser.

To give this more detail, assuming you have a MVC View that has a form bound to a Model class, lets call the Model ReportVM.

First, a controller action is required to receive the posted model, an example would be:

public ActionResult PostReportPartial(ReportVM model){

   // Validate the Model is correct and contains valid data
   // Generate your report output based on the model parameters
   // This can be an Excel, PDF, Word file - whatever you need.

   // As an example lets assume we've generated an EPPlus ExcelPackage

   ExcelPackage workbook = new ExcelPackage();
   // Do something to populate your workbook

   // Generate a new unique identifier against which the file can be stored
   string handle = Guid.NewGuid().ToString();

   using(MemoryStream memoryStream = new MemoryStream()){
        workbook.SaveAs(memoryStream);
        memoryStream.Position = 0;
        TempData[handle] = memoryStream.ToArray();
   }      

   // Note we are returning a filename as well as the handle
   return new JsonResult() { 
         Data = new { FileGuid = handle, FileName = "TestReportOutput.xlsx" }
   };

}

The AJAX call that posts my MVC form to the above controller and receives the response looks like this:

$ajax({
    cache: false,
    url: '/Report/PostReportPartial',
    data: _form.serialize(), 
    success: function (data){
         var response = JSON.parse(data);
         window.location = '/Report/Download?fileGuid=' + response.FileGuid 
                           + '&filename=' + response.FileName;
    }
})

The controller action to handle the downloading of the file:

One other change that could easily be accommodated if required is to pass the MIME Type of the file as a third parameter so that the one Controller action could correctly serve a variety of output file formats.

This removes any need for any physical files to created and stored on the server, so no housekeeping routines required and once again this is seamless to the end user.

Note, the advantage of using TempData rather than Session is that once TempData is read the data is cleared so it will be more efficient in terms of memory usage if you have a high volume of file requests. See TempData Best Practice.

You can't directly return a file for download via an AJAX call so, an alternative approach is to to use an AJAX call to post the related data to your server. You can then use server side code to create the Excel File (I would recommend using EPPlus or NPOI for this although it sounds as if you have this part working).

Once the file has been created on the server pass back the path to the file (or just the filename) as the return value to your AJAX call and then set the JavaScript window.location to this URL which will prompt the browser to download the file.

From the end users perspective, the file download operation is seamless as they never leave the page on which the request originates.

Below is a simple contrived example of an ajax call to achieve this:

$.ajax({
    type: 'POST',
    url: '/Reports/ExportMyData', 
    data: '{ "dataprop1": "test", "dataprop2" : "test2" }',
    contentType: 'application/json; charset=utf-8',
    dataType: 'json',
    success: function (returnValue) {
        window.location = '/Reports/Download?file=' + returnValue;
    }
});
  • url parameter is the Controller/Action method where your code will create the Excel file.
  • data parameter contains the json data that would be extracted from the form.
  • returnValue would be the file name of your newly created Excel file.
  • The window.location command redirects to the Controller/Action method that actually returns your file for download.

A sample controller method for the Download action would be:

[HttpGet]
public virtual ActionResult Download(string file)
{   
  string fullPath = Path.Combine(Server.MapPath("~/MyFiles"), file);
  return File(fullPath, "application/vnd.ms-excel", file);
}

This looks like a good potential option, but before I go ahead with it, are there no other alternatives that don't involve creating the file on the server first?

Not that I am aware of - this approach I have used successfully many times. From the users perspective it is seamless, the only thing to be mindful of is that you will need a housekeeping routine to tidy up the files that are created as they will mount up over time.

Creating an endpoint '/Download?file=...' SCREAMS massive security risk - I'm no security expert but I'd think you'd want to add user authentication, input sanitation, MVC's [ValidateAntiForgeryToken] and mention other security best-practices to this answer.

Great, why don't you put the old answer at the bottom? And the new answer at the top, so people don't waste time

c# - Download Excel file via AJAX MVC - Stack Overflow

c# jquery asp.net-mvc vb.net export-to-excel