Wednesday, 18 November 2015

UNMANAGED AND MANAGED SOLUTIONS IN MICROSOFT DYNAMICS CRM 2015

UNMANAGED AND MANAGED SOLUTION IN MS CRM

 
 Think of unmanaged solutions as source code and think of managed solutions as compiled, versioned and signed assemblies.
Here is very clear article about the managed and unmanaged solution from MVP  Gonzalo
 

REMOTE DEBUGGING MICROSOFT DYNAMICS CRM PLUGINS

Remote Debug the Microsoft Dynamics crm plugin

 
Here is the Screen shot of Remote debug the ms crm 2011 pugin
 
 
 
Here is a  nice video about the Remote debug the ms crm online 2015
 
 
Here is step by step remote debug of ms crm plugin
 

SHARED VARIABLES IN MS CRM 2011

Shared Variables in Microsoft Dynamics crm 2011

 
Here is the nice explaination  from Microsoft MSDN Article

The message pipeline model for Microsoft Dynamics CRM defines a parameter collection of custom data values in the execution context that is passed through the pipeline and shared among registered plug-ins, even from different 3rd party developers.

 This collection of data can be used by different plug-ins to communicate information between plug-ins and enable chain processing where data processed by one plug-in can be processed by the next plug-in in the sequence and so on.

This feature is especially useful in pricing engine scenarios where multiple pricing plug-ins pass data between one another to calculate the total price for a sales order or invoice. Another potential use for this feature is to communicate information between a plug-in registered for a pre-event and a plug-in registered for a post-event.

The name of the parameter that is used for passing information between plug-ins is SharedVariables. This is a collection of key\value pairs. At run time, plug-ins can add, read, or modify properties in the SharedVariables collection. This provides a method of information communication among plug-ins.
This sample shows how to use SharedVariables to pass data from a pre-event registered plug-in to a post-event registered plug-in.
 
using System;

// Microsoft Dynamics CRM namespace(s)
using Microsoft.Xrm.Sdk;

namespace Microsoft.Crm.Sdk.Samples
{
    /// <summary>
    /// A plug-in that sends data to another plug-in through the SharedVariables
    /// property of IPluginExecutionContext.
    /// </summary>
    /// <remarks>Register the PreEventPlugin for a pre-operation stage and the
    /// PostEventPlugin plug-in on a post-operation stage.
    /// </remarks>
    public class PreEventPlugin : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            // Obtain the execution context from the service provider.
            Microsoft.Xrm.Sdk.IPluginExecutionContext context = (Microsoft.Xrm.Sdk.IPluginExecutionContext)
                serviceProvider.GetService(typeof(Microsoft.Xrm.Sdk.IPluginExecutionContext));

            // Create or retrieve some data that will be needed by the post event
            // plug-in. You could run a query, create an entity, or perform a calculation.
            //In this sample, the data to be passed to the post plug-in is
            // represented by a GUID.
            Guid contact = new Guid("{74882D5C-381A-4863-A5B9-B8604615C2D0}");

            // Pass the data to the post event plug-in in an execution context shared
            // variable named PrimaryContact.
            context.SharedVariables.Add("PrimaryContact", (Object)contact.ToString());
        }
    }

    public class PostEventPlugin : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            // Obtain the execution context from the service provider.
            Microsoft.Xrm.Sdk.IPluginExecutionContext context = (Microsoft.Xrm.Sdk.IPluginExecutionContext)
                serviceProvider.GetService(typeof(Microsoft.Xrm.Sdk.IPluginExecutionContext));

            // Obtain the contact from the execution context shared variables.
            if (context.SharedVariables.Contains("PrimaryContact"))
            {
                Guid contact =
                    new Guid((string)context.SharedVariables["PrimaryContact"]);

                // Do something with the contact.
            }
        }
    }
}
It is important that any type of data added to the shared variables collection be serializable otherwise the server will not know how to serialize the data and plug-in execution will fail.

For a plug-in registered in stage 20 or 40, to access the shared variables from a stage 10 registered plug-in that executes on create, update, delete, or by a RetrieveExchangeRateRequest, you must access the ParentContext.SharedVariables collection. For all other cases, IPluginExecutionContext.SharedVariables contains the collection.

IBAN VALIDATION USING JAVASCRIPT AND CUSTOM PLUGIN IN MS CRM 2015


IBAN VALIDATION USING JAVASCRIPTAND CUSTOM PLUGIN MS CRM 2015




www.alpha.gr/.../iban_check_digit_En.pdf

github.com/.../iban.js


(function (root, factory) {
     if (typeof define === 'function' && define.amd) {
         // AMD. Register as an anonymous module.
         define(['exports'], factory);
     } else if (typeof exports === 'object' && typeof exports.nodeName !== 'string') {
         // CommonJS
         factory(exports);
     } else {
         // Browser globals
         factory(root.IBAN = {});
     }
 }(this, function(exports){


     // Array.prototype.map polyfill
     // code from https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array/map
     if (!Array.prototype.map){
         Array.prototype.map = function(fun /*, thisArg */){
             "use strict";


             if (this === void 0 || this === null)
                 throw new TypeError();


             var t = Object(this);
             var len = t.length >>> 0;
             if (typeof fun !== "function")
                 throw new TypeError();


             var res = new Array(len);
             var thisArg = arguments.length >= 2 ? arguments[1] : void 0;
             for (var i = 0; i < len; i++)
             {
                 // NOTE: Absolute correctness would demand Object.defineProperty
                 //       be used.  But this method is fairly new, and failure is
                 //       possible only if Object.prototype or Array.prototype
                 //       has a property |i| (very unlikely), so use a less-correct
                 //       but more portable alternative.
                 if (i in t)
                     res[i] = fun.call(thisArg, t[i], i, t);
             }


             return res;
         };
     }


     var A = 'A'.charCodeAt(0),
         Z = 'Z'.charCodeAt(0);


     /**
      * Prepare an IBAN for mod 97 computation by moving the first 4 chars to the end and transforming the letters to
      * numbers (A = 10, B = 11, ..., Z = 35), as specified in ISO13616.
      *
      * @param {string} iban the IBAN
      * @returns {string} the prepared IBAN
      */
     function iso13616Prepare(iban) {
         iban = iban.toUpperCase();
         iban = iban.substr(4) + iban.substr(0,4);


         return iban.split('').map(function(n){
             var code = n.charCodeAt(0);
            if (code >= A && code <= Z){
                 // A = 10, B = 11, ... Z = 35
                 return code - A + 10;
             } else {
                 return n;
             }
         }).join('');
     }


     /**
      * Calculates the MOD 97 10 of the passed IBAN as specified in ISO7064.
      *
      * @param iban
      * @returns {number}
      */
     function iso7064Mod97_10(iban) {
        var remainder = iban,
             block;


         while (remainder.length > 2){
             block = remainder.slice(0, 9);
             remainder = parseInt(block, 10) % 97 + remainder.slice(block.length);
         }


        return parseInt(remainder, 10) % 97;
     }


     /**
      * Parse the BBAN structure used to configure each IBAN Specification and returns a matching regular expression.
      * A structure is composed of blocks of 3 characters (one letter and 2 digits). Each block represents
      * a logical group in the typical representation of the BBAN. For each group, the letter indicates which characters
      * are allowed in this group and the following 2-digits number tells the length of the group.
      *
      * @param {string} structure the structure to parse
      * @returns {RegExp}
      */
     function parseStructure(structure){
         // split in blocks of 3 chars
         var regex = structure.match(/(.{3})/g).map(function(block){


             // parse each structure block (1-char + 2-digits)
             var format,
                 pattern = block.slice(0, 1),
                 repeats = parseInt(block.slice(1), 10);


             switch (pattern){
                 case "A": format = "0-9A-Za-z"; break;
                 case "B": format = "0-9A-Z"; break;
                 case "C": format = "A-Za-z"; break;
                 case "F": format = "0-9"; break;
                 case "L": format = "a-z"; break;
                 case "U": format = "A-Z"; break;
                 case "W": format = "0-9a-z"; break;
             }


             return '([' + format + ']{' + repeats + '})';
         });


         return new RegExp('^' + regex.join('') + '$');
     }


     /**
      * Create a new Specification for a valid IBAN number.
      *
      * @param countryCode the code of the country
      * @param length the length of the IBAN
      * @param structure the structure of the underlying BBAN (for validation and formatting)
      * @param example an example valid IBAN
      * @constructor
      */
     function Specification(countryCode, length, structure, example){


         this.countryCode = countryCode;
         this.length = length;
         this.structure = structure;
         this.example = example;
     }


     /**
      * Lazy-loaded regex (parse the structure and construct the regular expression the first time we need it for validation)
      */
     Specification.prototype._regex = function(){
         return this._cachedRegex || (this._cachedRegex = parseStructure(this.structure))
     };


     /**
      * Check if the passed iban is valid according to this specification.
      *
      * @param {String} iban the iban to validate
      * @returns {boolean} true if valid, false otherwise
      */
     Specification.prototype.isValid = function(iban){
         return this.length == iban.length
             && this.countryCode === iban.slice(0,2)
             && this._regex().test(iban.slice(4))
             && iso7064Mod97_10(iso13616Prepare(iban)) == 1;
     };


     /**
      * Convert the passed IBAN to a country-specific BBAN.
      *
      * @param iban the IBAN to convert
      * @param separator the separator to use between BBAN blocks
      * @returns {string} the BBAN
      */
     Specification.prototype.toBBAN = function(iban, separator) {
         return this._regex().exec(iban.slice(4)).slice(1).join(separator);
    };


     /**
      * Convert the passed BBAN to an IBAN for this country specification.
      * Please note that <i>"generation of the IBAN shall be the exclusive responsibility of the bank/branch servicing the account"</i>.
      * This method implements the preferred algorithm described in http://en.wikipedia.org/wiki/International_Bank_Account_Number#Generating_IBAN_check_digits
      *
      * @param bban the BBAN to convert to IBAN
      * @returns {string} the IBAN
      */
     Specification.prototype.fromBBAN = function(bban) {
         if (!this.isValidBBAN(bban)){
             throw new Error('Invalid BBAN');
         }


         var remainder = iso7064Mod97_10(iso13616Prepare(this.countryCode + '00' + bban)),
             checkDigit = ('0' + (98 - remainder)).slice(-2);


         return this.countryCode + checkDigit + bban;
     };


     /**
      * Check of the passed BBAN is valid.
      * This function only checks the format of the BBAN (length and matching the letetr/number specs) but does not
      * verify the check digit.
      *
      * @param bban the BBAN to validate
      * @returns {boolean} true if the passed bban is a valid BBAN according to this specification, false otherwise
      */
     Specification.prototype.isValidBBAN = function(bban) {
         return this.length - 4 == bban.length
             && this._regex().test(bban);
     };


     var countries = {};


     function addSpecification(IBAN){
         countries[IBAN.countryCode] = IBAN;
     }


     addSpecification(new Specification("AD", 24, "F04F04A12",          "AD1200012030200359100100"));
     addSpecification(new Specification("AE", 23, "F03F16",             "AE070331234567890123456"));
     addSpecification(new Specification("AL", 28, "F08A16",             "AL47212110090000000235698741"));
     addSpecification(new Specification("AT", 20, "F05F11",             "AT611904300234573201"));
     addSpecification(new Specification("AZ", 28, "U04A20",             "AZ21NABZ00000000137010001944"));
     addSpecification(new Specification("BA", 20, "F03F03F08F02",       "BA391290079401028494"));
     addSpecification(new Specification("BE", 16, "F03F07F02",          "BE68539007547034"));
     addSpecification(new Specification("BG", 22, "U04F04F02A08",       "BG80BNBG96611020345678"));
     addSpecification(new Specification("BH", 22, "U04A14",             "BH67BMAG00001299123456"));
     addSpecification(new Specification("BR", 29, "F08F05F10U01A01",    "BR9700360305000010009795493P1"));
     addSpecification(new Specification("CH", 21, "F05A12",             "CH9300762011623852957"));
     addSpecification(new Specification("CR", 21, "F03F14",             "CR0515202001026284066"));
     addSpecification(new Specification("CY", 28, "F03F05A16",          "CY17002001280000001200527600"));
     addSpecification(new Specification("CZ", 24, "F04F06F10",          "CZ6508000000192000145399"));
     addSpecification(new Specification("DE", 22, "F08F10",             "DE89370400440532013000"));
     addSpecification(new Specification("DK", 18, "F04F09F01",          "DK5000400440116243"));
     addSpecification(new Specification("DO", 28, "U04F20",             "DO28BAGR00000001212453611324"));
     addSpecification(new Specification("EE", 20, "F02F02F11F01",       "EE382200221020145685"));
     addSpecification(new Specification("ES", 24, "F04F04F01F01F10",    "ES9121000418450200051332"));
     addSpecification(new Specification("FI", 18, "F06F07F01",          "FI2112345600000785"));
     addSpecification(new Specification("FO", 18, "F04F09F01",          "FO6264600001631634"));
     addSpecification(new Specification("FR", 27, "F05F05A11F02",       "FR1420041010050500013M02606"));
     addSpecification(new Specification("GB", 22, "U04F06F08",          "GB29NWBK60161331926819"));
     addSpecification(new Specification("GE", 22, "U02F16",             "GE29NB0000000101904917"));
     addSpecification(new Specification("GI", 23, "U04A15",             "GI75NWBK000000007099453"));
     addSpecification(new Specification("GL", 18, "F04F09F01",          "GL8964710001000206"));
     addSpecification(new Specification("GR", 27, "F03F04A16",          "GR1601101250000000012300695"));
     addSpecification(new Specification("GT", 28, "A04A20",             "GT82TRAJ01020000001210029690"));
     addSpecification(new Specification("HR", 21, "F07F10",             "HR1210010051863000160"));
     addSpecification(new Specification("HU", 28, "F03F04F01F15F01",    "HU42117730161111101800000000"));
     addSpecification(new Specification("IE", 22, "U04F06F08",          "IE29AIBK93115212345678"));
     addSpecification(new Specification("IL", 23, "F03F03F13",          "IL620108000000099999999"));
     addSpecification(new Specification("IS", 26, "F04F02F06F10",       "IS140159260076545510730339"));
     addSpecification(new Specification("IT", 27, "U01F05F05A12",       "IT60X0542811101000000123456"));
     addSpecification(new Specification("KW", 30, "U04A22",             "KW81CBKU0000000000001234560101"));
     addSpecification(new Specification("KZ", 20, "F03A13",             "KZ86125KZT5004100100"));
     addSpecification(new Specification("LB", 28, "F04A20",             "LB62099900000001001901229114"));
     addSpecification(new Specification("LC", 32, "U04F24",             "LC07HEMM000100010012001200013015"));
     addSpecification(new Specification("LI", 21, "F05A12",             "LI21088100002324013AA"));
     addSpecification(new Specification("LT", 20, "F05F11",             "LT121000011101001000"));
     addSpecification(new Specification("LU", 20, "F03A13",             "LU280019400644750000"));
     addSpecification(new Specification("LV", 21, "U04A13",             "LV80BANK0000435195001"));
     addSpecification(new Specification("MC", 27, "F05F05A11F02",       "MC5811222000010123456789030"));
     addSpecification(new Specification("MD", 24, "U02A18",             "MD24AG000225100013104168"));
     addSpecification(new Specification("ME", 22, "F03F13F02",          "ME25505000012345678951"));
     addSpecification(new Specification("MK", 19, "F03A10F02",          "MK07250120000058984"));
     addSpecification(new Specification("MR", 27, "F05F05F11F02",       "MR1300020001010000123456753"));
     addSpecification(new Specification("MT", 31, "U04F05A18",          "MT84MALT011000012345MTLCAST001S"));
     addSpecification(new Specification("MU", 30, "U04F02F02F12F03U03", "MU17BOMM0101101030300200000MUR"));
     addSpecification(new Specification("NL", 18, "U04F10",             "NL91ABNA0417164300"));
     addSpecification(new Specification("NO", 15, "F04F06F01",          "NO9386011117947"));
     addSpecification(new Specification("PK", 24, "U04A16",             "PK36SCBL0000001123456702"));
     addSpecification(new Specification("PL", 28, "F08F16",             "PL61109010140000071219812874"));
     addSpecification(new Specification("PS", 29, "U04A21",             "PS92PALS000000000400123456702"));
     addSpecification(new Specification("PT", 25, "F04F04F11F02",       "PT50000201231234567890154"));
     addSpecification(new Specification("RO", 24, "U04A16",             "RO49AAAA1B31007593840000"));
     addSpecification(new Specification("RS", 22, "F03F13F02",          "RS35260005601001611379"));
     addSpecification(new Specification("SA", 24, "F02A18",             "SA0380000000608010167519"));
     addSpecification(new Specification("SE", 24, "F03F16F01",          "SE4550000000058398257466"));
     addSpecification(new Specification("SI", 19, "F05F08F02",          "SI56263300012039086"));
     addSpecification(new Specification("SK", 24, "F04F06F10",          "SK3112000000198742637541"));
     addSpecification(new Specification("SM", 27, "U01F05F05A12",       "SM86U0322509800000000270100"));
     addSpecification(new Specification("ST", 25, "F08F11F02",          "ST68000100010051845310112"));
     addSpecification(new Specification("TL", 23, "F03F14F02",          "TL380080012345678910157"));
     addSpecification(new Specification("TN", 24, "F02F03F13F02",       "TN5910006035183598478831"));
     addSpecification(new Specification("TR", 26, "F05F01A16",          "TR330006100519786457841326"));
     addSpecification(new Specification("VG", 24, "U04F16",             "VG96VPVG0000012345678901"));
     addSpecification(new Specification("XK", 20, "F04F10F02",          "XK051212012345678906"));


     // Angola
     addSpecification(new Specification("AO", 25, "F21",                "AO69123456789012345678901"));
    // Burkina
     addSpecification(new Specification("BF", 27, "F23",                "BF2312345678901234567890123"));
     // Burundi
     addSpecification(new Specification("BI", 16, "F12",                "BI41123456789012"));
     // Benin
     addSpecification(new Specification("BJ", 28, "F24",                "BJ39123456789012345678901234"));
     // Ivory
     addSpecification(new Specification("CI", 28, "U01F23",             "CI17A12345678901234567890123"));
     // Cameron
     addSpecification(new Specification("CM", 27, "F23",                "CM9012345678901234567890123"));
     // Cape Verde
     addSpecification(new Specification("CV", 25, "F21",                "CV30123456789012345678901"));
     // Algeria
     addSpecification(new Specification("DZ", 24, "F20",                "DZ8612345678901234567890"));
     // Iran
     addSpecification(new Specification("IR", 26, "F22",                "IR861234568790123456789012"));
     // Jordan
     addSpecification(new Specification("JO", 30, "A04F22",             "JO15AAAA1234567890123456789012"));
     // Madagascar
     addSpecification(new Specification("MG", 27, "F23",                "MG1812345678901234567890123"));
     // Mali
     addSpecification(new Specification("ML", 28, "U01F23",             "ML15A12345678901234567890123"));
     // Mozambique
     addSpecification(new Specification("MZ", 25, "F21",                "MZ25123456789012345678901"));
     // Quatar
     addSpecification(new Specification("QA", 29, "U04A21",             "QA30AAAA123456789012345678901"));
     // Senegal
     addSpecification(new Specification("SN", 28, "U01F23",             "SN52A12345678901234567890123"));
     // Ukraine
     addSpecification(new Specification("UA", 29, "F25",                "UA511234567890123456789012345"));


     var NON_ALPHANUM = /[^a-zA-Z0-9]/g,
         EVERY_FOUR_CHARS =/(.{4})(?!$)/g;


     /**
      * Utility function to check if a variable is a String.
      *
      * @param v
      * @returns {boolean} true if the passed variable is a String, false otherwise.
      */
     function isString(v){
         return (typeof v == 'string' || v instanceof String);
     }


     /**
      * Check if an IBAN is valid.
      *
      * @param {String} iban the IBAN to validate.
      * @returns {boolean} true if the passed IBAN is valid, false otherwise
      */
     exports.isValid = function(iban){
         if (!isString(iban)){
             return false;
         }
         iban = this.electronicFormat(iban);
         var countryStructure = countries[iban.slice(0,2)];
         return !!countryStructure && countryStructure.isValid(iban);
     };


     /**
      * Convert an IBAN to a BBAN.
      *
      * @param iban
      * @param {String} [separator] the separator to use between the blocks of the BBAN, defaults to ' '
      * @returns {string|*}
      */
     exports.toBBAN = function(iban, separator){
         if (typeof separator == 'undefined'){
             separator = ' ';
         }
         iban = this.electronicFormat(iban);
         var countryStructure = countries[iban.slice(0,2)];
         if (!countryStructure) {
             throw new Error('No country with code ' + iban.slice(0,2));
         }
         return countryStructure.toBBAN(iban, separator);
     };


     /**
      * Convert the passed BBAN to an IBAN for this country specification.
      * Please note that <i>"generation of the IBAN shall be the exclusive responsibility of the bank/branch servicing the account"</i>.
      * This method implements the preferred algorithm described in http://en.wikipedia.org/wiki/International_Bank_Account_Number#Generating_IBAN_check_digits
      *
      * @param countryCode the country of the BBAN
      * @param bban the BBAN to convert to IBAN
      * @returns {string} the IBAN
      */
     exports.fromBBAN = function(countryCode, bban){
         var countryStructure = countries[countryCode];
         if (!countryStructure) {
             throw new Error('No country with code ' + countryCode);
         }
         return countryStructure.fromBBAN(this.electronicFormat(bban));
     };


     /**
      * Check the validity of the passed BBAN.
      *
      * @param countryCode the country of the BBAN
      * @param bban the BBAN to check the validity of
      */
     exports.isValidBBAN = function(countryCode, bban){
         if (!isString(bban)){
             return false;
         }
         var countryStructure = countries[countryCode];
         return countryStructure && countryStructure.isValidBBAN(this.electronicFormat(bban));
     };


     /**
      *
      * @param iban
      * @param separator
      * @returns {string}
      */
     exports.printFormat = function(iban, separator){
         if (typeof separator == 'undefined'){
             separator = ' ';
         }
         return this.electronicFormat(iban).replace(EVERY_FOUR_CHARS, "$1" + separator);
     };


     /**
      *
      * @param iban
      * @returns {string}
      */
     exports.electronicFormat = function(iban){
         return iban.replace(NON_ALPHANUM, '').toUpperCase();
     };


     /**
      * An object containing all the known IBAN specifications.
      */
     exports.countries = countries;


 }));

Call the above function in another webresource to validate the fields

Add the below webresource onChange of the field("iban") on the payment form
-----------------------------------------------------------------------------------------
function IBANCheck() {
var AccountNumber = Xrm.Page.getAttribute("iban").getValue();
if(AccountNumber != null)
{
var status = IBAN.isValid(AccountNumber );
//alert(status);
if(status ==true)
Xrm.Page.getAttribute("ibanvalidation").setValue(true);
else
Xrm.Page.getAttribute("ibanvalidation").setValue(false);

}

}


=====================================
IBAN VALIDATION USING CUSTOM PLUGIN

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using Microsoft.Xrm.Sdk;

namespace Ibanvalidators



{
 
public class Iban:IPlugin



{
 
public void Execute(IServiceProvider serviceProvider)



{
 
string Accountnumber = "";

           //Extract the tracing service for use in debugging sandboxed plug-ins.

            ITracingService tracingService =

                (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            // Obtain the execution context from the service provider.

            IPluginExecutionContext context = (IPluginExecutionContext)

                serviceProvider.GetService(typeof(IPluginExecutionContext));

            // The InputParameters collection contains all the data passed in the message request.

if (context.InputParameters.Contains("Target") &&

context.InputParameters["Target"] is Entity)



{
 
// Obtain the target entity from the input parameters.

Entity entity = (Entity)context.InputParameters["Target"];

// Verify that the target entity represents an account.

// If not, this plug-in was not registered correctly.

if (entity.LogicalName != "ENT")

return;

if(entity.Attributes.Contains(""))



{
 
Accountnumber = entity.Attributes["FIELDNAME"].ToString();





}
 
bool ISvalidIban = ValidateBankAccount(Accountnumber);

if (ISvalidIban == false)

throw new InvalidPluginExecutionException("IBAN validation failed for given Accountnumber");



}

}
 
public static bool ValidateBankAccount(string bankAccount)



{
 
bankAccount = bankAccount.ToUpper(); //IN ORDER TO COPE WITH THE REGEX BELOW

if (String.IsNullOrEmpty(bankAccount))

return false;

else if (System.Text.RegularExpressions.Regex.IsMatch(bankAccount, "^[A-Z0-9]"))



{
 
bankAccount = bankAccount.Replace(" ", String.Empty);

string bank =



bankAccount.Substring(4, bankAccount.Length - 4) + bankAccount.Substring(0, 4);
 
int asciiShift = 55;

StringBuilder sb = new StringBuilder();

foreach (char c in bank)



{
 
int v;

if (Char.IsLetter(c)) v = c - asciiShift;

else v = int.Parse(c.ToString());



sb.Append(v);

}
 
string checkSumString = sb.ToString();

int checksum = int.Parse(checkSumString.Substring(0, 1));

for (int i = 1; i < checkSumString.Length; i++)



{
 
int v = int.Parse(checkSumString.Substring(i, 1));



checksum *= 10;

checksum += v;

checksum %= 97;

}
 
return checksum == 1;



}
 
else

return false;



}

}

}