Cita:
Empezado por dtovar8a
Buenos días,
En el caso de la construcción del XML he optado por su creación manual. En este sentido no tengo ningún problema, puedo subir manualmente el fichero desde el portal de AEAT con su certificado y pasa correctamente, puediendo ver la factura subida desde la consulta de facturas.
El problema viene cuando intento subir dicho archivo mediante C# o VB.
He utilizado diferentes mecanismos, y en ambos me encuentro varios problemas: - Utilizando HttpWebRequest, aparece el error "Fin prematuro del archivo".
Comenta @CMB que puede ser problema del fichero y que al abrir con un explorador me indicará la línea/columna del error, pero el fichero abre correctamente, de hecho, como he dicho antes, lo he subido sin problemas desde el portal.
El código que utilizo es el que utiliza @angelhorse:
Código:
Public Sub sendXML(_subjectname As String, _filepath As String)
subjectName = _subjectname
filepath = _filepath
Dim req As HttpWebRequest
Dim url As String = "https://www7.aeat.es/wlpl/SSII-FACT/ws/fe/SiiFactFEV1SOAP"
'inicializar propiedades request--------------------------------
req = HttpWebRequest.Create(url)
req.Headers.Add("SOAP:Action")
req.ContentType = "text/xml;charset=""utf-8"""
req.Accept = "text/xml"
req.Method = "POST"
Dim soapEnvelopeXml As XmlDocument = New XmlDocument()
soapEnvelopeXml.Load(_filepath)
cert = New X509Certificate2("c:\Temp\certificado.pfx", "12345")
req.ClientCertificates.Add(cert)
Dim rest As WebResponse = req.GetResponse()
Dim reader As StreamReader = New StreamReader(rest.GetResponseStream())
soapResult = reader.ReadToEnd()
End Sub
¿Que está ocurriendo?
- Utilizando la clase siiService, creada a partir del WS y cambianado inheerits por: Microsoft.Web.Services3.WebServicesClientProtocol, como describe @batuzail.
Los pasos que sigo son los siguientes:- Agrego a referencias de mi proyecto "Microsoft.Web.Services3"
- Utilizo la siguiente instrucción para generar la clase siiService a partir del servicio web:
Código:
wsdl https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/ssii/fact/ws/SuministroFactEmitidas.wsdl /language=VB
Una vez generada la clase, la edito y cambio
Código:
Partial Public Class siiService
Inherits System.Web.Services.Protocols.SoapHttpClientProtocol
por
Código:
Partial Public Class siiSuministroFactEmitidas
Inherits Microsoft.Web.Services3.WebServicesClientProtocol
- Importo a mi proyecto la clase recién generada
- Agrego la referencia al servico web para tener acceso a los datasets y la llamo SuministroFactEmitidas
- Añado los siguientes imports:
Código:
Imports System.IO
Imports System.Security.Cryptography.X509Certificates
Imports System.Xml.Serialization
Imports Microsoft.Web.Services3
Imports Microsoft.Web.Services3.Security
Imports Microsoft.Web.Services3.Security.Tokens
- Añado el siguiente código
Código:
Private Sub send()
Try
cert = findCertificate()
Dim signatureToken As X509SecurityToken = New X509SecurityToken(cert)
Dim sig As New MessageSignature(signatureToken)
Dim webserviceProxy As New siiSuministroFactEmitidas
webserviceProxy.ClientCertificates.Add(cert)
Dim requestContext As SoapContext = webserviceProxy.RequestSoapContext
requestContext.Security.Tokens.Add(signatureToken)
requestContext.Security.Timestamp.TtlInSeconds = 60
requestContext.Security.Elements.Add(sig)
Dim suministroLRFacturasEmitidas As New SuministroLRFacturasEmitidas
Dim xmlSerializer As New XmlSerializer(suministroLRFacturasEmitidas.GetType, "https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/ssii/fact/ws/SuministroLR.xsd")
Using reader As New FileStream(filepath, FileMode.Open)
suministroLRFacturasEmitidas = CType(xmlSerializer.Deserialize(reader), SuministroLRFacturasEmitidas)
End Using
Dim resp As SuministroFactEmitidas.RespuestaLRFEmitidasType
webserviceProxy.SuministroLRFacturasEmitidas(suministroLRFacturasEmitidas)
Catch ex As Exception
Console.WriteLine(ex.ToString())
End Try
End Sub
No tengo ningún error de compilación, pero al ejecutarlo aparece un error en tiempo de ejecución en la siguiente línea:
Código:
Dim webserviceProxy As New siiSuministroFactEmitidas
con el error "URI no válido: no se puede determinar el formato del URI."
¿Alguien podría darme algo de luz por alguna de las dos vías?
Gracias
|
También he probado a hacer el envío tal y como comenta @bartag:
Cita:
Empezado por bartag
Te pongo el código que utilizo. Básicamente lo que hace es tomar un archivo xml y lo envía. Debes por favor cumplimentar previamente los campos de dicho archivo pues en caso contrario te dará errores de validación.
Código:
' ----------------------------------------------------------------------------------------
Dim store As Security.Cryptography.X509Certificates.X509Store = New Security.Cryptography.X509Certificates.X509Store("My")
store.Open(Security.Cryptography.X509Certificates.OpenFlags.ReadOnly)
Dim CertificadoCorrecto As New System.Security.Cryptography.X509Certificates.X509Certificate2
For Each x In store.Certificates
ListCert = ListCert & vbNewLine
Next
'RichTextBox1.Text = ListCert
CertificadoCorrecto = store.Certificates(CInt(TextBoxNumeroOrdenCertificado.Text)) '(5)
' Objeto que almacenara la respuesta de la funcion del Web Service
Dim resp As New ServiceReference1.RespuestaLRFEmitidasType
' Ws
Dim Ws As New ServiceReference1.siiSOAPClient
Ws.ClientCredentials.ClientCertificate.Certificate = CertificadoCorrecto
Ws.ClientCredentials.UseIdentityConfiguration = True
' Asignamos el certificado:
Ws.ClientCredentials.ClientCertificate.Certificate = CertificadoCorrecto
' ----------------------------------------------------------------------------------------
' ----------------------------------------------------------------------------------------
Dim _SuministroLRFacturasEmitidas As New SuministroLRFacturasEmitidas
'--------------------------------------------------------------------------
Try
Dim x As New XmlSerializer(_SuministroLRFacturasEmitidas.GetType, "https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/ssii/fact/ws/SuministroLR.xsd")
' A FileStream is needed to read the XML document.
Dim filename As String = "facturaEmitidaMODEL.XML"
Using reader As New FileStream(filename, FileMode.Open)
_SuministroLRFacturasEmitidas = CType(x.Deserialize(reader), SuministroLRFacturasEmitidas)
End Using
' SI QUEREMOS SOBREESCRIBIR EL XML ANTES DE ENVIAR:
' SOBREESCRIBIMOS DATS FORM ANTES SEND:
_SuministroLRFacturasEmitidas.Cabecera.Titular.NombreRazon = Trim(TextBoxRazonSocialEmisor.Text)
_SuministroLRFacturasEmitidas.Cabecera.Titular.NIF = Trim(TextBoxNIFEmisor.Text)
'(...)
'// se hace la llamada a la funcion suministrada por el WS
resp = Ws.SuministroLRFacturasEmitidas(_SuministroLRFacturasEmitidas)
Catch ex As Exception
MsgBox(ex.Message)
Respuesta2RichTextBox = ex.Message
Finally
'Me.Cursor = Cursors.Default
'Threading.Thread.Sleep(5000)
'ProgressBar1.Style = ProgressBarStyle.Continuous
''ProgressBar1.Value = ProgressBar1.Maximum
End Try
Te adjunto también el archivo xml que debes cumplimentar donde indica '[A CUMPLIMENTAR]'.
Con esto, se toma la factura del archivo (fíjate que solamente tiene el nodo '<SuministroLRFacturasEmitidas>' y nada del encabezado SOAP para que no dé error al aplicar el Deserialize) y nos la convierte en un objeto serializado donde podemos acceder a los campos de la clase antes de enviar si lo deseamos; en caso contrario se envía y la propia llamada se encarga de insertar las cabeceras, los namespaces, etc.
|
Pero a pesar de no tener ningún error de compilación, me da un error de ejecución. Mi codigo es el siguiente:
Código:
Private Sub send()
Try
Dim webserviceProxy As New SuministroFactEmitidas.siiSOAPClient
Dim resp As New SuministroFactEmitidas.RespuestaLRFEmitidasType
Dim suministroLRFacturasEmitidas As New SuministroFactEmitidas.SuministroLRFacturasEmitidas
cert = findCertificate()
Dim signatureToken As X509SecurityToken = New X509SecurityToken(cert)
Dim sig As New MessageSignature(signatureToken)
webserviceProxy.ClientCredentials.ClientCertificate.Certificate = cert
Dim xmlSerializer As New XmlSerializer(suministroLRFacturasEmitidas.GetType, "https://www2.agenciatributaria.gob.es/static_files/common/internet/dep/aplicaciones/es/aeat/ssii/fact/ws/SuministroLR.xsd")
Dim reader As New FileStream(filepath, FileMode.Open)
suministroLRFacturasEmitidas = CType(xmlSerializer.Deserialize(reader), SuministroFactEmitidas.SuministroLRFacturasEmitidas)
resp = webserviceProxy.SuministroLRFacturasEmitidas(suministroLRFacturasEmitidas)
'webserviceProxy.SuministroLRFacturasEmitidas(suministroLRFacturasEmitidas)
Catch ex As Exception
Console.WriteLine(ex.ToString())
End Try
y el error que aparece es el siguiente:
No se encontró el elemento de extremo predeterminado que hace referencia al contrato 'SuministroFactEmitidas.siiSOAP' en la sección de configuración de cliente de ServiceModel. La razón puede ser que no se encontró ningún archivo de configuración para la aplicación o que no se encontró ningún elemento de extremo correspondiente a este contrato en el elemento de cliente.
¿podeis ayudarme?
Gracias