Thursday, February 17, 2022

Chuyển số thành chữ

Dưới đây là cách chuyển 1 chuỗi số thành chữ. Thường dùng trong trường hợp xử lý hóa đơn điện tử, các API của nhà cung cấp có thể yêu cầu chuyển số tiền thành chữ gửi vào input

Tham khảo: https://xuanthulab.net/code-c-chuyen-so-thanh-chu.html#

using System;

namespace XTL
{
  public static class Utils
  {
    /// 
    /// Chuyển phần nguyên của số thành chữ
    /// 
    /// Số double cần chuyển thành chữ
    /// Chuỗi kết quả chuyển từ số
    public static string NumberToText(double inputNumber, bool suffix = true)
    {
        string[] unitNumbers = new string[] { "không", "một", "hai", "ba", "bốn", "năm", "sáu", "bảy", "tám", "chín" };
        string[] placeValues = new string[] { "", "nghìn", "triệu", "tỷ" };
        bool isNegative = false;

        // -12345678.3445435 => "-12345678"
        string sNumber = inputNumber.ToString("#");
        double number = Convert.ToDouble(sNumber);
        if (number < 0)
        {
          number = -number;
          sNumber = number.ToString();
          isNegative = true;
        }


        int ones, tens, hundreds;

        int positionDigit = sNumber.Length;   // last -> first

        string result = " ";


        if (positionDigit == 0)
          result = unitNumbers[0] + result;
        else
        {
          // 0:       ###
          // 1: nghìn ###,###
          // 2: triệu ###,###,###
          // 3: tỷ    ###,###,###,###
          int placeValue = 0;

          while (positionDigit > 0)
          {
            // Check last 3 digits remain ### (hundreds tens ones)
            tens = hundreds = -1;
            ones = Convert.ToInt32(sNumber.Substring(positionDigit - 1, 1));
            positionDigit--;
            if (positionDigit > 0)
            {
              tens = Convert.ToInt32(sNumber.Substring(positionDigit - 1, 1));
              positionDigit--;
              if (positionDigit > 0)
              {
                hundreds = Convert.ToInt32(sNumber.Substring(positionDigit - 1, 1));
                positionDigit--;
              }
            }

            if ((ones > 0) || (tens > 0) || (hundreds > 0) || (placeValue == 3))
              result = placeValues[placeValue] + result;

            placeValue++;
            if (placeValue > 3) placeValue = 1;

            if ((ones == 1) && (tens > 1))
              result = "một " + result;
            else
            {
              if ((ones == 5) && (tens > 0))
                result = "lăm " + result;
              else if (ones > 0)
                result = unitNumbers[ones] + " " + result;
            }
            if (tens < 0)
              break;
            else
            {
              if ((tens == 0) && (ones > 0)) result = "lẻ " + result;
              if (tens == 1) result = "mười " + result;
              if (tens > 1) result = unitNumbers[tens] + " mươi " + result;
            }
            if (hundreds < 0) break;
            else
            {
              if ((hundreds > 0) || (tens > 0) || (ones > 0))
                result = unitNumbers[hundreds] + " trăm " + result;
            }
            result = " " + result;
          }
        }
        result = result.Trim();
        if (isNegative) result = "Âm " + result;
        return result + (suffix ? " đồng chẵn" : "");
      }
  }
}

Một cách khác

Tham khảo: https://tuoitreit.vn/threads/chuyen-so-sang-chu-c.41013/

private string ChuyenSo(string number)
{
    string[] dv = { "", "mươi", "trăm", "nghìn", "triệu", "tỉ"};
    string[] cs = { "không", "một", "hai", "ba", "bốn", "năm", "sáu", "bảy", "tám", "chín" };
    string doc;
    int i, j, k, n, len, found, ddv, rd;

    len = number.Length;
    number += "ss";
    doc = "";
    found=0;
    ddv=0;
    rd=0;

    i = 0;
    while (i < len)
    {
        //So chu so o hang dang duyet
        n = (len - i + 2) % 3 + 1;

        //Kiem tra so 0
        found = 0;
        for (j = 0; j < n; j++)
        {
            if (number[i + j] != '0')
            {
                found = 1;
                break;
            }
        }

        //Duyet n chu so
        if (found == 1)
        {
            rd = 1;
            for (j = 0; j < n; j++)
            {
                ddv=1;
                switch(number[i+j])
                {
                    case '0':
                        if (n-j==3) doc+=cs[0]+" ";
                        if (n-j==2)
                        {
                            if (number[i+j+1]!='0') doc+="lẻ ";
                            ddv=0;
                        }
                        break;
                    case '1':
                        if (n-j==3) doc+=cs[1] + " ";
                        if (n-j==2)
                        {
                            doc+="mười ";
                            ddv=0;
                        }
                        if (n-j==1)
                        {
                            if (i + j == 0) k = 0;
                            else k = i + j - 1;

                            if (number[k]!='1' && number[k]!='0')
                                doc += "mốt ";
                            else
                                doc+=cs[1]+" ";
                        }
                        break;
                    case '5':
                        if (i+j==len-1)
                            doc+="lăm ";
                        else
                            doc+=cs[5]+" ";
                        break;
                    default:
                        doc+=cs[(int)number[i+j]-48]+" ";
                        break;
                }

                 //Doc don vi nho
                if (ddv==1)
                {
                    doc+=dv[n-j-1]+" ";
                }
            }
        }
     

        //Doc don vi lon
        if (len-i-n>0)
        {
            if ((len - i - n ) % 9 == 0)
            {
                if (rd==1)
                    for (k = 0; k < (len - i - n) / 9; k++)
                        doc += "tỉ ";
                rd=0;
            }
            else
                if (found!=0) doc+=dv[((len-i-n+1)%9)/3+2]+" ";
        }

        i+=n;
    }

    if (len == 1)
        if (number[0] == '0' || number[0] == '5') return cs[(int)number[0] - 48];

    return doc;
}

Wednesday, November 24, 2021

Cách serialize và deserialize XML

 public static string XmlSerialize(object ObjectSerialized)

    {
        try
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.OmitXmlDeclaration = true;
            settings.Indent = true;
            settings.NewLineHandling = NewLineHandling.Replace;
            settings.NewLineChars = "\n";
            StringWriter stringWriter = new StringWriter();
            XmlWriter writer = XmlWriter.Create(stringWriter, settings);
            XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
            namespaces.Add(string.Empty, string.Empty);
            new XmlSerializer(ObjectSerialized.GetType()).Serialize(writer, ObjectSerialized, namespaces);
            return stringWriter.ToString();
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

    public static object XmlDeserialize(string strXml, Type objType)
    {
        try
        {
            StringReader rd = new StringReader(strXml);
            return new XmlSerializer(objType).Deserialize(rd);
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

Wednesday, November 10, 2021

Thiết lập ContentType cho Web service Client

 Khi gọi WSDL bằng Web Service client (SoapHttpClientProtocol), nếu gặp lỗi Client found response content type of 'text/xml;charset=utf-8', but expected 'text/xml' là do ContentType mặc định của response là text/xml nhưng response trả về từ đối tác là text/xml;charset=utf-8.

Để khắc phục, trong class service kế thừa từ SoapHttpClientProtocol, bổ sung override hàm GetWriterForMessage để có thể gán lại ContentType cho SoapMessage.


public partial class PartnerAPI : System.Web.Services.Protocols.SoapHttpClientProtocol 

{
    protected override System.Xml.XmlWriter GetWriterForMessage(SoapClientMessage message, int bufferSize)

        {

            message.ContentType = "text/xml;charset=utf-8";

            return base.GetWriterForMessage(message, bufferSize);

        }

}