No response received to multipart/mixed HTTP request - dotnet-httpclient

I am trying to use the Dynamics 365 Web API to GET records. The fetch query generated is too long to use a normal GET query so a workaround is to POST the request instead.
I have simplifed the fetch statement here for ease.
Ignore the lack of async/await and use of .Result, that can easily be sorted afterwards.
Code:
var clientcred = new ClientCredential(Config.ClientId, Config.ClientSecret);
var authenticationContext = new AuthenticationContext($"{Config.AadInstance}{Config.TenantId}");
var authenticationResult = authenticationContext.AcquireTokenAsync(Config.DynamicsUrl, clientcred).Result;
var token = authenticationResult.AccessToken;
var client = new HttpClient();
client.BaseAddress = new Uri("https://foobar.crm4.dynamics.com");
client.Timeout = new TimeSpan(0, 2, 0);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
client.DefaultRequestHeaders.Add("OData-Version", "4.0");
client.DefaultRequestHeaders.Add("OData-MaxVersion", "4.0");
client.DefaultRequestHeaders.Add("Prefer", "odata.include-annotations=\"*\"");
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
var req = new HttpRequestMessage(System.Net.Http.HttpMethod.Post, $"/api/data/v9.1/$batch");
var content = "--batch_rob--\n" +
"Content-Type: application/http\n" +
"Content-Transfer-Encoding: binary\n" +
$"GET {Config.BaseUrl}contacts?fetchXml=<fetch count=\"10\" ><entity name=\"contact\" ><attribute name=\"fullname\" /></entity></fetch> HTTP/1.1\n" +
"OData-Version: 4.0\n" +
"OData-MaxVersion: 4.0\n" +
"--batch_rob--";
using (var content2 = new MultipartContent())
{
content2.Add(new StringContent(content));
content2.Headers.Remove("Content-Type");
content2.Headers.TryAddWithoutValidation("Content-Type", "multipart/mixed;boundary=batch_rob");
var request = new HttpRequestMessage(System.Net.Http.HttpMethod.Post, $"/api/data/v9.1/$batch")
{
Content = content2
};
var response = client.SendAsync(request).Result;
var outcome2 = response.Content.ReadAsStringAsync().Result;
}
This all compiles and appears to run fine. The response however does not contain the JSON I expect (the result of the GET query) but rather is just:
--batchresponse_20851dc6-4ff6-4914-a749-66f451985f67--
Any idea what I have missed?
This is based on the example demonstrated here:
https://dreamingincrm.com/2017/01/15/executing-large-fetchxml-with-webapi/

Related

Bad request when posting to OData Data Entity in Dynamics 365

I've created a public Data Entity in dynamics with the following fields:
I keep getting a bad request response, but I'm not sure why.
I've tried to make a POST request in two ways:
1.
HireAction hireAction = new HireAction() { CompanyName = "DEMF", MovieId = "DEMF-000000014", HireActionStatus = "Created" };
string jsonMessage = JsonConvert.SerializeObject(hireAction);
using (HttpClient client = new HttpClient())
{
HttpRequestMessage requestMessage = new
HttpRequestMessage(HttpMethod.Post, "MyDynamicsEnvironmentName/data/HireActions?cross-company=true");
requestMessage.Content = new StringContent(jsonMessage, Encoding.UTF8, "application/json");
requestMessage.Headers.Add("Authorization", AuthResult.AuthorizationHeader);
HttpResponseMessage response = client.SendAsync(requestMessage).Result;
if (response.StatusCode == System.Net.HttpStatusCode.OK)
{
//Logic
}
}
var url = "MyDynamicsEnvironmentName/data/HireActions?cross-company=true";
var req = HttpWebRequest.Create(url);
req.Method = "POST";
req.ContentType = "application/json";
req.Headers["Authorization"] = AuthResult.AuthorizationHeader;
HireAction hireAction = new HireAction() { CompanyName = "DEMF", MovieId = "DEMF-000000014", HireActionId = "12345", HireActionStatus = "Created" };
var jsonSettings = new JsonSerializerSettings
{
DateTimeZoneHandling = DateTimeZoneHandling.Local
};
var postString = "CompanyName='DEMF'" + "&MovieId='DEMF-000000014'" + "&HireActionId=132&HireActionStatus='Created'";
var data = JsonConvert.SerializeObject(postString, jsonSettings);
var bytes = Encoding.Default.GetBytes(postString);
var newStream = req.GetRequestStream();
newStream.Write(bytes, 0, bytes.Length);
newStream.Close();
using (var resp = req.GetResponse())
{
var results = new StreamReader(resp.GetResponseStream()).ReadToEnd();
}
Some keypoints:
-Of course you'd replace MyDynamicsEnvironmentName with the URL for the environment. The URL is correct and verified however, by the fact that GET requests do work
-The Authresult.AuthorizationHeader contains a valid token, also validated by working GET requests
As said before, both of these result in a bad request. Does someone know what is wrong or missing?

Transition JIRA issue via API returning a 400

I'm trying to transition issues via the API using .NET but I'm consistently getting a 400 error back. I'm wondering if anyone can see anything obvious that I'm doing wrong?
Code:
string example = #"{
""id"": ""221""
}";
string ticketjson = JsonConvert.SerializeObject(example);
string postUrl = "https://myurl/rest/api/2/issue/" + issueKey + "/transitions";
System.Net.Http.HttpClient client = new System.Net.Http.HttpClient();
client.BaseAddress = new System.Uri(postUrl);
byte[] cred = UTF8Encoding.UTF8.GetBytes("username:pwd");
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", Convert.ToBase64String(cred));
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
var content = new StringContent(ticketjson, Encoding.UTF8, "application/json");
var response = client.PostAsync(postUrl, content).Result;
if (response.IsSuccessStatusCode)
{
string result = response.Content.ReadAsStringAsync().Result;
return result;
}
else
{
unauth.Text = "There has been a problem submitting your comment. Please try again.";
return response.StatusCode.ToString();
}
The transition exists and when I go to the postUrl I can see it:
Any help would be appreciated!

How to use LIKE operator for msg_id or from_email or to_email in query for sendgrid email activity?

var queryParams = "msg_id LIKE'pBRuJA0OSqyRAHaT2sW8hg'";
var client = new RestClient("https://api.sendgrid.com/v3/messages?query=" + queryParams + "&limit=1");
var request = new RestRequest(Method.GET);
client.Timeout = -1;
request.AddHeader("x-query-id", "{{x-query-id}}");
request.AddHeader("x-cursor", "{{x-cursor}}");
request.AddHeader("authorization", "bearer " + ApiKey);
IRestResponse response = client.Execute(request);
var sendGridEmailDetails = JsonConvert.DeserializeObject<SendGridResponse>(response.Content);
Here I want to find out msg_id start with this value 'pBRuJA0OSqyRAHaT2sW8hg' and I code for this as above. I used LIKE operator here but it gives me empty response. How to use LIKE operator if we want to find out startwith or endwith values? Does anyone know how this could be done? Thanks for your help & time.
This might be an empty result because you are not url encoding the request. It looks like you are using RestSharp to make requests to the API here, so what you can try instead is:
var params = new {
query = "msg_id LIKE 'pBRuJA0OSqyRAHaT2sW8hg'",
limit = 1
}
var client = new RestClient("https://api.sendgrid.com/v3/messages");
var request = new RestRequest(Method.GET);
request.addObject(params);
client.Timeout = -1;
request.AddHeader("x-query-id", "{{x-query-id}}");
request.AddHeader("x-cursor", "{{x-cursor}}");
request.AddHeader("authorization", "bearer " + ApiKey);
IRestResponse response = client.Execute(request);
var sendGridEmailDetails = JsonConvert.DeserializeObject<SendGridResponse>(response.Content);
This way you create an object of the parameters you want to pass and let the request object handle encoding them.

Why do my web api receive null values when posting to web API?

My Web API is receiving null value in Httpclient PostAsJsonAsync:
public static async Task<DefaultApiResponse<T>> PostList<T>(string url, string token, List<AddEventViewModel.Agenda> request)
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("bearer", token);
var content = JsonConvert.SerializeObject(request);
var buffer = System.Text.Encoding.UTF8.GetBytes(content);
var byteContent = new ByteArrayContent(buffer);
byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");
var httpResponse = await client.PostAsJsonAsync(url, byteContent);
var defaultresponse = JsonConvert.DeserializeObject<DefaultApiResponse<T>>(await httpResponse.Content.ReadAsStringAsync());
return defaultresponse;
}
Why?
I would try posting as a StringContent object instead
var content = new StringContent(
JsonConvert.SerializeObject(request),
Encoding.UTF8,
"application/json");
defaultresponse = await client.PostAsync(url, content);

Send HTTP Post with .Net Core

how can I set up an HTTP call in asp.net core mvc
$url = "https://prod-25.northeurope.logic.azure.com:443/..."
$parms = #{
Uri = $url
Method = 'post'
ContentType = 'application/json'
body = '{"recipient": "stefan.","body":"Test"}'
}
curl #parms
using
using System.Net.Http;
and your code will be
var url = "http://yoursite.com/Home/Insert";
var data = new {"recipient"= "stefan.", "body"="Test"};
using(var client = new HttpClient())
{
var response = await client.PostAsJsonAsync(url, data);
string responseContent = await response.Content.ReadAsStringAsync(); // only to see response as text ( debug perpose )
var result = await ProcessedResult<TResult>(response); // cast it to TResult or any type that you expect to retrieve
}

Resources