Update .gitlab-ci.yml file in GitLab using Gitlab API in C# - asp.net-core

I am working on a project that has a file .gitlab-ci.yml in master branch. I am trying to update that .yml file using gitlab api (https://docs.gitlab.com/ee/api/commits.html#create-a-commit-with-multiple-files-and-actions) but using it from a asp.net core 5 application.
Here is my try. But I am getting 400 bad request error. Kindly help to find out what is wrong I am doing here.
public IActionResult Update()
{
var url = $"{ProjectUrl}/{ProjectId}/repository/commits/";
var httpRequest = (HttpWebRequest)WebRequest.Create(url);
httpRequest.Method = "PUT";
httpRequest.Headers["PRIVATE-TOKEN"] = ClientSecret;
httpRequest.ContentType = "application/json";
var str =
#"{'branch': 'master',
'commit_message': 'some commit message',
'actions': [
{
'action': 'update',
'file_path': '.gitlab-ci.yml',
'content': 'some content'
}
}";
var data = str;
using (var streamWriter = new StreamWriter(httpRequest.GetRequestStream()))
{
streamWriter.Write(data);
}
var httpResponse = (HttpWebResponse)httpRequest.GetResponse(); // I'm getting 400 Bad request error here
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var result = streamReader.ReadToEnd();
// rest of the code goes here
}
return View();
}

Well after rewriting the code, finally I am able to make it works. Posting my solution here in a hope that someone will be benefited from this. Cheers!
using (var httpClient = new HttpClient())
{
using (var request = new HttpRequestMessage(new HttpMethod("PUT"), "https://ProjectUrl/api/v4/projects/projectid/repository/%2Egitlab%2Dci.yml"))
{
request.Headers.TryAddWithoutValidation("PRIVATE-TOKEN", "<your_private_token>");
request.Content = new StringContent("{\"branch\": \"master\", \"author_email\": \"user#email.com\", \"author_name\": \"user\", \n \"content\": \"some content\", \"commit_message\": \"update file\"}");
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
var response = await httpClient.SendAsync(request);
}
}

Related

Upload an image to Strapi using Xamarin.Forms

Currently im working on a xamarin forms app, that upload image to Strapi API. To take a picture from the camera i'm using CrossMedia Plugin
var photo = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions() { PhotoSize= PhotoSize.Small, CompressionQuality = 100 });
if (photo != null)
ProductPic.Source = ImageSource.FromStream(() => { return photo.GetStream(); });
than send the photo in post Method :
HttpClient httpClient = new HttpClient();
MultipartFormDataContent mt = new MultipartFormDataContent();
photo.GetStream().Position = 0;
StreamContent imagePart = new StreamContent(photo.GetStream());
imagePart.Headers.Add("files", "jpg");
mt.Add(imagePart, string.Format("image"), string.Format("bsk.jpeg"));
var response = await httpClient.PostAsync("http://111.111.111.111:2222/upload", mt);
The problem that im facing this error
"{\"statusCode\":400,\"error\":\"Bad Request\",\"message\":\"Bad Request\",\"data\":{\"errors\":[{\"id\":\"Upload.status.empty\",\"message\":\"Files are empty\"}]}}
The error points the image part is empty , try to replace StreamContent with ByteArrayContent , send ByteArray instead of Stream .
HttpClient httpClient = new HttpClient();
MultipartFormDataContent mt = new MultipartFormDataContent();
mt.Headers.ContentType.MediaType = "multipart/form-data";
var upfilebytes = File.ReadAllBytes(photo.Path);
mt.Add(new ByteArrayContent(upfilebytes, 0, upfilebytes.Count()), string.Format("image"), string.Format("bsk.jpeg"));
var response = await httpClient.PostAsync("http://111.111.111.111:2222/upload", mt);
Refer to
https://stackoverflow.com/a/61095848/8187800.

Missing user_metadata in userInfo of auth0

For authentication I am using Auth0 AuthenticationApi. In Account Controller, I need to fetch the user_metadata but it's missing. Any alternative to fetch the user_metadata?
AuthenticationApiClient client = new AuthenticationApiClient(new Uri($"https://{_auth0Options.Domain}/"));
var authenticateResponse = await client.GetTokenAsync(new ResourceOwnerTokenRequest
{
ClientId = _auth0Options.ClientId,
ClientSecret = _auth0Options.ClientSecret,
Scope = "openid",
Realm = _auth0Options.Connection,
Username = vm.EmailAddress,
Password = vm.Password
});
var user = await client.GetUserInfoAsync(authenticateResponse.AccessToken);
if (user.UserMetadata != null)
{
// Giving error...any alternative to access the userMetaData ?
}
Yes, as far as I see it now, the legacy call still works. However, I don't have a non-legacy solution yet :(
using (var client = GetClient())
{
var jObject = new JObject(new JProperty("id_token", id_token));
var response = await client.PostAsJsonAsync("tokeninfo", jObject);
if (response.IsSuccessStatusCode)
{
var userProfileJson = JObject.Parse(await response.Content.ReadAsStringAsync());
retVal.user_id = userProfileJson.Value<string>("user_id");
retVal.email = userProfileJson.Value<string>("email");
retVal.user_name = userProfileJson.Value<string>("nickname");
if (userProfileJson.Value<string>("created_at") != null)
{
retVal.created_at = userProfileJson.Value<DateTime>("created_at");
}
var exists = userProfileJson.TryGetValue("user_metadata", out JToken meta);

Jsreport Malformed URI error when rendering Async

Since I am sending lots of data with the request, I have to use renderAsync to use POST. When the stream came back, I use the following JS code to open it
jsreport.renderAsync(request).then(function(arrayBuffer) {
window.open("data:application/pdf;base64," + arrayBuffer
)};);
But then the error showed. Is there alternative way to do it?
This seems to work
<script>
jsreport.renderAsync(request).then(function(response) {
var uInt8Array = new Uint8Array(response);
var i = uInt8Array.length;
var binaryString = new Array(i);
while (i--)
{
binaryString[i] = String.fromCharCode(uInt8Array[i]);
}
var data = binaryString.join('');
var base64 = window.btoa(data);
window.open("data:application/pdf;base64, " + base64);
})
</script>

Dynamics CRM Web Api Function: Illegal characters in path when using encodeURIComponent

I'm trying to use the Search Function (https://msdn.microsoft.com/en-us/library/mt608029.aspx) via the Dynamics CRM 2016 Web API. This is my code:
var start = new Date(2016, 2, 1, 17, 0, 0);
var end = new Date(2016, 2, 10, 18, 0, 0);
var request = new Object();
request.AppointmentRequest = new Object();
request.AppointmentRequest.SearchWindowStart = start.toISOString();
request.AppointmentRequest.SearchWindowEnd = end.toISOString();
request.AppointmentRequest.ServiceId = "5f3b6e7f-48c0-e511-80d7-d89d67631c44";
request.AppointmentRequest.Direction = 0;
request.AppointmentRequest.NumberOfResults = 10;
request.AppointmentRequest.UserTimeZone = 1;
var req = new XMLHttpRequest()
req.open("GET", clientUrl + "/api/data/v8.0/Search(" + encodeURIComponent( JSON.stringify(request) ) +")", true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.onreadystatechange = function () {
if (req.readyState == 4 && req.status == 200) {
alert(req.responseText);
}
else {
alert(req.response);
}
};
req.send();
When I initially tried this using CRM Online I received the following error:
"An error has occurred.
Try this action again. If the problem continues, check the Microsoft Dynamics >CRM Community for solutions or contact your organization's Microsoft >Dynamics CRM Administrator. Finally, you can contact Microsoft Support."
When I try this with an On-Premise deployment with DevErrors="On" in the web.config, I see the following error in the Event Viewer:
Exception information:
Exception type: HttpException
Exception message: A potentially dangerous Request.Path value was detected >from the client (:).
at System.Web.HttpRequest.ValidateInputIfRequiredByConfig()
at System.Web.HttpApplication.PipelineStepManager.ValidateHelper(HttpContext >context)
Request information:
Request URL: http://win-0e5dfqgqorm:444/ORG/api/data/v8.0/Search({"AppointmentRequest":{"SearchWindowStart":"2016-03-01T17:00:00.000Z","SearchWindowEnd":"2016-03-10T18:00:00.000Z","ServiceId":"5f3b6e7f-48c0-e511-80d7-d89d67631c44","Direction":0,"NumberOfResults":10,"UserTimeZone":1}})
Request path: /SHUDEV/api/data/v8.0/Search({"AppointmentRequest":{"SearchWindowStart":"2016-03-01T17:00:00.000Z","SearchWindowEnd":"2016-03-10T18:00:00.000Z","ServiceId":"5f3b6e7f-48c0-e511-80d7-d89d67631c44","Direction":0,"NumberOfResults":10,"UserTimeZone":1}})
The JSON object is encoded so I'm not sure why it's detected illegal characters. The SDK documentation for the Web Api is light and doesn't go into too much detail as to how to pass a ComplexType to a Web Api function, has anyone seen this issue before/managed to pass a ComplexType to a Web Api function?
Thanks in advance.
I managed to resolve this issue. The key is to pass the JSON object in as a query parameter:
var request = new Object();
request.SearchWindowStart = start.toISOString();
request.SearchWindowEnd = end.toISOString();
request.ServiceId = "5f3b6e7f-48c0-e511-80d7-d89d67631c44";
request.Direction = '0';
request.NumberOfResults = 10;
request.UserTimeZoneCode = 1;
var req = new XMLHttpRequest()
req.open("GET", clientUrl + "/api/data/v8.0/Search(AppointmentRequest=#request)?#request=" + JSON.stringify(request) , true);
req.setRequestHeader("Accept", "application/json");
req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
req.setRequestHeader("OData-MaxVersion", "4.0");
req.setRequestHeader("OData-Version", "4.0");
req.onreadystatechange = function () {
if (req.readyState == 4 && req.status == 200) {
alert(req.responseText);
}
else {
alert(req.response);
}
};
req.send();
This is documented in the SDK: https://msdn.microsoft.com/en-us/library/gg309638.aspx.
Hope this helps anyone who runs into a similar issue.

Can't read data from WCF data service using titanium

I created a WCF data service which return JSON format
public static void InitializeService(DataServiceConfiguration config)
{
// TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
// Examples:
config.SetEntitySetAccessRule("", EntitySetRights.AllRead);
config.SetServiceOperationAccessRule("", ServiceOperationRights.All);
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
}
i used titanium to connect to web service to get data
var label= Titanium.UI.createLabel({
top:300
});
var data = [];
// Connecting to WCF data service
var xhr = Titanium.Network.createHTTPClient();
var theURL = 'http://localhost:4338/DataService.svc/Orders?$format=json';
var json;
xhr.onload = function (){
var json = JSON.parse(this.responseText);
};
for (var i = 0 ; i < json.length; i++)
{
data.push(json[i]);
}
label.text = data[0].OrderID;
xhr.open('Get',theURL);
what is wrong
First of all you have to be aware that HTTP requests are asynchchronous, which means although it will take some time to fetch the response (depending on the internet connection, server speed, data size etc.), the succeeding code is executed. If the request was synchronous, it would block the app and any user interaction while it loads. That is why the client provides callbacks that are fired on certain state changes.
Your code
var data = [];
// Connecting to WCF data service
var xhr = Titanium.Network.createHTTPClient();
// Just guessing, but is the $ necessary?
var theURL = 'http://localhost:4338/DataService.svc/Orders?$format=json';
// You are defining json here 'globally'
var json;
xhr.onload = function (){
// You are defining the json variable within the scope of
// the onload function, so it can't be accessed from outside
// the function. Moreover, you are overwriting json of the global scope
// within this function
var json = JSON.parse(this.responseText);
};
// At this point, json is undefined
// Moreover, this code is executed before xhr.onload fires
for (var i = 0 ; i < json.length; i++)
{
data.push(json[i]);
}
label.text = data[0].OrderID;
// Method should be GET not Get
xhr.open('Get',theURL);
How it should work
var data = [];
var theURL = 'http://localhost:4338/DataService.svc/Orders?format=json';
var xhr = Titanium.Network.createHTTPClient();
xhr.onload = function (){
// Assuming that you have a valid json response
var json = JSON.parse(this.responseText);
for (var i=0; i < json.length; i++) {
data.push(json[i]);
}
// For testing, otherwise make sure it won't break if your response is empty
label.text = data[0].OrderID;
};
xhr.open('GET', theURL);