我正在尝试通过TIdHTTP.Post()
方法发送XML文件。我在网站上的问题中看到了很多例子,但我没有发现任何适合我正在做的事情。
我需要先登录到webservice,它返回一个SessionID
和UserAuth
,然后我需要使用此信息发送XML文件。
我是这样做的:
var
IdHTTP : TIdHTTP;
params : TMemoryStream;
vResponse : TStringStream;
UserName, PassUser, URLogon, URSend, AuthUser: string;
jsonObj, jSubObj: TJSONObject;
begin
IdHTTP := TIdHTTP.Create;
vResponse := TStringStream.Create('');
params := TMemoryStream.Create;
UserName := '123456';
PassUser := '12345678';
AuthUser := string(EncodeBase64(AnsiString(UserName+':'+PassUser)));
URLogon := 'http://svchomologacao.sigen.cidasc.sc.gov.br/Acesso/Login?authToken=' + AuthUser;
URSend := 'http://svchomologacao.sigen.cidasc.sc.gov.br/Receituario/Incluir';
IdHTTP.Post(URLogon, params, vResponse);
Memo1.Lines.Add(vResponse.DataString);
//this is the return I get from WS, the SessionID and UserAuth in JSon:
jsonObj := TJsonObject.ParseJSONValue(vResponse.DataString) as TJsonObject; //Json conversion
params.LoadFromFile('D:\Exemple.xml');
IdHTTP.Request.CustomHeaders.Clear;
IdHTTP.Request.Clear;
IdHTTP.ConnectTimeout := 30000;
IdHTTP.Request.BasicAuthentication := True;
IdHTTP.Request.ContentType := 'application/xml';
IdHTTP.Request.ContentEncoding := 'raw';
IdHTTP.Request.Accept := 'application/xml';
IdHTTP.Response.CharSet := 'UTF-8';
IdHTTP.Request.UserAgent := 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; GTB5; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; Maxthon; InfoPath.1; .NET CLR 3.5.30729; .NET CLR 3.0.30618)';
IdHTTP.Request.CustomHeaders.AddValue(jsonObj.Get(0).JsonString.Value, jsonObj.Get(0).JsonValue.Value);
IdHTTP.Request.CustomHeaders.AddValue(jsonObj.Get(1).JsonString.Value, jsonObj.Get(1).JsonValue.Value);
IdHTTP.Post(URSend, params, vResponse);
ShowMessage(vResponse.DataString);
end;
在第二个POST中,我收到了回复:
HTTP / 1.1 401未经授权
以下是文档的摘录:
可以看到服务描述的URL是:https://svchomologacao.sigen.cidasc.sc.gov.br
这指向CIDASC测试数据库,因此向农药提供IT服务的公司(以下简称EIS)可以通过WEB服务集成其程序。
在HID集成得到CIDASC批准后,用于发送官方数据的URL将是:http://sigensvc.cidasc.sc.gov.br
处方将存储在CIDASC的生产数据库中。
authToken是BASE64(www.base64encode.org)中的组合(Encode)和UTF-8,发布处方的专业人员的登录名和密码,用冒号(:)分隔如下:
例如:专业用户:专业通行证
从上面的例子中,生成的authToken将是:dXN1YXJpb2RvcHJvZmlzc2lvbmFsOnNlbmhhZG9wcm9maXNzaW9uYWw =
要与cidasc服务器建立连接,为了传输特定EIS的处方,应调用Access服务的Login方法,如下所示:
SVC homo log A槽.四根.此DOS C.生成.gov.比如/aces so/login?AU TH token=下一站
其中xyz将是在步骤2中获得的令牌。
我们记得这个方法是POST,所以它只能通过EIS开发的软件调用来操作。为了测试,可以使用现有程序,例如POSTMAN。
将收件人发送到CIDASC建立与服务器的连接后,EIS应调用收据服务的Include方法,以发送收件人,如下所示:
SVC homo log A槽.四根.次大扫除.生成.gov.比如/rec EI图a Rio/Inc路IR
从这一点开始,由EIS单独开发的系统,即它发送第一个并等待该方法的响应代码。
更改HTTPS后,它是这样的:
var
IdHTTP : TIdHTTP;
sshSocketHandler: TIdSSLIOHandlerSocketOpenSSL;
vResponse : TStringStream;
params : TMemoryStream;
begin
IdHTTP := TidHTTP.Create;
sshSocketHandler := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP);
sshSocketHandler.SSLOptions.Method := sslvSSLv2;
IdHTTP.IOHandler := sshSocketHandler;
params := TMemoryStream.Create;
vResponse := TStringStream.Create('');
IdHTTP.Post('https://svchomologacao.sigen.cidasc.sc.gov.br/Acesso/Login?authToken=MzQ3MjA1Mzk2OjM4MjY1OTk5', params, vResponse);
Memo1.Lines.Add(vResponse.DataString);
现在我收到错误:
10054 Peer连接重置
我通过电子邮件联系了支持,他们告诉我必须在include调用的头cookie中发送UserAuth和SessionId数据,并在C#中发送一个示例:
public void InvokeService(string xml){
HttpWebRequest requestReceituarioCancelar = (
HttpWebRequest)WebRequest.CreateHttp(
@"https://svchomologacao.sigen.cidasc.sc.gov.br/Receituario/Cancelar"
);
requestReceituarioCancelar.Headers.Clear();
requestReceituarioCancelar.ContentType = "application/xml;charset=\"utf-8\"";
requestReceituarioCancelar.Accept = "application/xml";
requestReceituarioCancelar.Method = "POST";
XmlDocument SOAPReqBody = new XmlDocument();
//ServiceResult: contains the login return (SessionID and UserAuth)
var ServiceResult = StreamReceituarioLogin(requestLogin);
var uri = new Uri("https://svchomologacao.sigen.cidasc.sc.gov.br");
//Converts login return to json
var retorno = JsonConvert.DeserializeObject<StructCookie>(ServiceResult);
//In the CookieContainer add the Uri containing the URL, SessionID and UserAuth
requestReceituarioCancelar.CookieContainer = new CookieContainer();
requestReceituarioCancelar.CookieContainer.Add(uri, new Cookie("SessionID", retorno.SessionID));
requestReceituarioCancelar.CookieContainer.Add(uri, new Cookie("UserAuth", retorno.UserAuth));
SOAPReqBody.LoadXml(m);
//Now it sends the requestReceituarioCancelar and the SOAPReqBody containing the XML
Stream stream = null;
using (stream = requestReceituarioCancelar.GetRequestStream())
{
SOAPReqBody.Save(stream);
stream.Close();
}
using (WebResponse Serviceres = requestReceituarioCancelar.GetResponse())
{
using (StreamReader rd = new StreamReader(Serviceres.GetResponseStream()))
{
var ServiceResult = rd.ReadToEnd();
rd.Close();
}
}
}
但我不能在Delphi中做同样的事情。
根据您从服务器支持团队收到的电子邮件,您需要为SessionID
和UserAuth
值创建HTTP cookie,而不是像您最初尝试的那样创建单独的HTTP标头。两件完全不同的东西。
你可以使用Indy的TIdCookieMananger
组件来完成这项任务,例如:
var
IdHTTP : TIdHTTP;
sshSocketHandler: TIdSSLIOHandlerSocketOpenSSL;
params : TMemoryStream;
Response : string;
UserName, PassUser, URLogon, URSend, URCookie, AuthUser: string;
jsonObj: TJSONObject;
Uri: TIdUri;
begin
IdHTTP := TIdHTTP.Create;
try
sshSocketHandler := TIdSSLIOHandlerSocketOpenSSL.Create(IdHTTP);
sshSocketHandler.SSLOptions.SSLVersions := [sslvTLSv1, sslvTLSv1_1, sslvTLSv1_2];
IdHTTP.IOHandler := sshSocketHandler;
IdHTTP.CookieManager := TIdCookieManager.Create(IdHTTP);
IdHTTP.AllowCookies := True;
UserName := '123456';
PassUser := '12345678';
AuthUser := string(EncodeBase64(AnsiString(UserName+':'+PassUser)));
URLogon := 'https://svchomologacao.sigen.cidasc.sc.gov.br/Acesso/Login?authToken=' + AuthUser';
URSend := 'https://svchomologacao.sigen.cidasc.sc.gov.br/Receituario/Incluir';
URCookie := 'https://svchomologacao.sigen.cidasc.sc.gov.br';
params := TMemoryStream.Create;
try
Response := IdHTTP.Post(URLogon, params);
Memo1.Lines.Add(Response);
//this is the return I get from WS, the SessionID and UserAuth in JSon:
jsonObj := TJsonObject.ParseJSONValue(Response) as TJsonObject; //Json conversion
try
Uri := TIdUri.Create(URCookie);
try
IdHTTP.CookieManager.AddServerCookie('SessionID=' + jsonObj.Values['SessionID'].Value, Uri);
IdHTTP.CookieManager.AddServerCookie('UserAuth=' + jsonObj.Values['UserAuth'].Value, Uri);
finally
Uri.Free;
end;
finally
jsonObj.Free;
end;
params.LoadFromFile('D:\Exemple.xml');
IdHTTP.Request.Clear;
IdHTTP.ConnectTimeout := 30000;
IdHTTP.Request.Accept := 'application/xml';
IdHTTP.Request.ContentType := 'application/xml';
IdHTTP.Request.CharSet := 'utf-8';
IdHTTP.Request.UserAgent := 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; GTB5; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; Maxthon; InfoPath.1; .NET CLR 3.5.30729; .NET CLR 3.0.30618)';
Response := IdHTTP.Post(URSend, params);
ShowMessage(Response);
finally
params.Free;
end;
finally
IdHTTP.Free;
end;
end;