none
New Bing appids do not work anymore

    Question

  • Back in September 2011, we deprecated the use of Bing AppIDs for the Translator service. In reality, existing and new AppIDs continued to work until yesterday. We have now disabled the use of new Bing AppIDs: requests using a Bing AppID that has not been used with the Translator service before March 31, 2012 will be denied.

    Please upgrade to the secure method of Azure Marketplace tokens.

    If this constitutes an unusual hardship for you, please let us know your circumstances at mtlic@microsoft.com.

    Chris Wendt
    Microsoft Translator

    Monday, April 16, 2012 7:09 PM

Answers

  • I haven't written it up fully yet, but here's a snapshot of the code to give you an idea.

    I have a WP7 App, with 1 page, and on it there's a textbox called 'txtInput', a label called 'lblTranslated' and a button called 'button1' to which the click event handler is wired up.

    Tested this, and it's working...

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;

    namespace TranslatorTest
    {
        public class AdmAccessToken
        {
            public string access_token { get; set; }
            public string token_type { get; set; }
            public string expires_in { get; set; }
            public string scope { get; set; }
        }

        public partial class MainPage : PhoneApplicationPage
        {
            // Make a static string to capture the contents of the input text box
            // This will make it easier to get the string during our asynch stuff without
            // going cross-thread
            private static string strTextToTranslate = "";

            public MainPage()
            {
                InitializeComponent();
            }


            private void button1_Click(object sender, RoutedEventArgs e)
            {
                // Initialize the strTextToTranslate here, while we're on the UI thread
                strTextToTranslate = txtInput.Text;

                // STEP 1: Create the request for the OAuth service that will
                // get us our access tokens.
                String strTranslatorAccessURI = "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13";
                System.Net.WebRequest req = System.Net.WebRequest.Create(strTranslatorAccessURI);
                req.Method = "POST";
                req.ContentType = "application/x-www-form-urlencoded";
                // Important to note -- the call back here isn't that the request was processed by the server
                // but just that the request is ready for you to do stuff to it (like writing the details)
                // and then post it to the server.
                IAsyncResult writeRequestStreamCallback = (IAsyncResult)req.BeginGetRequestStream(new AsyncCallback(RequestStreamReady), req);
               
            }
            private void RequestStreamReady(IAsyncResult ar)
            {
                // STEP 2: The request stream is ready. Write the request into the POST stream
                string clientID = "your client id, let me know if you need help with it";
                string clientSecret = "your secret, ditto! :)"
                String strRequestDetails = string.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=http://api.microsofttranslator.com", HttpUtility.UrlEncode(clientID), HttpUtility.UrlEncode(clientSecret));
               
                // note, this isn't a new request -- the original was passed to beginrequeststream, so we're pulling
                // a reference to it back out. It's the same request
                System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)ar.AsyncState;
               
                // now that we have the working request, write the request details into it
                byte[] bytes = System.Text.Encoding.UTF8.GetBytes(strRequestDetails);
                System.IO.Stream postStream = request.EndGetRequestStream(ar);
                postStream.Write(bytes, 0, bytes.Length);
                postStream.Close();

                // now that the request is good to go, let's post it to the server
                // and get the response. When done, the async callback will call the
                // GetResponseCallback function
                request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);

               
            }
            private void GetResponseCallback(IAsyncResult ar)
            {
                // STEP 3: Process the response callback to get the token
                // we'll then use that token to call the translator service

                // Pull the request out of the IAsynch result
                HttpWebRequest request = (HttpWebRequest)ar.AsyncState;
     
                // The request now has the response details in it (because we've called back having gotten the response
                HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(ar);

                // Using JSON we'll pull the response details out, and load it into an AdmAccess token class (defined earlier in this module)
                // IMPORTANT (and vague) -- despite the name, in Windows Phone 7, this is in the System.ServiceModel.Web library,
                // and not the System.Runtime.Serialization one -- so you will need to have a reference to System.ServiceModel.Web
                System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(AdmAccessToken));
                AdmAccessToken token = (AdmAccessToken)serializer.ReadObject(response.GetResponseStream());

                // We create the URI to the Translate service in the usual way. It's hardcoded here for EN->ES
                string uri = "http://api.microsofttranslator.com/v2/Http.svc/Translate?text=" + System.Net.HttpUtility.UrlEncode(strTextToTranslate) + "&from=en&to=es";
                System.Net.WebRequest translationWebRequest = System.Net.HttpWebRequest.Create(uri);

                // The authorization header needs to be "Bearer" + " " + the access token
                string headerValue = "Bearer " + token.access_token;
                translationWebRequest.Headers["Authorization"] = headerValue;

                // And now we call the service. When the translation is complete, we'll get the callback
                IAsyncResult writeRequestStreamCallback = (IAsyncResult)translationWebRequest.BeginGetResponse(new AsyncCallback(translationReady), translationWebRequest);
            }
            private void translationReady(IAsyncResult ar)
            {
                // STEP 4: Process the translation

                // Get the request details
                HttpWebRequest request = (HttpWebRequest)ar.AsyncState;
               
                // Get the response details
                HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(ar);
               
                // Read the contents of the response into a string
                System.IO.Stream streamResponse = response.GetResponseStream();
                System.IO.StreamReader streamRead = new System.IO.StreamReader(streamResponse);
                string responseString = streamRead.ReadToEnd();

                // Translator returns XML, so load it into an XDocument
                // Note -- you need to add a reference to the System.Linq.XML namespace
                System.Xml.Linq.XDocument xTranslation = System.Xml.Linq.XDocument.Parse(responseString);
                string strTest = xTranslation.Root.FirstNode.ToString();

                // We're not on the UI thread, so use the dispatcher to update the UI
                Deployment.Current.Dispatcher.BeginInvoke( () => lblTranslated.Text = strTest);

            }
           
        }
    }


    //Laurence Moroney: MSFT/ ///Senior Program Manager // XAML Platform /

    Thursday, April 19, 2012 7:24 PM

All replies

  • Can we take Bing Developer API Key from here https://ssl.bing.com/webmaster/developers/createapp.aspx ? What is the new process?
    Tuesday, April 17, 2012 5:21 PM
  • Hi mfmfmf,

    for the new process, please visit http://api.microsofttranslator.com, and follow the links to the SDK documentation. New Bing appids are not suppported anymore.

    Let us know if you run into trouble,

    Chris Wendt
    Microsoft Translator

    Tuesday, April 17, 2012 7:07 PM
  • I can’t understand if we use the api keys with the same way but the process to take one is different.

    For example first we took the key from https://ssl.bing.com/webmaster/developers/createapp.aspx?rfp=7

     

    Now we go to

    https://datamarket.azure.com/dataset/1899a118-d202-492c-aa16-ba21c33c06cb

     

    we sign up 2,000,000 Characters/month.

    Then we go to MyData and Microsoft Translator and have Primary Account Key and Customer ID. How can we use it (are they same as API keys)? 

    Wednesday, April 18, 2012 9:38 AM
  • I think also there is the same question here:

    http://social.msdn.microsoft.com/Forums/en-US/microsofttranslator/thread/725ffeb7-2cdc-48d2-926c-9d4dddae75a2

    Wednesday, April 18, 2012 9:49 AM
  • Hi mfmfmf,

    please follow the guide at http://msdn.microsoft.com/en-us/library/hh454950.aspx. What you do is to obtain an access token from Azure Marketplace, using client ID and client secret in the authentication and then use the access token you received as value of the appid parameter.

    Let us know how it goes,

    Chris Wendt
    Microsoft Translator

    Wednesday, April 18, 2012 12:12 PM
  • Hello! 

    I ran into some trouble with this new system on Windows Phone. This sample code: http://msdn.microsoft.com/en-us/library/hh454950.aspx used to generate an App Token is not working on WP7 (Methods need to be asynchronous).  I am new to WP7 and I can't make that code to work. Is there a sample code which I can use in WP7? 

    Also, after I obtain this Access Token, I need to write an Authorization header like here> http://msdn.microsoft.com/en-us/library/ff512390.aspx ? There is a parameter in the SpeakAsync method in http://api.microsofttranslator.com/V2/Soap.svc named appId. I understood that this parameter needs to be empty. Is there an update to the service to use the AppToken instead of an AppID? (In your previous post you wrote that we can use the token instead of the AppId, but on MSDN it says to write this > "Bearer" + " " + Access Token Value < to access the service).

    Thank you for your response,

    Ionuț Dănilă


    Thursday, April 19, 2012 1:25 PM
  • Hi Ionuț

    I'm working on an on-ramp sample code for translator in ADM.

    I'll add asych to it, so that it works with phone.

    Will post back in a couple of days when it's ready...

    Laurence


    //Laurence Moroney: MSFT/ ///Senior Program Manager // XAML Platform /

    Thursday, April 19, 2012 2:29 PM
  • Hi Chris,

    I have written a code to translate text using Microsoft Translator. I followed all the steps to generate access token from this link,

    http://msdn.microsoft.com/en-us/library/hh454950.aspx

    I was getting the access token and also the translated text using "http://api.microsofttranslator.com/v2/Http.svc/Translate"

    Till today morning everything was working fine. Then suddenly the service is giving me an error and translation functionality is not working. I'm getting access token though.

    Can you please let me know what issue this can be? Is Microsoft making any changes?

    Thank you.

    Thursday, April 19, 2012 3:28 PM
  • Hi Chris,

    I have written a code to translate text using Microsoft Translator. I followed all the steps to generate access token from this link,

    http://msdn.microsoft.com/en-us/library/hh454950.aspx

    I was getting the access token and also the translated text using "http://api.microsofttranslator.com/v2/Http.svc/Translate"

    Till today morning everything was working fine. Then suddenly the service is giving me an error and translation functionality is not working. I'm getting access token though.

    Can you please let me know what issue this can be? Is Microsoft making any changes?

    Thank you.

    Do you have the Bad Request error when trying to get the token?

    I have the same problem...what is it happening?

    Thursday, April 19, 2012 5:39 PM
  • Hi Ionuț

    I'm working on an on-ramp sample code for translator in ADM.

    I'll add asych to it, so that it works with phone.

    Will post back in a couple of days when it's ready...

    Laurence


    //Laurence Moroney: MSFT/ ///Senior Program Manager // XAML Platform /

    Thank you for your reply, Laurence! I am looking forward for your sample code.


    Ionuț Dănilă

    Thursday, April 19, 2012 5:41 PM
  • I haven't written it up fully yet, but here's a snapshot of the code to give you an idea.

    I have a WP7 App, with 1 page, and on it there's a textbox called 'txtInput', a label called 'lblTranslated' and a button called 'button1' to which the click event handler is wired up.

    Tested this, and it's working...

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;

    namespace TranslatorTest
    {
        public class AdmAccessToken
        {
            public string access_token { get; set; }
            public string token_type { get; set; }
            public string expires_in { get; set; }
            public string scope { get; set; }
        }

        public partial class MainPage : PhoneApplicationPage
        {
            // Make a static string to capture the contents of the input text box
            // This will make it easier to get the string during our asynch stuff without
            // going cross-thread
            private static string strTextToTranslate = "";

            public MainPage()
            {
                InitializeComponent();
            }


            private void button1_Click(object sender, RoutedEventArgs e)
            {
                // Initialize the strTextToTranslate here, while we're on the UI thread
                strTextToTranslate = txtInput.Text;

                // STEP 1: Create the request for the OAuth service that will
                // get us our access tokens.
                String strTranslatorAccessURI = "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13";
                System.Net.WebRequest req = System.Net.WebRequest.Create(strTranslatorAccessURI);
                req.Method = "POST";
                req.ContentType = "application/x-www-form-urlencoded";
                // Important to note -- the call back here isn't that the request was processed by the server
                // but just that the request is ready for you to do stuff to it (like writing the details)
                // and then post it to the server.
                IAsyncResult writeRequestStreamCallback = (IAsyncResult)req.BeginGetRequestStream(new AsyncCallback(RequestStreamReady), req);
               
            }
            private void RequestStreamReady(IAsyncResult ar)
            {
                // STEP 2: The request stream is ready. Write the request into the POST stream
                string clientID = "your client id, let me know if you need help with it";
                string clientSecret = "your secret, ditto! :)"
                String strRequestDetails = string.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=http://api.microsofttranslator.com", HttpUtility.UrlEncode(clientID), HttpUtility.UrlEncode(clientSecret));
               
                // note, this isn't a new request -- the original was passed to beginrequeststream, so we're pulling
                // a reference to it back out. It's the same request
                System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)ar.AsyncState;
               
                // now that we have the working request, write the request details into it
                byte[] bytes = System.Text.Encoding.UTF8.GetBytes(strRequestDetails);
                System.IO.Stream postStream = request.EndGetRequestStream(ar);
                postStream.Write(bytes, 0, bytes.Length);
                postStream.Close();

                // now that the request is good to go, let's post it to the server
                // and get the response. When done, the async callback will call the
                // GetResponseCallback function
                request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);

               
            }
            private void GetResponseCallback(IAsyncResult ar)
            {
                // STEP 3: Process the response callback to get the token
                // we'll then use that token to call the translator service

                // Pull the request out of the IAsynch result
                HttpWebRequest request = (HttpWebRequest)ar.AsyncState;
     
                // The request now has the response details in it (because we've called back having gotten the response
                HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(ar);

                // Using JSON we'll pull the response details out, and load it into an AdmAccess token class (defined earlier in this module)
                // IMPORTANT (and vague) -- despite the name, in Windows Phone 7, this is in the System.ServiceModel.Web library,
                // and not the System.Runtime.Serialization one -- so you will need to have a reference to System.ServiceModel.Web
                System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(AdmAccessToken));
                AdmAccessToken token = (AdmAccessToken)serializer.ReadObject(response.GetResponseStream());

                // We create the URI to the Translate service in the usual way. It's hardcoded here for EN->ES
                string uri = "http://api.microsofttranslator.com/v2/Http.svc/Translate?text=" + System.Net.HttpUtility.UrlEncode(strTextToTranslate) + "&from=en&to=es";
                System.Net.WebRequest translationWebRequest = System.Net.HttpWebRequest.Create(uri);

                // The authorization header needs to be "Bearer" + " " + the access token
                string headerValue = "Bearer " + token.access_token;
                translationWebRequest.Headers["Authorization"] = headerValue;

                // And now we call the service. When the translation is complete, we'll get the callback
                IAsyncResult writeRequestStreamCallback = (IAsyncResult)translationWebRequest.BeginGetResponse(new AsyncCallback(translationReady), translationWebRequest);
            }
            private void translationReady(IAsyncResult ar)
            {
                // STEP 4: Process the translation

                // Get the request details
                HttpWebRequest request = (HttpWebRequest)ar.AsyncState;
               
                // Get the response details
                HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(ar);
               
                // Read the contents of the response into a string
                System.IO.Stream streamResponse = response.GetResponseStream();
                System.IO.StreamReader streamRead = new System.IO.StreamReader(streamResponse);
                string responseString = streamRead.ReadToEnd();

                // Translator returns XML, so load it into an XDocument
                // Note -- you need to add a reference to the System.Linq.XML namespace
                System.Xml.Linq.XDocument xTranslation = System.Xml.Linq.XDocument.Parse(responseString);
                string strTest = xTranslation.Root.FirstNode.ToString();

                // We're not on the UI thread, so use the dispatcher to update the UI
                Deployment.Current.Dispatcher.BeginInvoke( () => lblTranslated.Text = strTest);

            }
           
        }
    }


    //Laurence Moroney: MSFT/ ///Senior Program Manager // XAML Platform /

    Thursday, April 19, 2012 7:24 PM
  • I haven't written it up fully yet, but here's a snapshot of the code to give you an idea.

    I have a WP7 App, with 1 page, and on it there's a textbox called 'txtInput', a label called 'lblTranslated' and a button called 'button1' to which the click event handler is wired up.

    Tested this, and it's working...

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Microsoft.Phone.Controls;

    namespace TranslatorTest
    {
        public class AdmAccessToken
        {
            public string access_token { get; set; }
            public string token_type { get; set; }
            public string expires_in { get; set; }
            public string scope { get; set; }
        }

        public partial class MainPage : PhoneApplicationPage
        {
            // Make a static string to capture the contents of the input text box
            // This will make it easier to get the string during our asynch stuff without
            // going cross-thread
            private static string strTextToTranslate = "";

            public MainPage()
            {
                InitializeComponent();
            }


            private void button1_Click(object sender, RoutedEventArgs e)
            {
                // Initialize the strTextToTranslate here, while we're on the UI thread
                strTextToTranslate = txtInput.Text;

                // STEP 1: Create the request for the OAuth service that will
                // get us our access tokens.
                String strTranslatorAccessURI = "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13";
                System.Net.WebRequest req = System.Net.WebRequest.Create(strTranslatorAccessURI);
                req.Method = "POST";
                req.ContentType = "application/x-www-form-urlencoded";
                // Important to note -- the call back here isn't that the request was processed by the server
                // but just that the request is ready for you to do stuff to it (like writing the details)
                // and then post it to the server.
                IAsyncResult writeRequestStreamCallback = (IAsyncResult)req.BeginGetRequestStream(new AsyncCallback(RequestStreamReady), req);
               
            }
            private void RequestStreamReady(IAsyncResult ar)
            {
                // STEP 2: The request stream is ready. Write the request into the POST stream
                string clientID = "your client id, let me know if you need help with it";
                string clientSecret = "your secret, ditto! :)"
                String strRequestDetails = string.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=http://api.microsofttranslator.com", HttpUtility.UrlEncode(clientID), HttpUtility.UrlEncode(clientSecret));
               
                // note, this isn't a new request -- the original was passed to beginrequeststream, so we're pulling
                // a reference to it back out. It's the same request
                System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)ar.AsyncState;
               
                // now that we have the working request, write the request details into it
                byte[] bytes = System.Text.Encoding.UTF8.GetBytes(strRequestDetails);
                System.IO.Stream postStream = request.EndGetRequestStream(ar);
                postStream.Write(bytes, 0, bytes.Length);
                postStream.Close();

                // now that the request is good to go, let's post it to the server
                // and get the response. When done, the async callback will call the
                // GetResponseCallback function
                request.BeginGetResponse(new AsyncCallback(GetResponseCallback), request);

               
            }
            private void GetResponseCallback(IAsyncResult ar)
            {
                // STEP 3: Process the response callback to get the token
                // we'll then use that token to call the translator service

                // Pull the request out of the IAsynch result
                HttpWebRequest request = (HttpWebRequest)ar.AsyncState;
     
                // The request now has the response details in it (because we've called back having gotten the response
                HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(ar);

                // Using JSON we'll pull the response details out, and load it into an AdmAccess token class (defined earlier in this module)
                // IMPORTANT (and vague) -- despite the name, in Windows Phone 7, this is in the System.ServiceModel.Web library,
                // and not the System.Runtime.Serialization one -- so you will need to have a reference to System.ServiceModel.Web
                System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(AdmAccessToken));
                AdmAccessToken token = (AdmAccessToken)serializer.ReadObject(response.GetResponseStream());

                // We create the URI to the Translate service in the usual way. It's hardcoded here for EN->ES
                string uri = "http://api.microsofttranslator.com/v2/Http.svc/Translate?text=" + System.Net.HttpUtility.UrlEncode(strTextToTranslate) + "&from=en&to=es";
                System.Net.WebRequest translationWebRequest = System.Net.HttpWebRequest.Create(uri);

                // The authorization header needs to be "Bearer" + " " + the access token
                string headerValue = "Bearer " + token.access_token;
                translationWebRequest.Headers["Authorization"] = headerValue;

                // And now we call the service. When the translation is complete, we'll get the callback
                IAsyncResult writeRequestStreamCallback = (IAsyncResult)translationWebRequest.BeginGetResponse(new AsyncCallback(translationReady), translationWebRequest);
            }
            private void translationReady(IAsyncResult ar)
            {
                // STEP 4: Process the translation

                // Get the request details
                HttpWebRequest request = (HttpWebRequest)ar.AsyncState;
               
                // Get the response details
                HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(ar);
               
                // Read the contents of the response into a string
                System.IO.Stream streamResponse = response.GetResponseStream();
                System.IO.StreamReader streamRead = new System.IO.StreamReader(streamResponse);
                string responseString = streamRead.ReadToEnd();

                // Translator returns XML, so load it into an XDocument
                // Note -- you need to add a reference to the System.Linq.XML namespace
                System.Xml.Linq.XDocument xTranslation = System.Xml.Linq.XDocument.Parse(responseString);
                string strTest = xTranslation.Root.FirstNode.ToString();

                // We're not on the UI thread, so use the dispatcher to update the UI
                Deployment.Current.Dispatcher.BeginInvoke( () => lblTranslated.Text = strTest);

            }
           
        }
    }


    //Laurence Moroney: MSFT/ ///Senior Program Manager // XAML Platform /

    You were very fast! Thank you very much, Laurence! I will give it a try right now!

    Later Edit: It works great! I added a new Method to use also Speak from Microsoft Translate, I will write it here:

    private void GetResponseCallback(IAsyncResult
    {
    ....................
        // We create the URI to the Translate Speak service as Laurence did in the previous post
         string uri = "http://api.microsofttranslator.com/v2/Http.svc/Speak?text=" + System.Net.HttpUtility.UrlEncode(strTextToTranslate) + "&language=en&format=" + HttpUtility.UrlEncode("audio/wav") + "&options=MaxQuality";
    
    .......................
        // And finally we call the service. When everything is complete, we'll get the callback
         IAsyncResult writeRequestStreamCallback = (IAsyncResult)translationWebRequest.BeginGetResponse(new AsyncCallback(translator_SpeakCompleted), translationWebRequest);
    }
    
    void translator_SpeakCompleted(IAsyncResult 
    {
         // STEP 4: Process the stream (wave file)
         // Get the request details
         HttpWebRequest request = (HttpWebRequest)ar.AsyncState;
    
         // Get the response details
         HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(ar);
    
         // Read the contents of the response into a stream
         Stream streamResponse = response.GetResponseStream();
                
         var se = SoundEffect.FromStream(streamResponse);
         se.Play();
    }

    I hope that Laurence's code will help Lovo and Lovo and YogExt with their errors!


    Ionuț Dănilă



    Thursday, April 19, 2012 7:27 PM
  • Try my code from my answer to Ionuț 

    This is WIndows Phone 7 code though -- do you need it on another platform (ASP.NET etc.) ?

    Laurence


    //Laurence Moroney: www.netnavi.tv // Author of 'Introducing Silverlight' series and much more // @lmoroney

    Thursday, April 19, 2012 8:08 PM
  • Lovo & Lovo / YogExt:

    Here's the code that I wrote to try this synchronously from an ASP.NET Web Form:

    Just tried it and it is working...

    Synchronous keeps it simple, as well as XmlDocument instead of XDocument support, and less threading concerns.

    string clientID = "Your Client ID";
    string clientSecret = "Your Secret";
    String strTranslatorAccessURI = "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13";
    String strRequestDetails = string.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=http://api.microsofttranslator.com", HttpUtility.UrlEncode(clientID), HttpUtility.UrlEncode(clientSecret));

    System.Net.WebRequest webRequest = System.Net.WebRequest.Create(strTranslatorAccessURI);
    webRequest.ContentType = "application/x-www-form-urlencoded";
    webRequest.Method = "POST";

    byte[] bytes = System.Text.Encoding.ASCII.GetBytes(strRequestDetails);
    webRequest.ContentLength = bytes.Length;
    using (System.IO.Stream outputStream = webRequest.GetRequestStream())
    {
      outputStream.Write(bytes, 0, bytes.Length);
    }
    System.Net.WebResponse webResponse = webRequest.GetResponse();
            
    System.Runtime.Serialization.Json.DataContractJsonSerializer serializer = new System.Runtime.Serialization.Json.DataContractJsonSerializer(typeof(AdmAccessToken));
    //Get deserialized object from JSON stream
    AdmAccessToken token = (AdmAccessToken)serializer.ReadObject(webResponse.GetResponseStream());
    string txtToTranslate = TextBox1.Text;
    string headerValue = "Bearer " + token.access_token;
    string uri = "http://api.microsofttranslator.com/v2/Http.svc/Translate?text=" + System.Web.HttpUtility.UrlEncode(txtToTranslate) + "&from=en&to=es";

    System.Net.WebRequest translationWebRequest = System.Net.WebRequest.Create(uri);
    translationWebRequest.Headers.Add("Authorization", headerValue);
    System.Net.WebResponse response = null;
    response = translationWebRequest.GetResponse();
    System.IO.Stream stream = response.GetResponseStream();
    System.Text.Encoding encode = System.Text.Encoding.GetEncoding("utf-8");
    System.IO.StreamReader translatedStream = new System.IO.StreamReader( stream, encode );
    System.Xml.XmlDocument xTranslation = new System.Xml.XmlDocument();
    xTranslation.LoadXml(translatedStream.ReadToEnd());  

    lbl1.Text = "Your Translation is: " + xTranslation.InnerText;

    LMK if this solves your problem.

    Here's the markup for the ASPX:

    <%@ Page Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
        CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>

    <asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
    </asp:Content>
    <asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
        <h2>My Spanish Translator</h2>
        <p>
            Enter your text in English:&nbsp; </p>
        <p>
            <asp:TextBox ID="TextBox1" runat="server" 
                Width="198px"></asp:TextBox>
        </p>
        <p>
            <asp:Button ID="Button1" runat="server" onclick="Button1_Click"
                Text="Translate" />
        </p>
        <p>
            Here is your translation:</p>
        <p>
            <asp:Literal ID="lbl1" runat="server"></asp:Literal>
        </p>
    </asp:Content>


    //Laurence Moroney: www.netnavi.tv // Author of 'Introducing Silverlight' series and much more // @lmoroney

    Thursday, April 19, 2012 8:23 PM
  • Thanks for the sample code snippet.

    I am getting below error on ASP.Net app

    always gives me {"The remote server returned an error: (400) Bad Request."} exception. and response as "<html><body><h1>TranslateApiException</h1><p>Method: Translate()</p><p>Message: Cannot find an Azure Market Place Translator Subscription associated with the request credentials.</p><code></code><p>message id=3737.V2_Rest.Translate.30B62FFC</p></body></html>"

    I registered my application on https://datamarket.azure.com/developer/applications/ and get clientID and client Secret from Registered Appliation tab (from https://datamarket.azure.com/developer/applications/ after login).

    Please help to resolve this error.

    Will try your code snippet on WP today. Thanks again for sample code.

    Friday, April 20, 2012 6:08 AM
  • Hello everyone,

    I'm getting access token but when i try to translate the text i'm getting an error- The remote server returned an error: NotFound :(

    Need some help please.

    Thanks

    Friday, April 20, 2012 9:43 AM
  • Some thoughts:

    Can you check what you got back from the first call -- that which generates the headerValue?

    Put a breakpoint on the code, and check your headerValue, it should look something like this:

    Bearer http%3a%2f%2fschemas.xmlsoap.org%2fws%2f2005%2f05%2fidentity%2fclaims%2fnameidentifier=<<GUID>>&http%3a%2f%2fschemas.microsoft.com%2faccesscontrolservice%2f2010%2f07%2fclaims%2fidentityprovider=https%3a%2f%2fdatamarket.accesscontrol.windows.net%2f&Audience=http%3a%2f%2fapi.microsofttranslator.com&ExpiresOn=1334944597&Issuer=https%3a%2f%2fdatamarket.accesscontrol.windows.net%2f&<<TOKEN=SOMETHING>>


    Note the space between 'Bearer' and 'http'.

    If it doesn't look like this, your clientID and secret may be wrong. Sometimes they are switched around -- the Azure portal doesn't specify them clearly! :)


    //Laurence Moroney: www.netnavi.tv // Author of 'Introducing Silverlight' series and much more // @lmoroney

    Friday, April 20, 2012 5:50 PM
  • Can you check the call to the server? Using something like HttpFiddler, can you capture the session, so we can see what is being called, and what is injected into the header?

    'Not Found' is usually an HTTP404, which means the resource is not found. This could be a typo in the URI, or, it could be the header is wrong...


    //Laurence Moroney: www.netnavi.tv // Author of 'Introducing Silverlight' series and much more // @lmoroney


    Friday, April 20, 2012 5:51 PM
  • Also one other thing to try -- is there any difference if you just translate a single word, like 'test'?

    I'm wondering if there's something in your text that invalidates the URL, and which hasn't been encoded properly?


    //Laurence Moroney: www.netnavi.tv // Author of 'Introducing Silverlight' series and much more // @lmoroney

    Friday, April 20, 2012 6:01 PM
  • Actually now I have the same error: The remote server returned an error: NotFound in WP7. I checked and double checked the values of ClientID and Client. Is the same code as before? What is wrong? Is there a solution, Laurence?


    Ionuț Dănilă

    Monday, April 23, 2012 6:30 PM
  • Are you using exactly my code, where you get the token each time? Or are you getting the token once and re-using it for lots of calls to the API?

    If the latter, it could be that the token has timed out....


    //Laurence Moroney: www.netnavi.tv // Author of 'Introducing Silverlight' series and much more // @lmoroney

    Monday, April 23, 2012 8:30 PM
  • Hello Laurence!

    Actually it was a problem from the JSON Parser. The class needs to be defined like this: 

    public class AdmAccessToken
        {
            public string access_token { get; set; }
            public string token_type { get; set; }
            public string expires_in { get; set; }
            public string scope { get; set; }
        }

    I changed the name of the properties. Then it hit me: to deserialize the object received from the server, the object needs the same class as it is on the server, so I changed them back and it works!

    Thank you for your quick reponse!


    Ionuț Dănilă




    Tuesday, April 24, 2012 4:36 AM
  • Hi Ionuț

    That's great news! It sounds like we should have a developer FAQ, and that should be added....

    Glad you got it working now :)

    Laurence


    //Laurence Moroney: www.netnavi.tv // Author of 'Introducing Silverlight' series and much more // @lmoroney

    Tuesday, April 24, 2012 4:52 PM
  • Dear Laurence,

    I have created my Azure account and registered my app to achieve Client ID and Client Secret, then tried to use your sample code and it worked fine for few times but later on this error happens each time I press the translate button:

    System.Net.WebException was unhandled
      Message=The remote server returned an error: NotFound.

    The error happens on this line:

    HttpWebResponse response = (HttpWebResponse)request.EndGetResponse(ar);

    And when I check the "response", the value is null.

    I'm not pretty sure bur I think there's something wrong with the access token.

    Regards

    Wednesday, May 16, 2012 4:24 AM
  • Hi Saharo 

    Can you check your code all the way back along each step to see where it went wrong? 

    You could be right about the access token having something wrong -- but I'd like to see exactly where it went wrong for you.

    Are you sure that client/secret etc. are correct? Have you checked your usage of translator to see if you haven't gone over the 2m characters mark?

    Laurence


    //Laurence Moroney: www.netnavi.tv // Author of 'Introducing Silverlight' series and much more // @lmoroney

    Wednesday, May 16, 2012 2:37 PM
  • Dear Laurence,

    I checked everything. The client/secret IDs were correct and my usage was not over than 2M characters but I couldn't solve the problem.

    Then I created a new project one more time and used all those four methods you created but this time it worked fine!!!

    I have no idea what was the problem.. by the way thank you so much for your help and support.

    Regards,

    Saharo

    Friday, May 18, 2012 6:29 AM
  • Saharo:

    Great to hear it! Let us know if you have any more problems! :)

    Laurence

    Thursday, May 31, 2012 3:18 PM
  • Sometimes my code works fine, sometimes I get this Exception:

    TranslateApiException: Cannot find an active Azure Market Place Translator Subscription associated with the request credentials. : ID=3811.V2_Soap.TranslateArray.21F3C07F

    It's seems that I use the clientID and ClientSecret as I should...

    Is it bad to create a new LanguageServiceClient and Token every time I need a translation and not re-use the old one that hasn't expired yet?

    EDIT:
    --------

    It seems that I don't get the error ONLY when I debug the application...

    I'm officially frustrated... :(

    Ideas anyone ?

    EDIT2:
    --------

    Now it fails all the time... :(

    • Edited by Kostas0 Thursday, September 13, 2012 5:29 PM
    Thursday, September 13, 2012 5:03 PM
  • Hi Kostas,

    please check that you indeed have an active Microsoft Translator subscription. This message appears if you have an account on the Azure Marketplace, but not an active subscription to Microsoft Translator. (The first few calls will succeed even if you do not have an active subscription.)

    Chris Wendt
    Microsoft Translator

    Friday, September 14, 2012 3:47 PM
  • Hello again.

    Yes, it was the Microsoft Translator subscription that was missing. Silly me... I've skipped one of the steps described in MSDN...
    Now it works fine.

    Another question: will version 1 of your SOAP Translator API remain up and working forever (because there are apps out there using it)?

    Thanks,
    Konstantinos.


    • Edited by Kostas0 Sunday, September 16, 2012 11:55 PM
    Sunday, September 16, 2012 10:14 PM
  • Hi Konstantinos,

    thanks for letting us know that it worked after you subscribed.

    Version 1 will not continue working, and is deprecated as of May 4, 2011: http://social.msdn.microsoft.com/Forums/en-US/microsofttranslator/thread/fcba5155-4bbf-4e8d-96e7-cd215722f2c8

    At the time we announced that it will be shut down after November 4, 2011.

    Chris Wendt
    Microsoft Translator

    Monday, September 17, 2012 5:17 AM
  • Hi Chris sorry for the nuisance, I'm trying to put a translator in an Silverlight application, but I don't get it, I have my Client ID and Client Secret, but still without understand how do I use them. I have a code where use the V1 of the translator service (it still work) but now I'm interesting in use V2, thought that just replace the old appid but don't! can you help me to do it? Please
    here's my C# for Silverlight code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Animation;
    using System.Windows.Shapes;
    using Translator.TranslatorService;
    
    namespace Translator
    {
        public partial class MainPage : UserControl
        {
            TranslatorService.LanguageServiceClient client = new TranslatorService.LanguageServiceClient();
            string AppId = "My AppID";
            System.Collections.ObjectModel.ObservableCollection<string> results;
            System.Collections.ObjectModel.ObservableCollection<string> langcodes;
           
            public MainPage()
            {
                InitializeComponent();
    
                client.TranslateCompleted += new EventHandler<TranslateCompletedEventArgs>(client_TranslateCompleted);
                client.GetLanguageNamesCompleted += new EventHandler<GetLanguageNamesCompletedEventArgs>(client_GetLanguageNamesCompleted);
                client.GetLanguagesCompleted += new EventHandler<GetLanguagesCompletedEventArgs>(client_GetLanguagesCompleted);
    
                client.GetLanguageNamesAsync(AppId, this.Language.IetfLanguageTag);
                client.GetLanguagesAsync(AppId);
    
                srcTxt.Text = "--Etapa #1--1. Depart Tlacoquemecatl toward Fresas2. Turn right onto Avenida Insurgentes";
            }
    
            protected void client_TranslateCompleted(object sender, TranslateCompletedEventArgs e)
            {
                if (e.Error == null)
                {
    
                    destTxt.Text = e.Result;
                }
            }
    
            protected void client_GetLanguagesCompleted(object sender, GetLanguagesCompletedEventArgs e)
            {
                if (e.Error == null)
                {
                    langcodes = e.Result;
                }
            }
    
            protected void client_GetLanguageNamesCompleted(object sender, GetLanguageNamesCompletedEventArgs e)
            {
                if (e.Error == null)
                {
                    results = e.Result;
                    this.cmbBoxsrc.ItemsSource = results;
                    this.cmbBoxdest.ItemsSource = results;
                }
            }
    
            private void PerformTranslation()
            {
                if (cmbBoxsrc.SelectedItem != null && cmbBoxdest.SelectedItem != null)
                {
                    client.TranslateAsync(AppId, srcTxt.Text, "en", "es");
                }
                else
                    MessageBox.Show("Elige primero los lenguajes");
            }
    
            private void bttnTranslateClick(object sender, RoutedEventArgs e)
            {
                PerformTranslation();
            }
    
        }
    }
    and my Service Reference :  http://api.microsofttranslator.com/V1/SOAP.svc

    • Edited by the2cto Monday, November 12, 2012 4:27 PM
    Monday, November 12, 2012 4:19 PM