Monday, June 6, 2022

dotnet string compare like a database

Issue

You make a query on a rdbms database that compares strings with case INSENSITIVE rules instead binary comparison (like case insensitive + accent sensitive of Microsoft SQL Server).

Suppose that you have this table (MYDATA)


MYCODE DESCRIPTION
A A-DESCRIPTION
B B-DESCRIPTION
C C-DESCRIPTION
D D-DESCRIPTION
E E-DESCRIPTION

Suppose that you have to query this table based on website query string params, something like this:

https://myexample.com/favourites?first=a&second=b

If you use old-fashion style you can query database directly using SQL query like this:

DECLARE @first NVARCHAR(MAX);
DECLARE @second NVARCHAR(MAX); SET @first= 'a';
SET @second= 'b'; SELECT * FROM MYDATA WHERE MYCODE = @first OR MYCODE = @second;
GO

If you are using Microsoft SQL Server with collation sequence CASE INSENSITIVE and ACCENT SENSITIVE you will have 2 rows

CODE DESCRIPTION
A A-DESCRIPTION
B B-DESCRIPTION

You will have row with code 'A' and row with code 'B' even you were looking for 'a' and 'b' (case insensitive).

If you are using ORM you can query database using expression or linq like this:

IEnumerable<MyEntity> selectedData = dataRepo.Where(myEntity => myEntity.Code == first || myEntity.Code == second).ToList();

Above query returns 2 items (2 items of MyEntity).

Next in your code you need to find separately first and second.
(...remember that first value is 'a' and second value is 'b'.)

You can use this in memory expression:
MyEntity firstData = selectedData.FirstOrDefault(myEntity => myEntity.Code == first);

or this linq:

MyEntity firstData = (from items in selectedData
                         where items.Code == first
                         orderby items.Code
                         select items).FirstOrDefault();

Both solutions return NULL !!!

You have used same variables 'first' or 'second', but RDBMS Microsoft SQL Server works in case insensitive and in memory comparison is done using binary comparison.

Common solution is to use .ToUpper() on both string in every memory comparison. This solution works but: is legacy not flexible and you need to remember this rule.

More flexible and dynamic solution is DevExtremeToys package.
With this package you can add this using:

using DevExtremeToys.StringComparer;

Now you can configure the string comparison behavior in this way:

            CompareSettings.Instance.GetSetting = () =>
            {
                return new Settings()
                {
                    CaseOption = CaseOptions.Insensitive,
                    AccentOption = AccentOptions.Sensitive
                };
            };

Then you can use new string extensions like this:

firstData = selectedData.FirstOrDefault(myEntity => myEntity.Code.EqualsDevEx(first));

or this:

            firstData = (from items in selectedData
                         where items.Code.EqualsDevEx(first)
                         orderby items.Code
                         select items).FirstOrDefault();

With this solution you will have the same behavior between memory and database.

You can configure string comparison rules once, like the previous example, or specifying compare rules in each comparison using overload with compare settings parameter.

You can see more instructions and source code in github repository.

Enjoy

Wednesday, February 10, 2021

Azure IP address list

Are you looking for Azure IP addresses list?

I've published simple API to get all the Azure ip address list, at all, by region or by services.

How to get the ip address list of  a specified Azure Service in a specified Azure region

https://azinfo.azurewebsites.net/api/servicetags/{regionName}/{serviceName}
It's a GET command.
You have to replace {regionname} with a valid region name and {servicename} with a valid service name.
You can get the list of valid values for {regionname} and {servicename} with the API below

How to get valid region names

https://azinfo.azurewebsites.net/api/GetRegionNameList
It's a GET command.
Its return a list of valid region names and a special name "allregions" that you can use to get data for all regions.
If you use "allregions" with the first api above, you'll get all ip list of the specified service at all (not by region).

How to get valid service names

https://azinfo.azurewebsites.net/api/GetServiceNameList
It's a GET command.
Its return a list of valid Azure service names.

How to get the all the ip address list of all Azure Services in a specified Azure region

https://azinfo.azurewebsites.net/api/region/{regionName}
It's a GET command.
Its return a list with all Azure ip in the specified region.
If you use "allregions" as regionName, you'll get all Azure ip list. 


Where I get this data

Microsoft offer two way to find out Azure IP address list. 

One way is to download the weekly JSON file ad parse it like this example.
This file is weekly updated.
It's quite simple download it but you have to schedule the download of the file and you have to parse the file as you need.

Another way is to use "Service Tags - List" API.
To use this api you have to:
  • register Microsoft.Netowork resource provider at subscription level
  • configure a user\principal of the Azure Active Directory 
  • register an application to authenticate and grant access
  • authenticate with this user or principal to have oauth token
at this point you can use the Microsoft api:
https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.Network/locations/{location}/serviceTags?api-version=2020-07-01

Interesting documentations






Please Note

My API are Azure Functions hosted in a Free Plan, so after limited daily period of usage they will be unavailable.






Tuesday, February 24, 2015

Mutable or Immutable that is the question



The JavaScript Array Object provides a lot of methods to work with.

For me the difficult is to remember which is Mutable and which is Immutable.

Shortly, Immutable are methods (or the entire object) that doesn't change the state of the object; The string object is an example of this behavior.
On the other hand Mutable methods change the state of the object.

Below there is a table with array's methods and the column "Im\Mutable" suggest when a method is Mutable or Immutable.
Pay attention at slice and splice methods that sound similar but respectively are Immutable and Mutable.





















Method Im\Mutable Description Note Sample
concat Immutable As name imply returns a new array with concatenation of the arrays var newArray = array1.concat(array2);
indexOf Immutable It look for the first occurrence of known element and return its index It returns -1 if not found. Use identity check. Begin index start at zero. var index = myArray.indexOf('target',beginIndex);
lastIndexOf Immutable It look for the last occurrence of known element and return its index It returns -1 if not found. Use identity check. Begin index start at zero. var index = myArray.lastIndexOf('target',beginIndex);
join Immutable It returns a single string containing all the array elements separated by a specified string separator var newString = myArray.join(',');
reverse Mutable Reverse the order of all elements in the array Returns void myArray.reverse();
sort Mutable Sort all elements in the array in ascending order Returns void myArray.sort();
slice Immutable Extract one or more elements from the array and copy then to result array Parameters are: start index, end index. Ending index isn't included in extraction var newArray = myArray.slice(startIndex,endIndex);
splice Mutable It returns a new array with only the replaced element of the source array. It replace elements in the original array. Parameters: Index for the first element to be replaced. Number of the elements to replace. Values to use in replacement operation. If values are omitted the element are removed instead replaced. var newArray = myArray.splice(1,3,'newValue1','newValue2','newValue3');
pop Mutable Removes the last element of the array and returns it. var lastElement = myArray.pop();
push Mutable Adds an element at the end of the array and returns the new length var newLength = myArray.push('newElement')
shift Mutable Removes the first element of the array and return it. If array is empty the return value will be undefined. var firstElement = myArray.shift();
unshift Mutable Adds an element at the beginning of the array and returns the new length var newLength = myArray.unshift('newElement');
every Immutable Checks if all elements in the array respect a condition provided as function argument Last parameter is optional (is a reference to the array object) var everyMeetRequirement = myArray.every(myFunction,myArray);

function myFunction(value,index,array){
}

some Immutable Checks if at least one element in the array respect a condition provided as function argument. If all element doesn't meet requirement it return false. Last parameter is optional (is a reference to the array object) var someMeetRequirement = myArray.some(myFunction,myArray);
function myFunction(value,index,array){
}
foreach Immutable Provided function argument is called for every element in the array in ascending index order. myArray.forEach(myFunction);

function myFunction(value,index,array){
}
filter Immutable Returns a new array with elements of the array that meets a logical condition provided by a function argument var newArray = myArray.filter(myFunction,myArray);
function myFunction(value,index,array){
}
map Immutable Enable to evaluate all the elements in the array and return a substitute the element value, all those elements are returned in a new array. var newArray = myArray.map(myFunction);
function myFunction(value,index,array){
}
reduce Immutable Is a recursive method. Each result of function argument is passed as first argument to the function (as previous result). This method call the argument function in ascending index order. var newValue = myArray.reduce(myFunction);
function myFunction(previousReturnValue, currentElementValue) {
}
reduceRight Immutable Is a recursive method. Each result of function argument is passed as first argument to the function (as previous result). This method call the argument function in descending index order. var newValue = myArray.reduce(myFunction);
function myFunction(previousReturnValue, currentElementValue) {
}


Friday, January 23, 2015

JavaScript In Action

My professional life driving me to JavaScript & friends.
In JavasScript there are some tricks to define new objects so in this post I'm going to describe how to define an object\class and how to implement inheritance in JavaScript.

Namespace Organization

The thing is is a bit 'off topic but is required to obtain well organized code and objects.
Namespace is used for group and organize class, function and global objects.

This code example define the jsObjects namespace and jsObjects.WMS sub-namespace.
This is possible thanks to IIFE and singleton.
IIFE mean: "immediately invoked function expression".
IIFE is defined declaring an anonymous function wrapped in parenthesis and ended with open and closed parenthesis.
In this way the function is executed immediately after the file is loaded.

//namespace definition with IIFE and singleton
(function () {
    //jsObject definition and creation with singleton 
    this.jsObjects = this.jsObjects || {}; 
    var rootNamespace = this.jsObjects;
    //sub-namespace creation with singleton
    rootNamespace.WMS = rootNamespace.WMS || {}; 

   //place your classes here

}()); //IIFE



Using namespace we can use object in this way:

var pallet1 = new jsObjects.WMS.MyObject();


Base class definition


These are the steps to define a new class definition:
  1. Declare a variable and assign an IIFE to it.
  2. Surround a named function with previous IIFE. (This function will be constructor and class implementation).
  3. Declare your member inside previous constructor.
  4. Return the function name.
  5. Make class visible from namespace.
The example below define "Package" class and is exposed by jsObject.WMS namespace

    //package class definition
    var Package = (function () { 
        function Package(barcodeArg) { //this function is the constructor
            this.barcode = barcodeArg; //publicly accessible member
        }
        return Package; //return Package object definition
    })(); //IIFE

    //exposing class on jsObjects.WMS namespace
    rootNamespace.WMS.Package = Package;



Now we have to put this class inside the previously declarated namespace like this:


//namespace definition with IIFE and singleton
(function () {
    //jsObject definition and creation with singleton 
    this.jsObjects = this.jsObjects || {}; 
    var rootNamespace = this.jsObjects;
    //subnamespace creation with singleton
    rootNamespace.WMS = rootNamespace.WMS || {}; 

    //Package object definition
    var Package = (function () { 
        function Package(barcodeArg) { //this function is the constructor
            this.barcode = barcodeArg; //publicly accessible member
        }
        return Package; //return Package object definition
    })(); //IIFE

    //exposing class on jsObjects.WMS namespace
    rootNamespace.WMS.Package = Package;

}()); //IIFE





We can use Package object from jsObjects.WMS namespace in this way:


var pallet1 = new jsObjects.WMS.Pallet("PALLET1");


Derived class definition

These are the steps to define a Box object derived from Package object:

  1. Declare a variable and assign an IIFE to it ("Box").
    1. At the end of IIFE function pass the base class type (Package in this case).
  2. In the IIFE function clone "Package" class setting the prototype property of previously declared variable ("Box.prototype = new Package()");
  3. Change the constructor of Box prototype to use the Box's constructor.
  4. Implement the new Box Constructor.
  5. Inside Box constructor call base class's constructor (parent.call(this,...
    1. first argument of parent.call is "this". 
    2. the others are arguments needed by base class's constructor.
  6. Declare your member inside previous constructor.
  7. Return the function name.
  8. Make class visible from namespace.

    //inheritance definition (parent is Package like in IIFE at the end of this class)
    var Box = (function (parent) { 
        //assign to this class prototype the base class definition
        Box.prototype = new Package(); 
        //switch base class constructor with derived class constructor 
        Box.prototype.constructor = Box; 
        function Box(barcode) { //constructor
            parent.call(this, barcode); //calling base class constructor
            this.fragile = true; //added new public accessible member
        }
        return Box; //return Box object definition
    })(Package); //IIFE (pass Package definition to base class)

    //exposing class on jsObjects.WMS namespace
    rootNamespace.WMS.Box = Box;





We can use Box object from jsObjects.WMS namespace in this way:


var box1 = new jsObjects.WMS.Box('BOX1');


Public fields and inheritance

We can add a field publicly accessible using "this." keyword like barcode in the "Package" class example.

    //Package object definition
    var Package = (function () { 
        function Package(barcodeArg) { //this function is the constructor
            this.barcode = barcodeArg; //publicly accessible member
            var alternativeBarCode;
        }
    })(); //IIFE

In this way every one can access to barcode field.

Private fields and inheritance

We can add a field that is accessible only by the class that we are defining. This is a "private member". we accomplish this declaring a variable with "var" keyword.

For example we can add the private field"alternativeBarCode" to the Package Class like highlighted cod in the example below.

    //Package object definition
    var Package = (function () { 
        function Package(barcodeArg) { //this function is the constructor
            this.barcode = barcodeArg; //publicly accessible member
            var alternativeBarCode;
        }
    })(); //IIFE


In this way only "Package" class can access and modify "alternativeBarCode" member.
Inside public function we can use private member like example code below.

Public functions and inheritance

Public functions

We can declare public function using "this.myFunction = function".
Inside public function we can use private member like example code below.
Public function are automatically inherited and publicly exposed by derived class but derived class cannot override its behavior because this kind of function is not overridable.

You can see in the example below that "Box" object inherit from Package and "setAlternativeBarCode" function is called from "Box" instance.


    //Package object definition
    var Package = (function () { 
        function Package(barcodeArg) { //this function is the constructor
            this.barcode = barcodeArg; //publicly accessible member
            var alternativeBarCode;
            this.setAlternativeBarCode = function (alternative) {
                alternativeBarCode = alternative;
            }
            this.getAlternativeBarCode = function () {
                return alternativeBarCode;
            }
        }
    })(); //IIFE

    //inheritance definition (parent is Package like in IIFE at the end of this class)
    var Box = (function (parent) { 
        //assign to this class prototype the base class definition
        Box.prototype = new Package(); 
        //switch base class constructor with derived class constructor
        Box.prototype.constructor = Box;  
        function Box(barcode) { //constructor
            parent.call(this, barcode); //calling base class constructor
            this.fragile = true; //added new public accessible member
        }
        return Box; //return Box object definition
    })(Package); //IIFE (pass Package definition to base class)


Somewhere in your code you can use base class method in this way:

    var box1 = new jsObjects.WMS.Box('BOX1');
    box1.setAlternativeBarCode("BOX-K1");

Function prototype and inheritance

Prototyping is one of the most important thing of JavaScript (but this is another story).
In this post I'm writing only about function prototype regard inheritance.

Using function prototype is possible to implement a function in base class and to redefine its behavior in derived class.

Function prototype is typically locate outside constructor function and inside IIFE of class definition like example below.
The syntax is: [ClassName].prototype.[functionName] = function(....


    //Package object definition
    var Package = (function () { 
        function Package(barcodeArg) { //this function is the constructor
            this.weight = 0; //publicly accessible member
            this.height = 0;//publicly accessible member
            this.width = 0;//publicly accessible member
            this.depth = 0;//publicly accessible member
            this.barcode = barcodeArg; //publicly accessible member
            var alternativeBarCode;
            this.setAlternativeBarCode = function (alternative) {
                alternativeBarCode = alternative;
            }
            this.getAlternativeBarCode = function () {
                return alternativeBarCode;
            }
        }
        //prototype function is inherited automatically and is possible to 
        //redefine the same method in derived class and override behavior
        Package.prototype.getInfo = function () { 
            return ' barcode:' + this.barcode + ' weight: ' + this.weight + 
                   ' height:' + this.height + ' width:' + this.width + 
                   ' depth:' + this.depth + 
                   ' alternative:' + this.getAlternativeBarCode();
        }
        return Package; //return Package object definition
    })(); //IIFE



Given that is placed outside constructor, prototype function "getInfo" cannot access to private field like "alternativeBarCode". So if you need to access some field you can create public function like "getAlternativeBarCode" and use it.

We have "getInfo" prototype function in Package object so in derived class we can overwrite its behavior and call base class's implementation.


    //inheritance definition (parent is Package like in IIFE at the end of this class)
    var Pallet = (function (parent) {
        //assign to this class prototype the base class definition
        Pallet.prototype = new Package();
        //switch base class constructor with derived class constructor 
        Pallet.prototype.constructor = Pallet; 
        function Pallet(barcode) { //constructor
            parent.call(this, barcode); //calling base class constructor
            this.thickness = 0; //add new public accessible member
        }
        //This prototype override base class's getInfo function
        Pallet.prototype.getInfo = function () {
            //call to base class implementation of getInfo function
            return parent.prototype.getInfo.call(this)
                //change behavior to base class implementation
                + ' thickness:' + this.thickness; 
        }
        return Pallet; //return Pallet object definition
    })(Package); //IIFE (pass Package definition to base class)



To accomplish this we can define prototype function "getInfo" in "Pallet" object; inside the new "getInfo" function we can call base class implementation using this syntax:
parent.prototype.[functionName].call(this,[function arguments]);






Somewhere in your code you can use base class method in this way:

    var box1 = new jsObjects.WMS.Box('BOX1');
    var info = box1.getInfo();




Tuesday, June 3, 2014

Garbage Collector and Memory Fragmentation

Sometimes I've memory problems... Sorry, this is another story.
In .net sometimes we can have memory allocation problems.

If you allocate too many objects you can fragment heap memory.
Though you have sufficient free memory the system could not be able to find a block of memory to use for allocation request.
In this case you obtain "System.OutOfMemoryException" though there is still available memory.

This scenario can occur when you have WPF application or when you need to load a large object when memory is fragmented due to loading and unloading objects.

If you have those problems the class below is for you.
In your application you can call MemoryTestApp.MemoryUtils.CompactMemory();
With this method Garbage collector is called (just in case) and are called Windows API to "compact a specified heap by coalescing adjacent free blocks of memory and decommitting large free blocks of memory"
The main API called are:

  • SetProcessWorkingSetSize
  • HeapCompact

With first API we ensure that the working size in memory allocation is set to the minimum.
With second API we compact all allocated block of memory.

First we say to the system that we want the minimum page size when one object is allocated to the heap, second we compact all the allocated memory's pages.


using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace MemoryTestApp
{
    /// <summary>
    /// Utilities to free anche compact memory
    /// </summary>
    public static class MemoryUtils
    {
        [DllImport("kernel32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool SetProcessWorkingSetSize(
            IntPtr process,
            UIntPtr minimumWorkingSetSize,
            UIntPtr maximumWorkingSetSize);

        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern IntPtr GetProcessHeap();

        [DllImport("kernel32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool HeapLock(IntPtr heap);

        [DllImport("kernel32.dll")]
        private static extern uint HeapCompact(IntPtr heap, uint flags);

        [DllImport("kernel32.dll")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool HeapUnlock(IntPtr heap);

        private static void SetProcessWorkingSetSizeToMin()
        {
            SetProcessWorkingSetSize(
                Process.GetCurrentProcess().Handle,
                (UIntPtr)0xFFFFFFFF,
                (UIntPtr)0xFFFFFFFF);
        }

        /// <summary>
        /// Call Garbage collector, wait for it and Compact heap memory
        /// </summary>
        public static void CompactMemory()
        {
            CompactMemory(true, true);
        }
        /// <summary>
        /// Compact heap memory
        /// </summary>
        /// <param name="gcCollect">If true call GC.Collect</param>
        /// <param name="waitCollect">If true wait for GC.Collect</param>
        public static void CompactMemory(bool gcCollect, bool waitCollect)
        {
            if (gcCollect && waitCollect)
            {
                GC.Collect(GC.MaxGeneration);
                GC.WaitForPendingFinalizers();
            }
            else if (gcCollect && !waitCollect)
            {
                GC.Collect(GC.MaxGeneration);
            }

            SetProcessWorkingSetSizeToMin();
            HeapCompact();
        }

        private static void HeapCompact()
        {
            IntPtr heap = GetProcessHeap();

            if (HeapLock(heap))
            {
                try
                {
                    if (HeapCompact(heap, 0) == 0)
                    {
                        //error ignored
                    }
                }
                finally
                {
                    HeapUnlock(heap);
                }
            }
        }

    }
}

Saturday, May 3, 2014

Trace WCF

Very Often people ask to me how to configure web.config and app.config of .net website and .net application to emit trace information about WCF communication. So every time I search in my projects those settings.
To avoid this search I put in this blog those settings.

app.config
Below there is a portion of app.config that activate two trace and generate two file.
client_messages.svclog contains trace about messages exchanged between client and server.
client_traces.svclog contains trace about detailed information of System.ServiceModel Activities. 

Principal config sections are: <system.diagnostics> and <diagnostics>.
<system.diagnostics> section is child of  <configuration> element and in this example is at the same level of <appSettings>
<diagnostics> section is child of <system.serviceModel> element that is child of   <configuration> which is at the same level of <appSettings> and <system.diagnostics>

  ...
  </appSettings>
  ...
  <system.diagnostics>
    <sources>
      <source 
        name="System.ServiceModel.MessageLogging"           
        switchValue="Verbose">
        <listeners>
          <add 
            name="xml"       
            type="System.Diagnostics.XmlWriterTraceListener"
            initializeData="c:\temp\client_messages.svclog"/>
        </listeners>
      </source>
      <source 
        name="System.ServiceModel" 
        switchValue="Verbose" 
        propagateActivity="true">
        <listeners>
          <add 
            name="traceListener"
            type="System.Diagnostics.XmlWriterTraceListener" 
            initializeData="c:\temp\client_traces.svclog" />
        </listeners>
      </source>
    </sources>
    <trace autoflush="true"/>
  </system.diagnostics>

  <system.serviceModel>
    <diagnostics>
      <messageLogging 
        logEntireMessage="true"    
        logMalformedMessages="true"
        logMessagesAtServiceLevel="true"
        logMessagesAtTransportLevel="true"
        maxMessagesToLog="1000" />
      <endToEndTracing 
        activityTracing="true"
        messageFlowTracing="true" />

    </diagnostics>
  </system.serviceModel>

web.config
Below there is a portion of web.config that activate two trace and generate two file.
server_messages.svclog contains trace about messages exchanged between server and client.
server_traces.svclog contains trace about detailed information of System.ServiceModel Activities. 

Principal config sections are: <system.diagnostics> and <diagnostics>.
<system.diagnostics> section is child of  <configuration> element and in this example is at the same level of <system.web>
<diagnostics> section is child of <system.serviceModel> element that is child of   <configuration> which is at the same level of <system.weband <system.diagnostics>


  ...
  </system.web>
  ... 
  <system.diagnostics>
    <sources>
      <source 
        name="System.ServiceModel.MessageLogging" 
        switchValue="Verbose">
        <listeners>
          <add 
            name="xml" 
            type="System.Diagnostics.XmlWriterTraceListener" 
            initializeData="c:\temp\server_messages.svclog"/>
        </listeners>
      </source>
      <source 
        name="System.ServiceModel" 
        switchValue="Verbose" 
        propagateActivity="true">
        <listeners>
          <add 
            name="traceListener" 
            type="System.Diagnostics.XmlWriterTraceListener"                 initializeData="c:\temp\server_traces.svclog" />
        </listeners>
      </source>
    </sources>
  </system.diagnostics>

  <system.serviceModel>
    <diagnostics>
      <messageLogging 
        logEntireMessage="true" 
        maxMessagesToLog="1000" 
        logMessagesAtServiceLevel="true"        
        logMalformedMessages="true" 
        logMessagesAtTransportLevel="true"/>

    </diagnostics>
  </system.serviceModel>

Note 
Notate that every file has ".svclog" as file name extension.
In this way the file are opened automatically by Microsoft Service Trace Viewer.

Friday, May 2, 2014

WCF messge size tips and tricks

The default size of message in SOAP\WCF communication is 65536 bytes.

Sometimes you may need to send soap message bigger than 65536 bytes.

If you exceed that limit you obtain this exception:
System.ServiceModel.ProtocolException occurred
  Message=The remote server returned an unexpected response: (413) Request Entity Too Large.

To go beyond this limit you have to modify the service's binding configuration settings of web.config and app.config .

Setting are:
maxReceivedMessageSize of binding configuration
maxArrayLength of readerQuotas section
maxArrayLength of readerQuotas section
maxBytesPerRead of readerQuotas section
maxDepth of readerQuotas section
maxNameTableCharCount of readerQuotas section

All those setting require an int value, so the maximum value is the int.MaxValue.
Below there is an example of basicHttpBinding with all size values to the maximum value.

<basicHttpBinding>
    <binding
        closeTimeout="01:00:00"
        maxBufferPoolSize="2147483647"
        maxBufferSize="2147483647"
        maxReceivedMessageSize="2147483647"
        openTimeout="01:00:00"
        receiveTimeout="01:00:00"
        sendTimeout="01:00:00">
       <readerQuotas          
maxArrayLength="2147483647"          
maxBytesPerRead="2147483647"          
maxDepth="2147483647"          
maxNameTableCharCount="2147483647"                  
maxStringContentLength="2147483647"
        />  
</binding>
</basicHttpBinding>

In this way you can have soap messages with size about to 2gb.
But you must pay attention to do this because a single message can put your server in denial of service (DOS).
Size of 2gb is not a good idea.

All above said is formally corrected but... surprise surprise doesn't work completely. Yes of course.
If you are hosting your web service in IIS and your message is greater then 30,000,000 bytes, client side you'll receive this exception:

System.ServiceModel.EndpointNotFoundException occurred
  Message=There was no endpoint listening at http://localhost/WebApplication1/Service1.svc that could accept the message. This is often caused by an incorrect address or SOAP action. See InnerException, if present, for more details.

This exception is right because IIS enter in action before WCF "runtime" to filter requests and prevent denial of service (DOS) attacks.

If you need to go beyond 30,000,000 bytes you have to modify webserver's settings.
You can modify webserver's settings modifying web.config like the example below.

Setting to modify is maxAllowedContentLength that require integer value.

<system.webServer>
        <staticContent>
            <mimeMap fileExtension=".desk" mimeType="application/x-zip-compressed" />
            <mimeMap fileExtension=".crc" mimeType="text/plain" />
        </staticContent>
        <security>
            <requestFiltering>
                <requestLimits maxAllowedContentLength="2147483647" 

                   maxQueryString="2147483647" />
            </requestFiltering>
        </security>

    </system.webServer>

There are other ways to alter requestfiltering setting using "IIS Manager" described at this link:
http://www.iis.net/configreference/system.webserver/security/requestfiltering
Those ways at the end alter web.config.

Recap

  1. If you need to create a WCF service that accept more than 65536 bytes and less than 30,000,000 bytes of data you have to modify app.config and web.config altering maxReceivedMessageSize and readerQuotas.          
  2. If your messages are bigger than 30,000,000 bytes you have to alter all maxReceivedMessageSize, readerQuotas and requestFiltering settings with same values.
Pay attention because big amount of data can cause Denial Of Service problems, so be careful and apply this setting only on binding defined for the specified service that require so much data. 
Remember that for large amount of data scenario WCF support streaming transfer mode (but this is another story).