如何在C#中使用VIES SOAP服务检查EU VAT

时间:2015-10-16 10:37:42

标签: c# asp.net soap

我有一个ASP.NET网站,需要检查用户提供的增值税。 VIES Service可用于公开SOAP API

我需要一个关于如何使用此服务验证增值税的简单示例。在PHP中,它是这4行:https://stackoverflow.com/a/14340495。对于C#,我发现2010年的一些文章不起作用,或者是几十行甚至几百行"包装",#34;帮助服务"等

我不需要其中任何一种,有人可以提供类似PHP的四线程,可以在C#中检查增值税吗?谢谢。

6 个答案:

答案 0 :(得分:6)

在.NET平台上,通常使用Web服务以生成代理类。这通常可以使用Visual Studio"添加Web引用"你只需要填写WSDL的路径。另一种方法是使用wsdl.exesvcutil.exe生成源类。

然后只需消耗这个类,验证增值税就变成了一个单行:

DateTime date = new checkVatPortTypeClient().checkVat(ref countryCode, ref vatNumber, out isValid, out name, out address);

生成代理提供强类型API以使用整个服务,我们不需要手动创建soap信封和解析输出文本。它比yours更容易,更安全,更通用的解决方案。

答案 1 :(得分:4)

这是一个自给自足(没有WCF,没有WSDL,...)的实用程序类,它将检查增值税号并获取有关公司的信息(名称和地址)。如果增值税号无效或发生任何错误,它将返回null。

// sample calling code
Console.WriteLine(EuropeanVatInformation.Get("FR89831948815"));

...

public class EuropeanVatInformation
{
    private EuropeanVatInformation() { }

    public string CountryCode { get; private set; }
    public string VatNumber { get; private set; }
    public string Address { get; private set; }
    public string Name { get; private set; }
    public override string ToString() => CountryCode + " " + VatNumber + ": " + Name + ", " + Address.Replace("\n", ", ");

    public static EuropeanVatInformation Get(string countryCodeAndVatNumber)
    {
        if (countryCodeAndVatNumber == null)
            throw new ArgumentNullException(nameof(countryCodeAndVatNumber));

        if (countryCodeAndVatNumber.Length < 3)
            return null;

        return Get(countryCodeAndVatNumber.Substring(0, 2), countryCodeAndVatNumber.Substring(2));
    }

    public static EuropeanVatInformation Get(string countryCode, string vatNumber)
    {
        if (countryCode == null)
            throw new ArgumentNullException(nameof(countryCode));

        if (vatNumber == null)
            throw new ArgumentNullException(nameof(vatNumber));

        countryCode = countryCode.Trim();
        vatNumber = vatNumber.Trim().Replace(" ", string.Empty);

        const string url = "http://ec.europa.eu/taxation_customs/vies/services/checkVatService";
        const string xml = @"<s:Envelope xmlns:s='http://schemas.xmlsoap.org/soap/envelope/'><s:Body><checkVat xmlns='urn:ec.europa.eu:taxud:vies:services:checkVat:types'><countryCode>{0}</countryCode><vatNumber>{1}</vatNumber></checkVat></s:Body></s:Envelope>";

        try
        {
            using (var client = new WebClient())
            {
                var doc = new XmlDocument();
                doc.LoadXml(client.UploadString(url, string.Format(xml, countryCode, vatNumber)));
                var response = doc.SelectSingleNode("//*[local-name()='checkVatResponse']") as XmlElement;
                if (response == null || response["valid"]?.InnerText != "true")
                    return null;

                var info = new EuropeanVatInformation();
                info.CountryCode = response["countryCode"].InnerText;
                info.VatNumber = response["vatNumber"].InnerText;
                info.Name = response["name"]?.InnerText;
                info.Address = response["address"]?.InnerText;
                return info;
            }
        }
        catch
        {
            return null;
        }
    }
}

答案 2 :(得分:3)

我发现最简单的方法就是发送XML并在它返回时解析它:

var wc = new WebClient();
var request = @"<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:urn=""urn:ec.europa.eu:taxud:vies:services:checkVat:types"">
    <soapenv:Header/>
    <soapenv:Body>
      <urn:checkVat>
         <urn:countryCode>COUNTRY</urn:countryCode>
         <urn:vatNumber>VATNUMBER</urn:vatNumber>
      </urn:checkVat>
    </soapenv:Body>
    </soapenv:Envelope>";

request = request.Replace("COUNTRY", countryCode);
request = request.Replace("VATNUMBER", theRest);

String response;
try
{
    response = wc.UploadString("http://ec.europa.eu/taxation_customs/vies/services/checkVatService", request);
}
catch
{
    // service throws WebException e.g. when non-EU VAT is supplied
}

var isValid = response.Contains("<valid>true</valid>");

答案 3 :(得分:2)

我上传了一个与.NET Core兼容的简单类。

https://github.com/TriggerMe/CSharpVatChecker

它解析SOAP并返回一个简单的对象。

var vatResult = await VatQuery.VatQuery.CheckVATNumberAsync("IE", "3041081MH"); // The Squarespace VAT Number

Console.WriteLine(vatResult.Valid); // Is the VAT Number valid?
Console.WriteLine(vatResult.Name);  // Name of the organisation 

答案 4 :(得分:0)

基于Pavel Hodek的:

  1. 确保为visual studio安装了Microsoft WCF Web Service Reference Provide扩展程序(我正在使用VS 2017 社区)。
  2. 在解决方案资源管理器中右键单击Connected Services&gt;添加连接服务
  3. 选择WCF扩展名。
  4. 输入VIES提供的网址 http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl从wsdl生成Service类。

  5. 按Go并选择服务,为命名空间指定正确的名称,例如Services.VATCheck

  6. 按Finish,将创建一个新文件夹,并在Connected Services中将名为reference.cs的文件重命名为VATCheck,VATCheck也将重命名该类。
  7. 在控制器中使用以下代码来调用该调用,确保它是异步的(最终加载所有数据可能需要一段时间)

        public async Task<IActionResult> CheckVAT()
        {
            var countryCode = "BE";
            var vatNumber = "123456789";
    
            try
            {
                checkVatPortType test = new checkVatPortTypeClient(checkVatPortTypeClient.EndpointConfiguration.checkVatPort, "http://ec.europa.eu/taxation_customs/vies/services/checkVatService");
                checkVatResponse response = await test.checkVatAsync(new checkVatRequest { countryCode = countryCode, vatNumber = vatNumber });
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }
    
            return Ok();
        }
    

    请注意,您可以清理此电话,但这完全取决于您。

答案 5 :(得分:0)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BTWCheck.eu.europa.ec;    

namespace BTWCheck
{
     class Program
    {
        static void Main(string[] args)
        {
            // VS 2017
            // add service reference -> button "Advanced" -> button "Add Web Reference" ->
            // URL = http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl 

            string Landcode = "NL";
            string BTWNummer = "820471616B01"; // VAT nr BOL.COM 

            checkVatService test = new checkVatService();
            test.checkVat(ref Landcode, ref BTWNummer, out bool GeldigBTWNr, out string Naam, out string Adres);

            Console.WriteLine(Landcode + BTWNummer + " " + GeldigBTWNr);
            Console.WriteLine(Naam+Adres);
            Console.ReadKey();

        }
    }
}