How to concat rows text from a list into a success text msg in .Net Core wep api - asp.net-core

concat rows text from a list into a success text msg in .Net Core wep api

Has nothing to do with WebAPI itself. It is more of a framework issue. Use string.Join(delimiter, ienumerable).
However, here is an example:
[Route("api/[controller]")]
public class DemoController : Controller
{
[HttpGet]
public IActionResult Get()
{
var listOfMessages = new[] {"these", "should", "be", "combined"};
var result = string.Join(' ', listOfMessages);
return Ok(result);
}
}
The result looks like this:
HTTP/1.1 200 OK
Content-Type: text/plain; charset=utf-8
Date: Tue, 22 May 2018 10:59:38 GMT
Content-Length: 24
these should be combined

Related

Correctly perform the DELETE with RestSharp

Till now I've used RestSharp to perform POST/GET passing a JSON payload as parameter/body.
Now I've to perform a delete (you can see the example form documentation just here)
DELETE https://api.xxx.it/shipment
HTTP/1.1 Accept-Encoding: gzip,deflate
Content-Type: application/x-www-form-urlencoded
X-API-KEY: APIKEY123456789
Content-Length: 10 Host: api.xxx.it
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
id=1234567
and my code below.
public Task PerformShipmentDeleteAsync(ShipmentDeleteRequest objectRequest)
{
var client = new RestClient(settingsService.Endpoint);
var request = new RestRequest("shipment", DataFormat.Json);
request.AddHeader(Constants.XApiKey, settingsService.ApiXKey);
request.AddParameter( "text/plain",$"id={objectRequest.Id}", ParameterType.RequestBody);
var res = client.Delete(request);
return Task.CompletedTask;
}
and ShipmentDeleteRequest.cs
public class ShipmentDeleteRequest
{
[JsonProperty("id")]
public int Id { get;set; }
}
The only way I've found is to format the string in this way, but It's a hack.
How do I correctly pass the body as the example without passing a string but just the C# object?

PostAsJsonAsync posts null

I am trying to post an object using PostAsJsonAsync, but it is always null at the receiving API. The calling code is here:
public async Task UploadDocument(FileDto model)
{
var response = await _httpClient.PostAsJsonAsync("file/UploadDocument", model);
response.EnsureSuccessStatusCode();
}
The signature of the receiving code is here:
[HttpPost]
[Route("UploadDocument")]
public async Task<IHttpActionResult> UploadDocument(FileDto document)
FileDto is identical in both projects and only contains one string property "FileName"
The problem is that the document is always null.
I can use PostAsync which works fine:
public async Task UploadDocument(FileDto model)
{
string inputJson = Newtonsoft.Json.JsonConvert.SerializeObject(model);
HttpContent inputContent = new StringContent(inputJson, Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync("file/UploadDocument", inputContent);
response.EnsureSuccessStatusCode();
}
Looking at Fiddler, with the first (not working) example, the request looks like this:
POST http://localhost:59322/api/file/UploadDocument HTTP/1.1
Accept: application/json
Transfer-Encoding: chunked
Content-Type: application/json; charset=utf-8
Host: localhost:59322
28
{"FileName":"File-0000004157.jpg"}
0
The second (working) example looks like this in Fiddler:
POST http://localhost:59322/api/file/UploadDocument HTTP/1.1
Accept: application/json
Transfer-Encoding: chunked
Content-Type: application/json; charset=utf-8
Host: localhost:59322
{"FileName":"File-0000004157.jpg"}
The first example appears to have added extra text - see the "28" and "0".
Where is this text coming from. I can just go with PostAsync, but it seems a shame to add the extra code when PostAsJsonAsync does it for you.
Anybody have any ideas?
You need to return IActionResult instead of IHttpActionResult in asp.net core
[HttpPost]
[Route("UploadDocument")]
public async Task<IActionResult> UploadDocument(FileDto document)
{
return Ok(document);
}
https://learn.microsoft.com/en-us/aspnet/core/migration/webapi?view=aspnetcore-3.0
ASP.NET Core Web Api Error for IhttpActionResult
There seems to be an issue with PostAsJsonAsync in .net core : It returns a content-length of 0 causing the receiving ends to ignore the declared empty body.
https://github.com/aspnet/AspNetWebStack/issues/252
HttpClient PostAsJsonAsync behaving different in .NET Core and Classic .NET
The workaround is to use... PostAsync

Adding multiple allow headers is only adding the last header in http response

I am attempting to add multiple Allow Headers to the HttpResponse in aspnetcore v1.1.2. When I run the code below, the headers are added to the IHeaderDictionary on the HttpResponse, however only the last header (in this case "POST") in the collection is actually added to the http response when serialized. Has anyone else experienced this, or am I doing something wrong??
Here is the code I am using.
public override async Task OnResultExecutionAsync(ResultExecutingContext context, ResultExecutionDelegate next)
{
context.HttpContext.Response.Headers.Add("Allow", new StringValues(new [] {"GET", "POST"}));
await next();
}
I am doing this within a ResultFilterAttribute.
Many Thanks...
This should fix the issue:
context.HttpContext.Response.Headers.Add("Allow", "GET, POST");
Your code is fine, the only place that you may need to change is your response parsing logic. Double check your response - it contains 2 Allow headers, not one header with 2 values:
Allow: GET
Allow: POST
Simple example:
Lets say you have next controller action:
[Route("api/[controller]")]
public class ValuesController : Controller
{
// GET api/values
[HttpGet]
[AddHeader]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}
Get request using curl:
curl -X GET http://localhost:5000/api/values -i
Response:
HTTP/1.1 200 OK
Date: Fri, 23 Jun 2017 22:23:24 GMT
Content-Type: application/json; charset=utf-8
Server: Kestrel
Transfer-Encoding: chunked
Allow: GET
Allow: POST
["value1","value2"]

Why does RestSharp throw an error when deserializing a boolean response?

When I make a request in RestSharp like so:
var response = client.Execute<bool>(request);
I get the following error:
"Unable to cast object of type 'System.Boolean' to type 'System.Collections.Generic.IDictionary`2[System.String,System.Object]'."
This is complete HTTP response, per Fiddler:
HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/7.5
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 01 Apr 2013 15:09:14 GMT
Content-Length: 5
false
It appears that everything is kosher with the response, so what gives?
Also, if I'm doing something stupid with my WebAPI Controller by returning a simple value instead of an object and that would fix my problem, feel free to suggest.
RestSharp will only deserialise valid json. false is not valid json (according to RFC-4627). The server will need to return something like the following at the least:
{ "foo": false }
And you'll need a class like to following to deserialize to:
public class BooleanResponse
{
public bool Foo { get; set; }
}

Internet Explorer error using Asp MVC 4.0 FileResult

I have the following code, deployed on a https Asp site, build with MVC 4.0:
public FileResult ANotSoWorkingFunction(string filePath, string fileName)
{
pathToFile = string.Format("~/{0}/{1}", pathToFile, fileName);
return File(new FileStream(pathToFile, FileMode.Open), "application/pdf", fileName);
}
This will work (as you many of you probably already guessed) with Chrome, Firefox and IE9. But it will throw a:
---------------------------
Windows Internet Explorer
---------------------------
Internet Explorer cannot download someFileName from a_site.com.
Internet Explorer was not able to open this Internet site. The requested site is either unavailable or cannot be found. Please try again later.
---------------------------
OK
---------------------------
On IE6,7,8
Any ideas or clues on this one are greatly appreciated as I already spend the hole day playing with html header.
EDIT:
Here are the header from IE7:
HTTP/1.1 200 OK
Cache-Control: private, no-cache="Set-Cookie"
Content-Type: application/pdf
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 4.0
X-AspNet-Version: 4.0.30319
Set-Cookie: .ASPXAUTH=; expires=Mon, 11-Oct-1999 21:00:00 GMT; path=/; HttpOnly
X-Powered-By: ASP.NET
Date: Wed, 04 Apr 2012 08:43:50 GMT
Content-Length: 233324
And here are the ones from IE9:
HTTP/1.1 200 OK
Cache-Control: private, no-cache="Set-Cookie"
Content-Type: application/pdf
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 4.0
X-AspNet-Version: 4.0.30319
Set-Cookie: .ASPXAUTH=; expires=Mon, 11-Oct-1999 21:00:00 GMT; path=/; HttpOnly
X-Powered-By: ASP.NET
Date: Wed, 04 Apr 2012 08:42:14 GMT
Content-Length: 233324
Thank you,
I think I also ran into your problem.
I am also running IIS 7.5 and downloading a PDF through an action on an HTTPS request. For reasons I have yet to isolate, IIS 7.5 seems to be appending no-cache="Set-Cookie" to my Cache-Control response header regardless of what I set the Cache settings to on the Response. This was causing the fairly well documented no-cache issue on IE6, IE7, and IE8.
To resolve this, I made a small wrapper around the FileContentResult that cleared the headers, called the parent, then set the Cacheability to 'Private'. This side-stepped IIS 7.5's insistence to add no-cache="Set-Cookie" to the header, and the file downloaded properly in all browsers I tested. If you want to emulate what I did, first, here's my FileContentResult wrapper.
public class PdfContentResult : FileContentResult {
public PdfContentResult(byte[] data) : base(data, "application/pdf") { }
public PdfContentResult(byte[] data, string fileName) : this(data) {
if (fileName == null) {
throw new ArgumentNullException("fileName");
}
this.FileDownloadName = fileName;
}
public override void ExecuteResult(ControllerContext context) {
context.HttpContext.Response.ClearHeaders();
base.ExecuteResult(context);
context.HttpContext.Response.Cache.SetCacheability(HttpCacheability.Private);
}
}
Then I added an extension method to my ControllerExtensions so that it would be simple to find:
public static class ControllerExtensions {
public static PdfContentResult Pdf(this Controller controller, byte[] fileContents, string fileName) {
return new PdfContentResult(fileContents, fileName);
}
}
Finally, within the Action, I did the equivalent of this:
public ActionResult MyGeneratedPdf() {
byte[] myPdfContentInByteStream = GetPdfFromModel();
return this.Pdf(myPdfContentInByteStream, "MyFile.pdf");
}
Obviously, if you're downloading all kinds of data types, you might not want to bind the workaround so closely to PDF.
We resolved this by changing the cache-control header before streaming the file.
Simplified code sample:
var browserInformation = Request.Browser;
//Set as private if current browser type is IE
Response.AppendHeader("cache-control",
browserInformation.Browser == "IE" ? "private" : "no-cache");
return File(fileName, contentType, downloadFileName);
This worked (yay).. BUT I was left with a lack of clarity on why we had to do it this way for that specific site. We have four websites running on the same box, all under SSL, and only one had this header problem. I compared the web.config files and looked at the setup in IIS but couldn't shed any further light on why that one site needs those headers set explicitly.
If anyone has more to add on the above (for added clairty) that would be great.
In older versions of IE if a user tries to download a file over a HTTPS connection, any response headers that prevent caching will cause the file download process to fail. Below are most common headers which are causing the issue:
Cache-Control with the values no-cache or no-store
Vary with any value
Pragma with value no-cache
You can create an ActionFilterAttribute which will clear cache headers for you like this:
public class ClearCacheHeadersAttribute : FilterAttribute, IActionFilter
{
public void OnActionExecuted(ActionExecutedContext filterContext)
{
return;
}
public void OnActionExecuting(ActionExecutingContext filterContext)
{
HttpContext.Current.Response.Headers.Remove("Cache-Control");
HttpContext.Current.Response.Headers.Remove("Vary");
HttpContext.Current.Response.Headers.Remove("Pragma");
//Set the cache headers any way you like keeping in mind which values can brake the download
}
}
And decorate yoour action with it:
[ClearCacheHeaders]
public FileResult ANotSoWorkingFunction(string filePath, string fileName)
{
pathToFile = string.Format("~/{0}/{1}", pathToFile, fileName);
return File(new FileStream(pathToFile, FileMode.Open), "application/pdf", fileName);
}