Valid value for TimeSpan property to post in web api? C# - c#

I have a TimeSpan property
public TimeSpan Time { get; set; }
Currently using swagger to test API
Trying to figure out what value value to pass here
"time": {},
Tried:
"time": {"01:01:01"},
"time": {"01:01"},
"time": "01:01:01",
"time": 01:01:01,
all returning 401 code

On this another page you will find the solution to the problem: .Net Core 3.0 TimeSpan deserialization error - Fixed in .Net 5.0.
In a complementary way, add this in the swagger
c.MapType<TimeSpan>(() => new OpenApiSchema
{
Type = "string",
Example = new OpenApiString("00:00:00")
});

Related

Import repository from one azure devops organization to another through the API

I am trying to automate some processes in our organization and part of that includes being able to transfer a repository in one of our azure devops organizations to another (think of it as a dev organization and a test organization so we are pushing from dev to test)
Through the API https://learn.microsoft.com/en-us/rest/api/azure/devops/git/import%20requests/create?view=azure-devops-rest-6.0 I am trying to create an import request.
Here's where I'm stumped and the documentation doesn't say much about.
If I use a request body like in the example:
{
"parameters": {
"gitSource": {
"url": "https://github.com/Microsoft/vsts-agent.git"
}
}
}
The import request works fine as long as I'm importing to an empty repository. However I need to be able to sync an existing repository.
[There's a property in the documentation called overwrite that seems to be for this purpose][1]: https://i.stack.imgur.com/ezCB3.png
The only problem is when I add this to the request body and set to true
{
"parameters": {
"gitSource": {
"url": "https://github.com/Microsoft/vsts-agent.git",
"overwrite": true
}
}
}
I get bad request message saying invalid combination of parameters
If I set this to false it works if I'm trying to import to an empty repository. If the repository isn't empty I get an error saying I can only import into an empty repo.
So it seems this property is meant for exactly what I'm doing, however it seems there are more parameters needed when that property is set to true in order to make the request succeed, but the documentation is lacking in this area.
Any help would be much appreciated
I suspect that overwrite = true is giving you error because there may be some permission issues or Auth problem in your latter repo.
Alternatively, you can fork your parent repository and sync only the provided refs:
CURL:
POST https://dev.azure.com/{organization}/_apis/git/repositories?sourceRef=users/heads/master&api-version=6.0
Request Body:
{
"name": "forkRepositoryWithOnlySourceRef",
"project": {
"id": "3b046b6a-d070-4cd5-ad59-2eace5d05b90"
},
"parentRepository": {
"id": "76b510af-7910-4a96-9902-b978d6226bee"
}
}
Sample response (HTTP 201):
{
"id": "29230c30-9125-459b-a3f6-ffab329053bd",
"name": "forkRepositoryWithOnlySourceRef",
"url": "https://dev.azure.com/fabrikam/MyFirstProject/_apis/git/repositories/29230c30-9125-459b-a3f6-ffab329053bd",
"project": {
"id": "3b046b6a-d070-4cd5-ad59-2eace5d05b90",
"name": "MyFirstProject",
"url": "https://dev.azure.com/fabrikam/_apis/projects/3b046b6a-d070-4cd5-ad59-2eace5d05b90",
"state": "wellFormed",
"revision": 12,
"visibility": "private",
"defaultTeamImageUrl": null
},
"size": 0,
"remoteUrl": "https://dev.azure.com/fabrikam/MyFirstProject/_git/forkRepositoryWithOnlySourceRef",
"sshUrl": "git#ssh.dev.azure.com:v3/fabrikam/MyFirstProject/forkRepositoryWithOnlySourceRef",
"isFork": true,
"_links": {
"forkSyncOperation": {
"href": "https://dev.azure.com/fabrikam/_apis/git/repositories/29230c30-9125-459b-a3f6-ffab329053bd/forkSyncRequests/7"
}
}
}

DateTime property issue when using servicestack autoquery

Thanks Mythz for providing such an amazing and powerful framework. However, I encountered the DateTime property rendered like this "/Date(1543681261000-0000)/" instead of "2019-03-25T12:50:3000" by using servicestack autoquery. I couldn't find any relevant docs. Please help me.
{
"customer": [
{
"transaction_total": 0,
"text": "0067 83228780",
"transaction_time": 0,
"action": 0,
"point_collection_on_registration": false,
"id": 71,
"push_notification_id": "null",
"name": "0067",
"ic": "27668",
"type": 0,
"phone_no": "83228780",
"point": 5132,
"balance": 1621.3,
"issue_date": "/Date(1543681261000-0000)/",
"is_subscribed": true,
"is_expiry": false,
"lang_preferred": "cn",
"is_delete": false
}
],
"count_all": 120
}
ServiceStack by default uses WCF Dates for JSON, see this answer for different ways to parse WCF Dates in JavaScript.
You can choose to change how dates are serialized in JSON for any JSON Response in ServiceStack by customizing JSON Responses, e.g you can change the JSON returned by the Auto Query Service with:
?jsconfig=DateHandler:ISO8601
?jsconfig=DateHandler:ISO8601DateOnly
?jsconfig=DateHandler:ISO8601DateTime
Or use the short-hand alias notation:
?jsconfig=dh:iso8601
?jsconfig=dh:iso8601do
?jsconfig=dh:iso8601dt
Alternatively you can tell ServiceStack to always use ISO8601 dates in JSON in your AppHost.Configure() with:
JsConfig.Init(new Config {
DateHandler = DateHandler.ISO8601
});

Why is Asp.net Core returning JSON instead of a CSV file? [duplicate]

I am currently working with ASP.NET Core RC2 and I am running into some strange results.
So I have an MVC controller with the following function:
public HttpResponseMessage Tunnel() {
var message = new HttpResponseMessage(HttpStatusCode.OK);
message.Content = new StringContent("blablabla", Encoding.UTF8);
message.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("text/plain");
message.Headers.CacheControl = new System.Net.Http.Headers.CacheControlHeaderValue {
NoCache = true
};
return message;
}
If I call this with postman with an Accept header set to text plain I get this response:
{
"Version": {
"Major": 1,
"Minor": 1,
"Build": -1,
"Revision": -1,
"MajorRevision": -1,
"MinorRevision": -1
},
"Content": {
"Headers": [
{
"Key": "Content-Type",
"Value": [
"text/plain"
]
}
]
},
"StatusCode": 200,
"ReasonPhrase": "OK",
"Headers": [
{
"Key": "Cache-Control",
"Value": [
"no-cache"
]
}
],
"RequestMessage": null,
"IsSuccessStatusCode": true
}
I really do not understand how this is the generated reponse to the above controller. It is basically a JSON serialization of the entire message itself and does in no way contain the "blablabla" I intended to send.
The only way I have gotten the desired result is by making my controller function return string instead of HttpResponse, but that way I am unable to set headers like CacheControl
So my question is: why do I get this strange response? It seems like very weird behaviour to me
According to this article, ASP.NET Core MVC does not support HttpResponseMessage-returning methods by default.
If you want to keep using it, you can, by using WebApiCompatShim:
Add reference to Microsoft.AspNetCore.Mvc.WebApiCompatShim to your project.
Configure it in ConfigureServices(): services.AddMvc().AddWebApiConventions();
Set up route for it in Configure():
app.UseMvc(routes =>
{
routes.MapWebApiRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
If you want to set Cache-Control header with string content, try this:
[Produces("text/plain")]
public string Tunnel()
{
Response.Headers.Add("Cache-Control", "no-cache");
return "blablabla";
}
In ASP.NET Core, modify the response as it travels through the pipeline. So for headers, set them directly as in this answer. (I've tested this for setting cookies.) You can also set the HTTP status code this way.
To set content, and therefore use a specific formatter, follow the documentation Format response data in ASP.NET Core Web API. This enables you to use helpers such as JsonResult() and ContentResult().
A complete example translating your code might be:
[HttpGet("tunnel")]
public ContentResult Tunnel() {
var response = HttpContext.Response;
response.StatusCode = (int) HttpStatusCode.OK;
response.Headers[HeaderNames.CacheControl] = CacheControlHeaderValue.NoCacheString;
return ContentResult("blablabla", "text/plain", Encoding.UTF8);
}

Trying to PUT string with Postman in local C# web api, always null or fails

I currently have this WEB API running locally:
// POST api/CsvParse
[HttpPut]
public void Put([FromBody]string value)
{
if (string.IsNullOrEmpty(value))
throw new Exception("Input is null or empty.");
}
I currently have it running locally, and am sending a string to the put using POSTMAN. I have selected the body tab, and have the string pasted into the raw body tab:
It states that my text is unsupported, or when I add a break point the value is null or I get the error describing the format is incorrect.
What am I doing wrong?
That's because there is no media type formatter that can serialize a raw string into your model (your route parameter with [FromBody] attribute).
A quick and dirty workaround is to directly read the body of your request as a string:
[HttpPut]
public async Task<HttpResponseMessage> Put(HttpRequestMessage request)
{
var myCsv = await request.Content.ReadAsStringAsync();
// do stuff with your string
return new HttpResponseMessage(HttpStatusCode.OK);
}
As an alternative you could implement a custom media type formatter yourself, as per this answer.
Change the media type to x-www-form-urlencoded rather than multipart/form-data.
Also, WebAPI is particular about FromBody parameters.
http://encosia.com/using-jquery-to-post-frombody-parameters-to-web-api/
For you, I think this is the relevant part:
[FromBody] parameters must be encoded as =value
The final hurdle remaining is that Web API requires you to pass
[FromBody] parameters in a particular format. That’s the reason why
our value parameter was null in the previous example even after we
decorated the method’s parameter with [FromBody].
Instead of the fairly standard key=value encoding that most client-
and server-side frameworks expect, Web API’s model binder expects to
find the [FromBody] values in the POST body without a key name at all.
In other words, instead of key=value, it’s looking for =value.
This part is, by far, the most confusing part of sending primitive
types into a Web API POST method. Not too bad once you understand it,
but terribly unintuitive and not discoverable.
Try adding a content type of text/plain
There is a similar Q&A here
I found that solution #1 worked for me as I was trying to PUT JSON containing the Key/Value pair. So originally my JSON looked like this
{
"subscriber": {
"Id": "2",
"subscriptions":[
{
"Name": "Subscription 1",
"Id": "18",
"IsSubscribed": false
},
{
"Name": "Subscription 2",
"Id": "19",
"IsSubscribed": false
},
{
"Name": "Subscription 3",
"Id": "20",
"IsSubscribed": false
}
]
}
}
But I modified it to become
{
"Id": "2",
"subscriptions":[
{
"Name": "Subscription 1",
"Id": "18",
"IsSubscribed": false
},
{
"Name": "Subscription 2",
"Id": "19",
"IsSubscribed": false
},
{
"Name": "Subscription 3",
"Id": "20",
"IsSubscribed": false
}
]
}
And that worked. My PUT request from Postman was recognised in my C# web api using [FromBody]
Just to add my bit, there is one more solution to pass primitives into a POST or a PUT method. Just specify the model as JObject. ASP.Net core web api then binds incoming JSON object(containing primitives like string) into JObject model object.
Your code would look like this:
// POST api/CsvParse
[HttpPut]
public void Put([FromBody]JObject value)
{
//access your string data
string data = value[SPECIFY_KEY_HERE];
if (string.IsNullOrEmpty(data))
throw new Exception("Input is null or empty.");
}

Retrieving "images" from a JSON string retrived from Instagram API

Using C# and Visual Studio 2010 (Windows Form Project), InstaSharp and Newtonsoft.Json libraries.
I want to get the image url from the JSON string returned to me by the Endpoint Instagram API when I request for a particular hashtag.
I can so far retrive the JSON string.
I am trying to use Newtonsoft.Json to deserialize the object using the examples, but I probably dont understand the JSON string representation of the object properly.
Below is a simplified sample response I get from the api call tags/tag-name/media/recent from their documentation. source here
{
"data": [{
"type": "image",
"filter": "Earlybird",
"tags": ["snow"],
"comments": {
}
"caption": {
},
"likes": {
},
"created_time": "1296703536",
"images": {
"low_resolution": {
"url": "http://distillery.s3.amazonaws.com/media/2011/02/02/f9443f3443484c40b4792fa7c76214d5_6.jpg",
"width": 306,
"height": 306
},
"thumbnail": {
"url": "http://distillery.s3.amazonaws.com/media/2011/02/02/f9443f3443484c40b4792fa7c76214d5_5.jpg",
"width": 150,
"height": 150
},
"standard_resolution": {
"url": "http://distillery.s3.amazonaws.com/media/2011/02/02/f9443f3443484c40b4792fa7c76214d5_7.jpg",
"width": 612,
"height": 612
}
},
"id": "22699663",
"location": null
},
...
]
}
I want to get specifically the standard_resolution in the images part.
This is the revelevant code that I currently have.
//Create the Client Configuration object using Instasharp
var config = new InstaSharp.Endpoints.Tags.Unauthenticated(config);
//Get the recent pictures of a particular hashtag (tagName)
var pictures = config.Recent(tagName);
//Deserialize the object to get the "images" part
var pictureResultObject = JsonConvert.DeserializeObject<dynamic>(pictureResult.Json);
consoleTextBox.Text = pictureResult.Json;
var imageUrl = pictureResultObject.Data.Images;
Console.WriteLine(imageUrl);
I get the error: Additional information: Cannot perform runtime binding on a null reference
so imageUrl is indeed null when I debug, hence indicating I am not accessing it the right way.
Anyone can explain to me how to access different parts of this JSON String using Newtonsoft.Json?
Using Newtonsoft.Json
dynamic dyn = JsonConvert.DeserializeObject(json);
foreach (var data in dyn.data)
{
Console.WriteLine("{0} - {1}",
data.filter,
data.images.standard_resolution.url);
}
I wrote a plugin for .net which takes care of deserializing the json string and returning a data table. it is still in development but see if it helps. Instagram.NET on Github

Categories