Solving development problems  |  About this blog

Archive for the ‘Web Services’ Category

The easiest way to generate a QR Code for software developers

So you want to simply generate a QR Code image without diving into the technical specifics? This blog post contains a few simple examples. Just copy-paste where you need it.

Idea is to build a URL, make an HTTP request and download the QR Code image. Result is the following image:

your content goes here

HTTP Request

URL looks like http://www.esponce.com/api/v3/generate?content={content}&format={format} where {content} is URL encoded content to be embedded in QR and {format} is output image format. Available formats are png, jpg, bmp, tif, xaml, svg, eps, txt, html, zip (containing all listed formats)

List of other parameters like color and size can be found here.

C# Sample

This code can be used in .NET 2.0 including ASP.NET and WPF or Silverlight for web or WP7

using System;
using System.IO;
using System.Web;
using System.Net;

public class Program
{
  public static void Main(string[] args)
  {
    //Generate a QR Code and save it to file "sample.png"
    Generate("your content goes here", "png", "sample.png");
  }

  public static void Generate(string content, string format, string path)
  {
    string encoded = HttpUtility.UrlEncode(content);
    Uri uri = new Uri("http://www.esponce.com/api/v3/generate?content=" + encoded + "&format=" + format);
    WebClient client = new WebClient();
    client.DownloadFile(uri, path);
  }
}

Java Sample

This code can be used in a classic Java application or web applet or Android application

import java.io.*;
import java.net.*;

public class qrcode
{
  public static void main(String args[])
  {
    //Generate a QR Code image and save it to file "sample.png"
    generate("your content goes here", "png", "sample.png");
  }

  public static void generate(String content, String format, String path)
  {
    try
    {
      String encoded = URLEncoder.encode(content, "UTF-8");
      String url = "http://www.esponce.com/api/v3/generate?content=" + encoded + "&format=" + format;
      BufferedInputStream ins = new BufferedInputStream(new URL(url).openStream());
      FileOutputStream fos = new FileOutputStream(path);
      BufferedOutputStream bos = new BufferedOutputStream(fos, 1024);

      int size = 0;
      byte data[] = new byte[1024];
      while ((size = ins.read(data, 0, 1024)) > 0)
      {
        bos.write(data, 0, size);
      }

      bos.close();
      fos.close();
      ins.close();
    }
    catch (Exception e)
    {
    }
  }
}

Python Sample

Using Python 2.7

#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import urllib
import httplib

def generate(content, format = "png"):
    query = urllib.urlencode({ "content": content, "format": format })
    con = httplib.HTTPConnection("www.esponce.com")
    con.request("GET", "/api/v3/generate?" + query)
    response = con.getresponse()
    image = response.read()
    con.close()
    return image

image = generate("your content goes here")
file = open("sample.png", "wb")
file.write(image)
file.close()

JavaScript Sample

JavaScript in combination with HTML

<img id="qrcode" src="" alt="QR Code" />
<script type="text/javascript">
    function generate(content)
    {
        var url = "http://www.esponce.com/api/v3/generate?content=" + encodeURI(content) + "&format=png";
        var img = document.getElementById("qrcode");
        img.src = url;
    }
    generate("your content goes here");
</script>

PHP Sample

<img src="<?php echo generate("your content goes here"); ?>" alt="QR Code" />

<?php
function generate($content, $format = "png")
{
    $encoded = urlencode($content);
    $url = "http://www.esponce.com/api/v3/generate?content=$encoded&format=$format";
    return $url;
}
?>

There is more

Download all samples with make script here.

Other QR Code related methods like decoding (reverse process of generating) and tracking scans can be found at esponce.com.

Written by developer

January 24th, 2012 at 3:46 pm

Increasing maximum request length for WCF REST Web Service with ASP .NET 4.0

Recently we have extended a web service with method for uploading user’s profile image. So far the service was working fine with less amount of data, i.e. name, address and description. First image upload test with the new method resulted with 400 Bad Request. Breakpoints were set in WCF method but debugger did not stop there, not even entered the method.

Default configuration

WCF service had been configured for REST using default webHttpBinding configuration in web.config

<configuration>
  ...
  <system.serviceModel>
    <behaviors>
      <endpointBehaviors>
        <behavior name="ApiBehavior" />
      </endpointBehaviors>
      <serviceBehaviors>
        <behavior name="Avivo.Web.Services.ApiServiceBehavior">
         <serviceMetadata httpGetEnabled="true" />
         <serviceDebug includeExceptionDetailInFaults="false" />
         <serviceTimeouts transactionTimeout="00:05:00" />
        </behavior>
      </serviceBehaviors>
    </behaviors>

    <services>
      <!-- API v1.0 -->
      <service behaviorConfiguration="Avivo.Web.Services.ApiServiceBehavior"
name="Avivo.Web.Services.ApiService">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:1234/api/v1" />
          </baseAddresses>
        </host>
        <endpoint address="" binding="webHttpBinding"
contract="Avivo.Web.Services.IApiService" behaviorConfiguration="ApiBehavior" />
      </service>
    </services>

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true">
      <baseAddressPrefixFilters>
        <add prefix="http://localhost:1234/api/v1"/>
      </baseAddressPrefixFilters>
    </serviceHostingEnvironment>

  </system.serviceModel>
  ...
</configuration>

Identifying the problem

Images can be quite large (few MB), especially when comparing with text size (few KB). At first it was assumed the web service call has exceeded maximum request length limit. To confirm the assumption we analyzed WCF traffic using SvcTraceViewer.

Enabling WCF tracing in web.config

<configuration>
  ...
  <!-- Use SvcTraceViewer for debugging WCF services -->
  <system.diagnostics>
    <trace autoflush="true" />
    <sources>
      <source name="System.ServiceModel" switchValue="Information,
ActivityTracing" propagateActivity="true">
        <listeners>
          <add name="sdt" type="System.Diagnostics.XmlWriterTraceListener"
initializeData="d:\temp\wcf-trace.svclog" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>
  ...
</configuration>

When the tracing is set each request to web service will write entry to d:\temp\wcf-trace.svclog in this case. The report file can be opened with SvcTraceViewer found in %ProgramFiles%\Microsoft SDKs\Windows, e.g. “c:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\SvcTraceViewer.exe”

Entries in SvcTraceViewer marked with red represents errors. The problematic request was logged with error message:

The maximum message size quota for incoming messages (65536) has been exceeded. To increase the quota, use the MaxReceivedMessageSize property on the appropriate binding element.

Identifying that assumption was right and the upload request exceeded default 65 KB limit.

Increasing request limit quota

Customizing webHttpBinding in web.config and referencing with bindingConfiguration in endpoint element

<configuration>
        ...
  <system.serviceModel>
        ...
    <bindings>
      <!-- Customizations for REST service -->
      <webHttpBinding>
        <!-- Limits set to 10 MB (specified value in bytes) -->
        <binding name="ApiQuotaBinding" maxReceivedMessageSize="10485760"
maxBufferPoolSize="10485760" maxBufferSize="10485760" closeTimeout="00:03:00"
openTimeout="00:03:00" receiveTimeout="00:10:00" sendTimeout="00:03:00">
          <readerQuotas maxDepth="32" maxStringContentLength="10485760"
maxArrayLength="10485760" maxBytesPerRead="10485760" />
          <security mode="None" />
        </binding>
      </webHttpBinding>
    </bindings>

    <services>
      <!-- API v1.0 -->
      <service behaviorConfiguration="Avivo.Web.Services.ApiServiceBehavior"
name="Avivo.Web.Services.ApiService">
        <host>
          <baseAddresses>
            <add baseAddress="http://localhost:1234/api/v1" />
          </baseAddresses>
        </host>
        <!-- Added attribute 'bindingConfiguration' -->
        <endpoint address="" bindingConfiguration="ApiQuotaBinding" binding="webHttpBinding"
contract="Avivo.Web.Services.IApiService" behaviorConfiguration="ApiBehavior" />
      </service>
    </services>

  </system.serviceModel>
  ...
</configuration>

Additionally httpRuntime limits must also be set because web service is running in ASP .NET compatibilty mode. Note that maxRequestLength has value in kilobytes.

<configuration>
  ...
  <system.web>
    <httpRuntime maxRequestLength="10240" />
  </system.web>
  ...
</configuration>

Testing

Finding the solution was not straightforward, it took some time searching the web and reading documentation. Finally after figuring out the described config in this post we solved the problem with success.

Written by developer

October 26th, 2011 at 7:50 pm

QR Codes API – automatically generated for given content

There are a lot of  QR Code generators on a web and there is also listed our generator – available at http://qrcode.good-survey.com

It already went over simple generator functionality and new features are adding.

QR Codes Generator and API

QR Codes Generator and API

Basically, beside QR Code generation, we are offering as addition:

  • Tracking of generated QR Codes – for marketing managers ti know which locations work best (i.e. posters with printed QR Code)
  • Dynamic QR Codes – if some QR Code is already printed you can make it point to completely different URL without changing the printed code
  • Adding your logo inside QR Code (with readability testing) – branding feature
  • All types of content are supported (hyperlinks, custom text, vCard, Bizcard, Mecard,  vCalendar, social networks – Twitter, Facebook, YouTube, Geo locations and maps, SMS messages, phones,…)
  • Strong use of API – automating generation process and possibility to use from your application/website – this is what we will talk about a little bit more in this article…

Using API is not complicated at all, we wrote a tutorial which is easy to understand.

Here is an example how you can have instantly QR Code image on your website:

This are direct links:

This how it could look like inside your website (just put this hyperlink inside your IMG tag)

<img src="http://qrcode.good-survey.com/api/v2/generate?content=
http%3a%2f%2fmaps.google.com%2fmaps%3ff%3dq%26q%3d46.043286%2c14.492791300000022%
26q%3d30%2bTeslova%2bUlica%252c%2bLjubljana%2b1000%252c%2bSlovenia&
format=png&padding=2&size=10&em=byte&ec=m" alt="Avivo location" />
Try it also by yourself – just download DEMO API application from CodePlex and you can play with supported API features.

The service cannot be activated due to an exception during compilation. The exception message is: This collection already contains an address with scheme http. There can be at most one address per scheme in this collection.

You can solve this issue by adding the following code to your web.config:

<system.serviceModel>
	...
	<serviceHostingEnvironment>
	  <baseAddressPrefixFilters>
	  	<add prefix="http://sample.domain.tld/Sample/"/>
	  </baseAddressPrefixFilters>
	</serviceHostingEnvironment>
	...
</system.serviceModel>

Allowing WCF services (svc extension) in IIS7

  1. First, click on your website (or IIS7 website root)
  2. Click on MimeTypes and enter “.svc” and “application/octet-stream” and save
  3. In your project add this to your web.config in <httpHandlers> section:
    <add name=”svc-Integrated” path=”*.svc” verb=”*” type=”System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089″ preCondition=”integratedMode” />
    <add name=”svc-ISAPI-2.0″ path=”*.svc” verb=”*” modules=”IsapiModule” scriptProcessor=”%SystemRoot%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll” preCondition=”classicMode,runtimeVersionv2.0,bitness32″ />

Written by Avivo

July 12th, 2010 at 9:17 pm