问题
I have a PowerShell script that I want to rewrite in C# (initially I wanted to call the PowerShell script from C#, but here it turned out that rewriting it is propably easier and more elegant).
So this is the PowerShell code I need to port to C#:
$uri = "$BaseUri/auth/token"
$bodyJson = ConvertTo-Json @{token = $ApiToken} -Compress
$response = Invoke-RestMethod `
-Uri $uri `
-Method Post `
-ContentType "application/json" `
-Body $bodyJson
$jwtToken = $response.token
#jwtToken is then used to authenticate a GET request:
$response = Invoke-RestMethod `
-Uri $uri `
-Method Get `
-ContentType "application/json" `
-Authentication Bearer `
-Token $jwtToken `
-AllowUnencryptedAuthentication
This is the C# equivalent I came up with:
//this is only called once
//ApiToken only has a field called "token", the class only exists for the JSON parser to work
ApiToken apiToken = new ApiToken();
client.BaseAddress = new Uri(baseUri);
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("token", apiToken.Token);
//this is called every time
Task <HttpResponseMessage> postTask = client.PostAsJsonAsync("auth/token", apiToken);
HttpResponseMessage response = await postTask;
jwt = response.???
Multiple problems here:
- I am new to PowerShell and HttpRequesting and I didn't write the script, so I don't fully understand every little detail here
- I don't know how to retrieve the JWT returned by the API, as I can't use
response.token
in C# (why does that even work in PowerShell? Why doesresponse
have a field called token?) - The C# code returns Error 401 (Unauthorized), while the PowerShell works fine with the same token. My theory is that this happens because I think I don't send the token correctly. (I'm not sure if my C# message matches the PowerShell
ConvertTo-Json @{token = $ApiToken} -Compress
) I feel like I didn't really find the proper equivalent for the-Token
parameter thatInvoke-RestMethod
has.
回答1:
1) What precisely do you not understand?
2) It works in Powershell because Invoke-RestMethod de-serializes the response and the response contains a field named 'token'. The C# program however wants to know the data structure at compile time. So unless you define it, your program doesn't know about it.
3) If you are doing OAuth, you should be setting "Bearer" in AuthenticationHeaderValue
client.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", apiToken.Token);
About the request itself:
I can not comment on client.PostAsJson()
as I cannot find recent information on the HttpClientExtensions class and my dev environment does not import it automatically either.
However, here is how I did my last webrequest:
var apiToken = new ApiToken()
{
Token = "mysecret",
};
HttpResponseMessage response = Task<HttpResponseMessage>.Run(async () =>
{
return await client.PostAsync(
requestUri: uriEndpoint,
content: new StringContent(
content: JsonConvert.SerializeObject(apiToken),
encoding: Encoding.UTF8,
mediaType: "application/json"))
.ConfigureAwait(true);
}).Result;
string fullResponse = await response.Content.ReadAsStringAsync().ConfigureAwait(true);
ApiToken apiResponse = JsonConvert.DeserializeObject<ApiToken>(fullResponse);
Please note that JsonConvert comes from Newtonsoft.Json
来源:https://stackoverflow.com/questions/58974020/c-sharp-equivalent-for-powershell-invoke-restmethod-token