0

Я зарегистрировал заявку на Azure, получил секретный и успешно получил маркер доступа с помощью TIdHTTP с моей Delphi 2010:Получение 400 ответа при использовании Delphi, чтобы получить Microsoft Translation

paramsList := TStringList.Create; 
paramsList.Add('grant_type=client_credentials'); 
paramsList.Add('client_id=<ClientID>'); 
paramsList.Add('client_secret=<ClientSecret>'); 
paramsList.Add('scope=http://api.microsofttranslator.com'); 
try 
    Result := idHTTP.Post(uri, lParamList); 
finally 
    FreeAndNill(idHTTP); 
    FreeAndNill(paramsList); 
end; 

Я тогда извлечь лексемы часть ответа с использованием копии. Теперь, когда я пытаюсь получить фактический перевод, я получаю ошибку «Плохой запрос». Вот что я пытаюсь:

idHTTP.Request.CustomHeaders.AddValue('Authorization', headers); 
try 
    stringResult := idHTT.Get('http://api.microsofttranslator.com/v2/Http.svc/Translate?text=Gracias%20a%20l%20vida&from=es&to=en'); 
finally 
    FreeAndNil(idHTTP); 
end; 

Я также не получаю ответ, используя сообщение:

paramList := TStiringList.Create; 
paramList.Add('Authorization= Bearer ' + Token); 
try 
    idHTTP.Post(uri, paramList); 
finally 
... 

Тем не менее такой же ответ - 400, Любые мысли?

+0

Вы добавляете пользовательские 'заголовок Authorization', но вы сделали не показывать код, создающий значение заголовка, уверены ли вы, что вы делаете это правильно? Во втором примере (который BTW не будет работать как «Авторизация» - это заголовок HTTP, а не поле формы отправки), у вас есть '' Authorization = Bearer '+ Token', который должен быть '' Authorization = Bearer' + Token' вместо этого у IOW у вас есть дополнительное пространство перед «Носителем». Вы делаете ту же ошибку в примере «CustomHeaders» при назначении значения «заголовкам»? –

+0

Привет, Рами, спасибо, что вернулись ко мне. Вы говорите, что второй пример не будет работать, поскольку он не является полем формы отправки, как его следует отправить? Я скопировал значение ключа + из образцов PHP и C#, которые работают для меня, там говорится: «Авторизация: Bearer http ...» – asafadd

+0

Как я уже сказал, «Авторизация» - это HTTP-заголовок. Пример 'CustomHeaders' обрабатывает этот сценарий, не помещайте его в опубликованный' TStringList'. Но вы не ответили на мой вопрос: есть ли переменная 'headers', содержащая те же ошибочные пробелы, что и данные' TStringList'? –

ответ

0

Во-первых, факты: При запросе маркера доступа в Microsoft Translator вы используете Post и при обращении к API с токена доступа используется Получить (Спасибо @RemyLebeau). Теперь код. Приведенный выше код для приема токена доступа работает. Таким образом, код для получения перевода также прямо вперед:

lHTTP.Request.CustomHeaders.FoldLines := false; // avoid split by white space 
lHTTP.Request.CustomHeaders.AddValue('Authorization', 'Bearer ' + AuthKey); 
myStream = TStringStream.Create; 
try 
    lHTTP.Get(uri, stream); 
    stream.Position := 0; 
    Result := stream.ReadString(stream.size); 
finally 
    FreeAndNil(lHTTP); 
    FreeAndNil(stream); 
end; 
0

Вот рабочий пример Проверьте: // http://oauthdevconsole.cloudapp.net/PartialOAuth

unit MSTranslationv2; 

interface 

uses 
    Classes, SysUtils, 
    IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, 
    IdHTTP, IdIOHandler, IdIOHandlerSocket, IdIOHandlerStack, IdSSL, 
    IdSSLOpenSSL; 

type 
    TMSTranslator = class(TComponent) 
    IdHTTP: TIdHTTP; 
    IdSSLIOHandlerSocketOpenSSL: TIdSSLIOHandlerSocketOpenSSL; 
    private 
    fSourceLanguage: string; 
    fClientID: string; 
    fClientSecret: string; 
    fTargetLanguage: string; 
    AuthKey : string; 

    { Private declarations } 
    function GetAuthorizationKey: string; 
    procedure SetClientID(const Value: string); 
    procedure SetClientSecret(const Value: string); 
    public 
    { Public declarations } 
    constructor Create(AOwner: TComponent); override; 
    destructor Destroy; override; 

    function Translate(Text: string): string; 

    property ClientID: string read fClientID write SetClientID; 
    property ClientSecret: string read fClientSecret write SetClientSecret; 
    property SourceLanguage: string read fSourceLanguage write fSourceLanguage; 
    property TargetLanguage: string read fTargetLanguage write fTargetLanguage; 
    end; 

//http://oauthdevconsole.cloudapp.net/PartialOAuth 
implementation 

uses 
    HTTPApp, DBXJSON, ComObj, Variants; 

{ TMSTranslator } 

constructor TMSTranslator.Create(AOwner: TComponent); 
begin 
    inherited; 

    IdHTTP := TIdHTTP.Create(nil); 
    IdSSLIOHandlerSocketOpenSSL := TIdSSLIOHandlerSocketOpenSSL.Create(nil); 

    IdHTTP.Request.ContentType := 'application/x-www-form-urlencoded'; 
    idHTTP.HandleRedirects := True; 
    IdHTTP.Request.CustomHeaders.FoldLines := false; // avoid split by white space 
    IdHTTP.IOHandler := IdSSLIOHandlerSocketOpenSSL; 
end; 

destructor TMSTranslator.Destroy; 
begin 
    IdHTTP.Free; 
    IdSSLIOHandlerSocketOpenSSL.Free; 

    inherited; 
end; 

procedure TMSTranslator.SetClientID(const Value: string); 
begin 
    if fClientID <> Value then 
    AuthKey:= ''; 

    fClientID := Value; 
end; 

procedure TMSTranslator.SetClientSecret(const Value: string); 
begin 
    if fClientSecret <> Value then 
    AuthKey := ''; 

    fClientSecret := Value; 
end; 

function TMSTranslator.GetAuthorizationKey: string; 
var 
    StringList : TStringList; 
    StringStream: TStringStream; 
    LJsonObj : TJSONObject; 
    LJsonValue : TJSONValue; 
begin 
    if AuthKey = '' then begin 

    if fClientID = '' then 
     raise Exception.Create('Property fClientID needs to be assigned.'); 

    if fClientSecret = '' then 
     raise Exception.Create('Property fClientSecret needs to be assigned.'); 

    StringList := TStringList.Create; 
    StringStream := TStringStream.Create('', TEncoding.UTF8); 
    try 
     StringList.Add('grant_type=client_credentials'); 
     StringList.Add('&client_id='+ HTTPEncode(fClientID)); 
     StringList.Add('&client_secret='+ HTTPEncode(fClientSecret)); 
     StringList.Add('&scope='+ HTTPEncode('http://api.microsofttranslator.com')); 
     StringStream.WriteString(StringList.text); 

     IdHTTP.Request.CustomHeaders.Clear; 
     result := idHTTP.Post('https://datamarket.accesscontrol.windows.net/v2/OAuth2-13', StringStream); 

     LJsonObj := TJSONObject.ParseJSONValue(TEncoding.ASCII.GetBytes(result),0) as TJSONObject; 
     try 
     LJsonValue :=LJsonObj.Get('access_token').JsonValue; 
     result := LJsonValue.Value; 
     finally 
     LJsonObj.Free; 
     end; 

    finally 
     StringList.free; 
     StringStream.free; 
    end; 
    end else 
    result := AuthKey; 
end; 

function TMSTranslator.Translate(Text: string): string; 
var 
    XmlDoc: OleVariant; 
    Node: OleVariant; 
    StringStream : TStringStream; 
    Url: string; 
const 
    Msxml2_DOMDocument = 'Msxml2.DOMDocument.6.0'; 
begin 
    AuthKey := GetAuthorizationKey; 

    if Text <> '' then begin 
    if fSourceLanguage = '' then 
     raise Exception.Create('Property fSourceLanguage needs to be assigned.'); 

    if fTargetLanguage = '' then 
     raise Exception.Create('Property fTargetLanguage needs to be assigned.'); 

    Url := format('http://api.microsofttranslator.com/v2/Http.svc/Translate?text=%s&from=%s&to=%s', [HTTPEncode(Text), fSourceLanguage, fTargetLanguage]); 

    IdHTTP.Request.CustomHeaders.Clear; 
    IdHTTP.Request.CustomHeaders.AddValue('Authorization', 'Bearer ' + AuthKey); 
    StringStream := TStringStream.Create('', TEncoding.UTF8); 
    try 
     IdHTTP.Get(Url, StringStream); 
     StringStream.Position := 0; 
     Result := StringStream.ReadString(StringStream.size); 

     XmlDoc:= CreateOleObject(Msxml2_DOMDocument); 
     try 
     XmlDoc.Async := False; 
     XmlDoc.LoadXML(Result); 
     if (XmlDoc.parseError.errorCode <> 0) then 
      raise Exception.CreateFmt('Error in Xml data: %s',[XmlDoc.parseError]); 
     Node:= XmlDoc.documentElement; 
     if not VarIsClear(Node) then begin 
      Result:= XmlDoc.Text; 
      if pos('TranslateApiExceptionMethod', result) >0 then 
      Result := ''; 
     end; 
     finally 
     XmlDoc := Unassigned; 
     end; 
    end else 
    result := ''; 
end; 

==================== 

var 
    MSTranslator: TMSTranslator; 
begin 
    MSTranslator := TMSTranslator.Create(nil); 
    try 
    MSTranslator.ClientID := 'YourClientIDHere'; 
    MSTranslator.ClientSecret := 'YourClientSecretHere'; 
    MSTranslator.SourceLanguage := 'en'; 
    MSTranslator.TargetLanguage := 'th'; 
    ShowMessage(MSTranslator.Translate('Hello')); 
    finally 
    MSTranslator.free; 
    end; 
end; 
Смежные вопросы