I am trying to create a new user in my tenant using Microsoft Graph (v1.0) with help of the Microsoft doc.
When I create my user, I always get an error 400 bad request as response.
I am using HttpClient to make the post Request.
My Function :
private async Task<string> BuildUser(string token, string query)
{
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
UserCreation uc = new UserCreation
{
accountEnabled = this.checkBoxActive.Checked,
displayName = this.textBoxDN.Text,
mailNickName = this.textBoxMail.Text,
passwordProfile = new PasswordProfile { forceChangePasswordNextSignIn = this.checkBoxChangeMDP.Checked, password = this.textBoxPassword.Text},
userPrincipalName = this.textBoxUPN.Text
};
string json = JsonConvert.SerializeObject(uc);
var content = new StringContent(json, Encoding.UTF8, "application/json");
HttpResponseMessage response = httpClient.PostAsync(query, content).Result;
return response.ToString();
}
My token is valid and i am able to make simple Get requests, my app have the authorizations mentioned here.
For example, my json var can contains :
{
"accountEnabled":true,
"displayName":"cyril testgraphh",
"mailNickName":"cyriltestgraphh",
"userPrincipalName":"cyriltestgraphh#mytenant.fr",
"passwordProfile":{
"forceChangePasswordNextSignIn":true,
"password":"XXX"
}
}
EDIT :
I solved my problem by using Microsoft Graph objects (Microsoft.Graph.User and Microsoft.Graph.PasswordProfile) and add .onmicrosoft.com to my upn
You should check your code. I tried the following code, it works well.
using Microsoft.Graph;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp4
{
class Program
{
static void Main(string[] args)
{
HttpClient httpClient = new HttpClient();
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
UserCreation uc = new UserCreation
{
accountEnabled = true,
displayName = "cyril testgraphh",
mailNickName = "cyriltestgraphh",
passwordProfile = new PasswordProfile { ForceChangePasswordNextSignIn = false, Password = "Password!" },
userPrincipalName = "XXXXXX#jmaster.onmicrosoft.com"
};
string json = JsonConvert.SerializeObject(uc);
var content = new StringContent(json, Encoding.UTF8, "application/json");
HttpResponseMessage response = httpClient.PostAsync("https://graph.microsoft.com/v1.0/users", content).Result;
Console.Write(response);
Console.ReadLine();
}
}
class UserCreation
{
public bool accountEnabled { get; internal set; }
public string displayName { get; internal set; }
public string mailNickName { get; internal set; }
public string userPrincipalName { get; internal set; }
public PasswordProfile passwordProfile { get; internal set; }
}
}
And the response like this:
In my case the only thing returned from Azure Graph API was the error 400 - Bad Request... nothing else. :(
What I did to solve it? I was using the full blown Group object from Microsoft.Graph NuGet package to create a Group on Azure B2C. However, I was just using 5 properties of that object. While serializing to JSON it was serializing all properties of that class and for some reason the Graph API was barking about a malformed request.
So I just created an anonymous type with the properties that I needed:
var group = new
{
DisplayName = theGroupName,
Description = $"User group for {theGroupName}",
MailNickname = theGroupName.Replace(" ", string.Empty),
MailEnabled = false,
SecurityEnabled = true
};
After sending this streamlined object to the Graph API endpoint, I got a success response.
Related
I am trying to access Sharepoint files without having to have the user login.
I can get an access token by either
Method 1:
var client = new RestClient("https://login.microsoftonline.com/app's-tenant-id-here/oauth2/token");
client.Timeout = -1;
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/x-www-form-urlencoded");
request.AddHeader("Cookie", "fpc=AjMRWuGtzbFJgrxV0V1kMCkUHKO3AQAAAEqqRtgOAAAA");
request.AddParameter("resource", "https://graph.microsoft.com");
request.AddParameter("grant_type", "client_credentials");
request.AddParameter("client_id", "client-id-here");
request.AddParameter("client_secret", ".client-secret-here");
IRestResponse response = client.Execute(request);
or Method 2 -
(This one gives the following error: The type initializer for 'AppForSharePointOnlineWebToolkit.TokenHelper' threw an exception.)
string siteUrl = "https://the-site-I-am-trying-to-access.sharepoint.com/sites/xxx/";
string realm = TokenHelper.GetRealmFromTargetUrl(new Uri(siteUrl));
string accessToken2 = TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal, new Uri(siteUrl).Authority, realm).AccessToken;
using (ClientContext cc = TokenHelper.GetClientContextWithAccessToken(siteUrl, accessToken2))
{
cc.Load(cc.Web, p => p.Title);
cc.ExecuteQuery();
Console.WriteLine(cc.Web.Title);
}
And even method 3
HttpWebRequest endpointRequest = (HttpWebRequest)WebRequest.Create("https://the-site-I-am-trying-to-access.sharepoint.com/sites/xxx/_api/web/getfilebyserverrelativeurl('~/Shared%20Documents/picture.png')");
endpointRequest.Method = "GET";
endpointRequest.Accept = "application/json;odata=verbose";
endpointRequest.Headers.Add("Authorization", "Bearer " + accessToken);
HttpWebResponse endpointResponse = (HttpWebResponse)endpointRequest.GetResponse();
None of which successfully access Sharepoint.
So my question is, am I doing something wrong or is there another way to achieve this?
Well, first of all I would suggest to use Graph API if possible. At least it's the preferred way to query data and it makes things a lot easier.
To access data inside the Microsoft 365 world via Graph API it's required to create a new app registration inside the azure portal > Azure Active Directory > App Registrations.
See this link for more information: MS Docs App Registration
After you've created a new app, configure the required scope and permissions to access SharePoint data (e.g. Sites.ReadWrite.All for full access).
After that simply use the generated and provided clientID, clientSecret, tenantID and scope to request a new access token.
I created a Class to carry out all the http requests for me:
public class GraphClient
{
private const string LOGIN_URL = "https://login.microsoftonline.com/{0}/oauth2/v2.0/token";
private const string BASE_URL = "https://graph.microsoft.com";
protected internal string HttpBaseAddress { get; }
protected internal readonly HttpClient HttpClient;
public GraphClient(string tenantId, string clientId, string clientSecret, string version = "1.0")
{
var msgHandler = new GraphAuthMessageHandler(string.Format(LOGIN_URL, tenantId),
$"{BASE_URL}/.default",
clientId,
clientSecret,
new HttpClientHandler());
HttpBaseAddress = $"{BASE_URL}/v{version}/";
HttpClient = new HttpClient(msgHandler)
{
BaseAddress = new Uri(HttpBaseAddress),
Timeout = new TimeSpan(0, 2, 0)
};
HttpClient.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0");
HttpClient.DefaultRequestHeaders.Add("OData-Version", "4.0");
HttpClient.DefaultRequestHeaders.Add("Prefer", "odata.include-annotations=\"*\"");
HttpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
}
}
The provided MessageHangler requests the token and adds the provided access token to the header:
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Http.Json;
using System.Threading;
using System.Threading.Tasks;
public class GraphAuthMessageHandler : DelegatingHandler
{
private readonly string _loginUrl;
private readonly string _clientId;
private readonly string _clientSecret;
private readonly string _scope;
public GraphAuthMessageHandler(string loginUrl, string scope, string clientId, string clientSecret, HttpMessageHandler innerHandler)
: base(innerHandler)
{
_loginUrl = loginUrl;
_clientId = clientId;
_clientSecret = clientSecret;
_scope = scope;
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var result = await AcquireAccessToken();
request.Headers.Authorization = new AuthenticationHeaderValue(result.TokenType, result.AccessToken);
return await base.SendAsync(request, cancellationToken);
}
private async Task<AuthResponse> AcquireAccessToken()
{
var httpClient = new HttpClient();
var values = new List<KeyValuePair<string, string>>
{
new("client_id", _clientId),
new("client_secret", _clientSecret),
new("scope", _scope),
new("grant_type", "client_credentials")
};
var response = await httpClient.PostAsync(_loginUrl, new FormUrlEncodedContent(values));
return await response.Content.ReadFromJsonAsync<AuthResponse>();
}
}
Edit Here's the AuthResponse class, that simply maps the json response to an C# Object:
using System.Text.Json.Serialization;
public class AuthResponse
{
[JsonPropertyName("token_type")] public string TokenType { get; set; }
[JsonPropertyName("expires_in")] public int ExpiresIn { get; set; }
[JsonPropertyName("access_token")] public string AccessToken { get; set; }
}
And then simply use it:
var driveId = "your-drive-id-here";
var itemId = "your-item-id-here";
var client = new GraphClient(TENANT_ID, CLIENT_ID, CLIENT_SECRET);
var response = await client.HttpClient.GetAsync($"drives/{driveId}/items/{itemId}/content");
if (response.IsSuccessStatusCode)
{
var fileStream = await response.Content.ReadAsStreamAsync();
// do something with stream
}
// handle errors here
The Microsoft Docs are a good start to get it working, it helped me a lot about using Graph API and also the Graph Explorer to test queries and requests to the endpoint.
P.S. this is just a simple example and for sure there's room for improvements, but this will hopefully point you to the right direction ;)
The Problem:
I am struggeling to understand how to get tokens. I know why I should use them, but I just don't understand how to get them. All the samples that uses Tokens just fetch them from "https://webchat-mockbot.azurewebsites.net/directline/token" or something similar. How do I create this path in my bot?
Describe alternatives you have considered
I was able to create something which worked with my JS-Bot:
const server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, function() {
console.log(`\n${ server.name } listening to ${ server.url }`);
console.log('\nGet Bot Framework Emulator: https://aka.ms/botframework-emulator');
console.log('\nTo talk to your bot, open the emulator select "Open Bot"');
});
server.post('/token-generate', async (_, res) => {
console.log('requesting token ');
try {
const cres = await fetch('https://directline.botframework.com/v3/directline/tokens/generate', {
headers: {
authorization: `Bearer ${ process.env.DIRECT_LINE_SECRET }`
},
method: 'POST'
});
const json = await cres.json();
if ('error' in json) {
res.send(500);
} else {
res.send(json);
}
} catch (err) {
res.send(500);
}
});
But I don't find how to do this with my C#-Bot ( I switched to C# because I understand it better than JS).
In my C#-Bot there is only this:
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Integration.AspNet.Core;
namespace ComplianceBot.Controllers
{
// This ASP Controller is created to handle a request. Dependency Injection will provide the Adapter and IBot
// implementation at runtime. Multiple different IBot implementations running at different endpoints can be
// achieved by specifying a more specific type for the bot constructor argument.
[Route("api/messages")]
[ApiController]
public class BotController : ControllerBase
{
private readonly IBotFrameworkHttpAdapter _adapter;
private readonly IBot _bot;
public BotController(IBotFrameworkHttpAdapter adapter, IBot bot)
{
_adapter = adapter;
_bot = bot;
}
[HttpGet, HttpPost]
public async Task PostAsync()
{
// Delegate the processing of the HTTP POST to the adapter.
// The adapter will invoke the bot.
await _adapter.ProcessAsync(Request, Response, _bot);
}
}
}
Can I add a new Route here? like [Route("directline/token")] ?
I know I could do this with an extra "token-server" (I don't know how to realise it, but I know that would work), but if possible I'd like to do this with my already existing c#-bot as I did it with my JS-Bot.
I have posted an answer which includes how to implement an API to get a direct line access token in C# bot and how to get this token, just refer to here. If you have any further questions, pls feel free to let me know .
Update :
My code is based on this demo . If you are using .net core, pls create a TokenController.cs under /Controllers folder:
Code of TokenController.cs :
using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
namespace Microsoft.BotBuilderSamples.Controllers
{
[Route("api/token")]
[ApiController]
public class TokenController : ControllerBase
{
[HttpGet]
public async Task<ObjectResult> getToken()
{
var secret = "<direct line secret here>";
HttpClient client = new HttpClient();
HttpRequestMessage request = new HttpRequestMessage(
HttpMethod.Post,
$"https://directline.botframework.com/v3/directline/tokens/generate");
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", secret);
var userId = $"dl_{Guid.NewGuid()}";
request.Content = new StringContent(
Newtonsoft.Json.JsonConvert.SerializeObject(
new { User = new { Id = userId } }),
Encoding.UTF8,
"application/json");
var response = await client.SendAsync(request);
string token = String.Empty;
if (response.IsSuccessStatusCode)
{
var body = await response.Content.ReadAsStringAsync();
token = JsonConvert.DeserializeObject<DirectLineToken>(body).token;
}
var config = new ChatConfig()
{
token = token,
userId = userId
};
return Ok(config);
}
}
public class DirectLineToken
{
public string conversationId { get; set; }
public string token { get; set; }
public int expires_in { get; set; }
}
public class ChatConfig
{
public string token { get; set; }
public string userId { get; set; }
}
}
Run the project after you replace secret with your own direct line secret. You will be able to get token by url: http://localhost:3978/api/token on local :
I want to be able to login to my identity database with user name and password and retreive a JWT. Then I want to use the JWT to access data securely from my API.
I found out that the SDK code generated by VS2017 uses an old version of autorest, so I have switched to using Azure Autorest
The api and the SDK are both ASP.NET Core 2.0
To generate the SDK I use
AutoRest -mynamespace mytrack.Client -CodeGenerator CSharp -Modeler
Swagger -Input swagger.json -PackageName mytrack.client -AddCredentials true
The versions show as
AutoRest code generation utility [version: 2.0.4262; node: v8.11.2]
I have written my test as
using System;
using System.Threading.Tasks;
using Microsoft.Rest;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json.Linq;
using swagger; // my name space from the autorest command, not to be confused with swagger itself.
using swagger.Models;
namespace CoreClientTest
{
[TestClass]
public class MyTests
{
[TestMethod]
public void TestMethod1()
{
try
{
GetMyJob().Wait();
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
private static async Task GetMyJob()
{
var tokenRequest = new TokenRequest
{
Username = "myusername",
Password = "mypassword"
};
var credentials = new TokenCredentials("bearer token");
var uri = new Uri("https://localhost:44348", UriKind.Absolute);
var tokenClient = new Track3API(uri, credentials);
var tokenResponse = await tokenClient.ApiRequestTokenPostWithHttpMessagesAsync(tokenRequest);
var tokenContent = await tokenResponse.Response.Content.ReadAsStringAsync();
var tokenString = JObject.Parse(tokenContent).GetValue("token").ToString();
var creds2 = new TokenCredentials(tokenString);
var client2 = new Track3API(uri, creds2);
var result = await client2.ApiJobsByIdGetWithHttpMessagesAsync(1);
var response = result.Response;
Console.WriteLine(response.ToString());
}
}
}
I can see that the result has OK and I can see the token in it.
I cant see the return job
The method in the api has
[Produces("application/json")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
[Route("api/jobs")]
public class JobController : Controller
{
/// <summary>
/// Returns Job Header for Id
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
[HttpGet("{id}", Name = "Get")]
public IActionResult Get(int id)
{
var header1 = new JobHeader
{
JobNumber = "1234",
Id = id,
CustomerPurchaseOrderNumber = "fred"
};
return Ok(header1);
}
}
You should apply the DataContract attribute over the class so that when RestClient consumes the service reference, it also generate the types.
Read it here.
You should also attach DatamMember attribute on Property. See below example
[DataContract]
class Person
{
[DataMember]
public string Name {get; set; }
[DataMember]
public int Id {get; set; }
public Person(string name, int id)
{
this.Name = name;
this.Id = id;
}
}
When Rest Client consume the service, it will generate the classes at client side for those classes which are attributed with DataContract.
Finally it is working.
I found a tip at Andrei Dzimchuk's blog on setting up the token
using System;
using System.Threading.Tasks;
using Microsoft.Rest;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using swagger;
using swagger.Models;
namespace CoreClientTest
{
[TestClass]
public class MyTests
{
[TestMethod]
public void TestMethod1()
{
try
{
GetMyJob().Wait();
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
private static async Task<JobHeader> GetMyJob()
{
var tokenRequest = new TokenRequest
{
Username = "myusername",
Password = "mypassword"
};
var credentials = new TokenCredentials("bearer token");
var uri = new Uri("https://localhost:44348", UriKind.Absolute);
var tokenClient = new Track3API(uri, credentials);
var tokenResponse = await tokenClient.ApiRequestTokenPostWithHttpMessagesAsync(tokenRequest);
var tokenContent = await tokenResponse.Response.Content.ReadAsStringAsync();
var tokenString = JObject.Parse(tokenContent).GetValue("token").ToString();
var creds2 = new TokenCredentials(tokenString);
var client2 = new Track3API(uri, creds2);
var result = await client2.ApiJobsByIdGetWithHttpMessagesAsync(1);
string resultContent = await result.Response.Content.ReadAsStringAsync();
var job = JsonConvert.DeserializeObject<JobHeader>(resultContent);
Console.WriteLine(job.JobNumber);
return job;
}
}
}
I have to integrate Ecom express shipping API in my code. This api is for pre generation of AWB Number at the time of order. Here is the document instruction to integrate shipping api :
Test Server URL:http://staging.ecomexpress.in/apiv2/fetch_awb/
Test Server Credentials: Username: ecomexpress Password: Ke$3c#4oT5m6h#$
Sample Request Body :
For PPD
username=ecomexpress&password=Ke$3c#4oT5m6h#$&count=1&type=PPD
For COD
username=ecomexpress&password=Ke$3c#4oT5m6h#$&count=1&type=COD
This API works fine with postman and generate AWB number also, But trying with C# code gives null object.
Check here the code I am using :
var client = new HttpHandler.Client("http://staging.ecomexpress.in/apiv2/fetch_awb/");
var newUrl = "http://staging.ecomexpress.in/apiv2/fetch_awb/?username=ecomexpress&password=Ke$3c#4oT5m6h#$&count=1&type=PPD";
var data = client.PostData<dynamic>(newUrl, new { username= "ecomexpress", password= "Ke$3c#4oT5m6h#$", count=1,type= "PPD" });
if (data!=null){ // do some stuff here }
I am using http handler nuget package (https://www.nuget.org/packages/VerveLogic.HttpHandler/)
Please help or suggest a way in which I can get AWB Number using C# code.Also check the postman and document instruction here :
You can easily make this work using HttpClient and Newtonsoft.Json, so might be something with that particular library not sending the parameters as form-urlencoded.
using (var client = new HttpClient())
{
var content = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("username", "ecomexpress"),
new KeyValuePair<string, string>("password", "Ke$3c#4oT5m6h#$"),
new KeyValuePair<string, string>("count", "1"),
new KeyValuePair<string, string>("type", "PPD"),
});
var response = await client.PostAsync("http://staging.ecomexpress.in/apiv2/fetch_awb/", content);
var body = await response.Content.ReadAsStringAsync();
var responseObject = JsonConvert.DeserializeObject<ResponseObject>(body);
}
Where ResponseObject is:
public class ResponseObject
{
[JsonProperty("reference_id")]
public int ReferenceId { get; set; }
[JsonProperty("success")]
public string SuccessText { get; set; }
[JsonIgnore]
public bool Success => SuccessText.Equals("yes", StringComparison.OrdinalIgnoreCase);
[JsonProperty("awb")]
public int[] Awb { get; set; }
}
I'm attempting to translate some English text to Chinese using Bing Translate's API.
My code is essentially what was provided on MSDN, albeit with a few modifications.
using System;
using System.Text;
using System.Net;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Web;
using System.ServiceModel.Channels;
using System.ServiceModel;
namespace AutoTranslate2
{
public class Translator
{
private string authToken;
public Translator(string clientId, string clientSecret)
{
AdmAccessToken admToken;
AdmAuthentication admAuth = new AdmAuthentication("clientId", "client secret");
admToken = admAuth.GetAccessToken();
DateTime tokenReceived = DateTime.Now;
this.authToken = "Bearer " + admToken.access_token;
}
public string TranslateMethod(
string text,
string inputLang = "en",
string outputLang = "zh-CHS", // Chinese, simplified ('zh-CHT' is traditional Chinese)
string inputType = "text/html",
string outputType = "general")
{
// Add TranslatorService as a service reference, Address:http://api.microsofttranslator.com/V2/Soap.svc
TranslatorService.LanguageServiceClient client = new TranslatorService.LanguageServiceClient();
//Set Authorization header before sending the request
HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty();
httpRequestProperty.Method = "POST";
httpRequestProperty.Headers.Add("Authorization", this.authToken);
// Creates a block within which an OperationContext object is in scope.
string translationResult;
using (OperationContextScope scope = new OperationContextScope(client.InnerChannel))
{
OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = httpRequestProperty;
//Keep appId parameter blank as we are sending access token in authorization header.
translationResult = client.Translate("", "<p>" + text + "</p>", inputLang, outputLang, inputType, outputType);
}
return translationResult;
}
}
[DataContract]
public class AdmAccessToken
{
[DataMember]
public string access_token { get; set; }
[DataMember]
public string token_type { get; set; }
[DataMember]
public string expires_in { get; set; }
[DataMember]
public string scope { get; set; }
}
public class AdmAuthentication
{
public static readonly string DatamarketAccessUri = "https://datamarket.accesscontrol.windows.net/v2/OAuth2-13";
private string clientId;
private string clientSecret;
private string request;
public AdmAuthentication(string clientId, string clientSecret)
{
this.clientId = clientId;
this.clientSecret = clientSecret;
//If clientid or client secret has special characters, encode before sending request
this.request = string.Format("grant_type=client_credentials&client_id={0}&client_secret={1}&scope=http://api.microsofttranslator.com", HttpUtility.UrlEncode(clientId), HttpUtility.UrlEncode(clientSecret));
}
public AdmAccessToken GetAccessToken()
{
return HttpPost(DatamarketAccessUri, this.request);
}
private AdmAccessToken HttpPost(string DatamarketAccessUri, string requestDetails)
{
//Prepare OAuth request
WebRequest webRequest = WebRequest.Create(DatamarketAccessUri);
webRequest.ContentType = "application/x-www-form-urlencoded";
webRequest.Method = "POST";
byte[] bytes = Encoding.ASCII.GetBytes(requestDetails);
webRequest.ContentLength = bytes.Length;
using (Stream outputStream = webRequest.GetRequestStream())
{
outputStream.Write(bytes, 0, bytes.Length);
}
WebResponse webResponse = webRequest.GetResponse();
using (webResponse)
{
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(AdmAccessToken));
//Get deserialized object from JSON stream
AdmAccessToken token = (AdmAccessToken)serializer.ReadObject(webResponse.GetResponseStream());
return token;
}
}
}
}
...and somewhere else in my code, I do...
Translator t = new Translator(client_id, secret);
string output = t.TranslateMethod(text);
However, the code always returns an exception:
Unhandled Exception: System.Net.WebException: The remote server returned an error: (400) Bad Request.
at System.Net.HttpWebRequest.GetResponse()
at AutoTranslate2.AdmAuthentication.HttpPost(String DatamarketAccessUri, String requestDetails) in C:\Users\Deflect\AutoTranslate2\AutoTranslate2\Translate.cs:line 102
at AutoTranslate2.AdmAuthentication.GetAccessToken() in C:\Users\Deflect\AutoTranslate2\AutoTranslate2\Translate.cs:line 87
at AutoTranslate2.Translator..ctor(String clientId, String clientSecret) in C:\Users\Deflect\AutoTranslate2\AutoTranslate2\Translate.cs:line 26
at AutoTranslate2.Chinese.Parse(String rawText) in C:\Users\Deflect\AutoTranslate2\AutoTranslate2\Parse.cs:line 68
at AutoTranslate2.Program.Main(String[] args) in C:\Users\Deflect\AutoTranslate2\AutoTranslate2\Program.cs:line 19
I'll be the first to admit I really don't know what my code is doing, since I mostly copied and pasted from MSDN -- does anybody know why my code is returning an exception, and how I can get it to work?
It was this line:
AdmAuthentication admAuth = new AdmAuthentication("clientId", "client secret");
I forgot to swap the strings in the examples with the actual variables.