Olá!
Precisa importar o Web Service no C#.
Antes de tudo, acesse a URL https://bhissdigital.pbh.gov.br/bhiss-ws/nfse?wsdl e salve como um arquivo .wsdl .
Depois abra a opção de importar o webservice:

Clique em Advanced…

Agora em Add Web Reference

Informe o local onde salvou o arquivo e clique no botão do lado para acessar:

De um nome para o webservice e clique em Add Reference
Para funcionar com a PBH, você vai precisar de uma classe auxiliar para informar o certificado durante a requisição:
//Classes Auxiliares para adicionar o Certificado a Requisição
public class WS_3106200A_Custom : WS_3106200A.NfseWSService
{
private HttpStatusCode cLastCode;
private X509Certificate2 cCertificado;
public X509Certificate2 Certificado
{
get { return cCertificado; }
set { cCertificado = value; }
}
public HttpStatusCode lastCode { get { return cLastCode; } }
public WS_3106200A_Custom(
X509Certificate2 pCertificado,
string pUrl)
{
Certificado = pCertificado;
Url = pUrl;
}
// Override para informar o certificado
protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
// instanciar o objeto de requisição para a Url informada no construtor da classe
System.Net.WebRequest wr = System.Net.WebRequest.Create(new Uri(Url));
System.Net.HttpWebRequest hr = ((System.Net.HttpWebRequest)wr);
// incluir o certificado digital na requisição
hr.ClientCertificates.Clear();
if (cCertificado != null)
hr.ClientCertificates.Add(cCertificado);
hr.PreAuthenticate = true;
hr.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateRemoteCertificate);
//Corrige: "A solicitação foi anulada: Não foi possível criar um canal seguro para SSL/TLS."
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
ServicePointManager.Expect100Continue = true;
return wr;
}
// Guardar o ultimo StatusCode
protected override System.Net.WebResponse GetWebResponse(System.Net.WebRequest request)
{
System.Net.WebResponse wr = base.GetWebResponse(request);
System.Net.HttpWebResponse hr = ((System.Net.HttpWebResponse)wr);
cLastCode = hr.StatusCode;
return wr;
}
// Callback usado para validar o certificate com a SSL conversation
private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors policyErrors)
{
return true;
}
}
Eu uso uma classe de retorno na minha consulta:
public class RetornoXML
{
private List<ErroXML> errorList = new List<ErroXML>();
public bool Sucesso { set; get; }
public List<ErroXML> Erros
{
get { return errorList; }
set { errorList = value; }
}
public class ErroXML
{
public string Codigo { set; get; }
public string Descricao { set; get; }
public string Correcao { set; get; }
}
public string url { set; get; }
public string protocolo { set; get; }
public string numeroNota { set; get; }
public string codigoVerificacao { set; get; }
public DateTime dataEmissao { set; get; }
public DateTime dataCancelamento { set; get; }
}
Assim o resto fica fácil:
WS_3106200A_Custom ws1 = new WS_3106200A_Custom(certificado, "https://bhissdigital.pbh.gov.br/bhiss-ws/nfse");
RetornoXML retorno = new RetornoXML();
string b = "";
string s = "";
try
{
//Cabeçalho
b = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<cabecalho xmlns = \"http://www.abrasf.org.br/nfse.xsd\" versao = \"1.00\" >\n" +
"<versaoDados>1.00</versaoDados>\n" +
"</cabecalho>";
//Envia Lote
s = "<-- XML ASSINADO --> ";
s = ws1.GerarNfse(b, s);
s = s.Replace(">" , ">").Replace("<", "<");
try
{
XDocument doc = new XDocument();
//Safe UTF preamble
using (var xmlStream = new MemoryStream(Encoding.UTF8.GetBytes(s)))
using (var xmlReader = new XmlTextReader(xmlStream))
{
doc = XDocument.Load(xmlReader);
doc.Save(System.IO.Path.Combine(path, filename.Replace(".xml", ".ret.xml"))); //salvar arquivo retorno
}
//Possui Erro?
var e = from AnyElement in doc.Descendants() where (AnyElement.Name.LocalName == "MensagemRetorno") select AnyElement; //Ignora Namescape
foreach (XElement c in e)
{
retorno.Sucesso = false;
RetornoXML.ErroXML z = new RetornoXML.ErroXML();
z.Codigo = c.Element(XName.Get("Codigo", "http://www.abrasf.org.br/nfse.xsd")).Value;
z.Descricao = c.Element(XName.Get("Mensagem", "http://www.abrasf.org.br/nfse.xsd")).Value;
//z.Correcao = c.Element(XName.Get("Correcao", "http://www.abrasf.org.br/nfse.xsd")).Value;
retorno.Erros.Add(z);
}
//Salvar nota
e = from AnyElement in doc.Descendants() where (AnyElement.Name.LocalName == "InfNfse") select AnyElement;
foreach (XElement i in e)
{
retorno.Sucesso = true;
try
{
retorno.numeroNota = i.Element(XName.Get("Numero", "http://www.abrasf.org.br/nfse.xsd")).Value;
retorno.codigoVerificacao = i.Element(XName.Get("CodigoVerificacao", "http://www.abrasf.org.br/nfse.xsd")).Value;
string data = i.Element(XName.Get("DataEmissao", "http://www.abrasf.org.br/nfse.xsd")).Value;
retorno.dataEmissao = DateTime.ParseExact(data, "yyyy-MM-ddTHH:mm:ss", System.Globalization.CultureInfo.InvariantCulture);
retorno.url = "https://bhissdigital.pbh.gov.br/nfse/pages/consultaNFS-e_cidadao.jsf";
}
catch (Exception ex)
{
throw ex;
}
}
}
catch (Exception ex)
{
retorno.Sucesso = false;
RetornoXML.ErroXML z = new RetornoXML.ErroXML();
z.Codigo = "501";
z.Descricao = ex.Message;
retorno.Erros.Add(z);
}
}
catch (System.Web.Services.Protocols.SoapException error)
{
retorno.Sucesso = false;
RetornoXML.ErroXML z = new RetornoXML.ErroXML();
z.Codigo = ws1.lastCode.ToString();
z.Descricao = error.Message;
retorno.Erros.Add(z);
}
return retorno;
}