Download file or send json in web api method - c#

I have written web api in which it is returning/producing json response. Below is the code for the same.
[HttpGet]
[Route("someapi/myclassdata")]
[Produces("application/json")]
public MyClassData GetMyClassData(int ID, int isdownload)
{
myclassdata = myclassdataBL.GetMyClassData(ID);
return myclassdata;
//**Commented Code**
//if(isdownload==1)
//{
//download file
//}
//else
//{
// send response
//}
}
Till now it is working fine. Now I want to create and download the file based on value in 'isDownload' parameter.
So after getting the data if files needs to be downloaded I want to download the file otherwise I will send the json response.
So, my question is can we send json reponse or download the file in same web api method.
Any help on this appreciated!

Yes, this is easily achievable. Rather than returning MyClassData explicitly like that, you can return an IActionResult, like this:
public IActionResult GetMyClassData(int ID, int isdownload)
{
myclassdata = myclassdataBL.GetMyClassData(ID);
if (isDownload == 1)
return File(...);
return Ok(myclassdata);
}
Both File(...) and Ok(...) return an IActionResult, which allows for the dynamism you're asking for here.
Note: You can also just return Json(myclassdata) if you want to force JSON, but by default this will be JSON anyway and is more flexible with e.g. content-negotiation.
See Controller action return types in ASP.NET Core Web API for more details.

Related

ASP.Net core redirect to an action which return FileStreamResult

I have to actions in a controller:
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
[HttpGet("redirect1")]
public IActionResult Redirect1()
{
var r = RedirectToAction(nameof(GetStream));
return r;
}
[HttpGet("stream")]
public IActionResult GetStream()
{
var ms = new MemoryStream(Encoding.UTF8.GetBytes("Hello Word"));
return File(ms, "application/octet-stream", "test.xyz", true);
}
}
When I typed https://localhost:44352/api/values/redirect1, the save as dialog is open for download but the url in browser is not changed to https://localhost:44352/api/values/stream. Is a way to change also the url. In case the GetStream action return a json the url is changed to https://localhost:44352/api/values/stream. How is possible also to change the url in case I return FileStreamResult.
Is possible to have something in the view like "waiting..." and return FileStreamResult
How is possible also to change the url in case I return FileStreamResult?
You can return a HTML to make it:
public IActionResult Redirect1()
{
var r = RedirectToAction(nameof(GetStream));
return r;
var url = this.Url.Action(nameof(GetStream));
return Content(
$"<script>history.pushState({{}},'downloading','{url}');history.go()</script>",
"text/html"
);
}
The key is spelling the magic from JavaScript so that you can change the browser behavior as you like.
Is possible to have something in the view like "waiting..." and return FileStreamResult
Again, you can do that by a HTML Content. Lets' say you want to display a waiting... message and trigger the downloading in 1 second:
public IActionResult Redirect1()
{
var url = this.Url.Action(nameof(GetStream));
return Content($"<div id='msg'>waiting...</div><script>history.pushState({{}},'downloading','{url}'); setTimeout(function(){{document.getElementById('msg').textContent='';history.go();}}, 1000);</script>","text/html");
}
What if your javascript goes more complicated? Simply create a cshtml View and put the content within a View file.
Thanks,
Maybe I have to describe more my problem.
I Have an action which return a FileFileStreamResult and is authorized using OpenIdConnect and IdentityServer4 Authority. This action is called from angular web application in a new tab. If the browser know the mime type will display the content of stream if not will show the save dialog and the tab is closed by the browser. This work perfect unless first time when the authentication is done the tab is not closed automatically by the browser becouse the url of the browser is not updated.
The URLs sequence in dev tools are:
https://taxmart-portal-dev-v2.taxmaxng.eu/api/active-data-marts/21933e46-c4e5-44cc-b49b-a6bf3636ba44/objects/11/content
https://taxmart-identity-dev-v2.taxmaxng.eu/connect/authorize?client_id=...
https://taxmart-portal-dev-v2.taxmaxng.eu/signin-oidc
https://taxmart-portal-dev-v2.taxmaxng.eu/api/active-data-marts/21933e46-c4e5-44cc-b49b-a6bf3636ba44/objects/11/content
but the browser display the URL from point 2.
Can somebody know how to do to be display the URL from point 4.
Ioan Toader
Thanks

Put request is not working using postman to web api 2 c#

I have a method in Api as follows
[HttpPut]
[Route("UpdateTeacher")]
public IHttpActionResult UpdateTeacher(BusinessLayerTeacher Obj)
{
try
{
BusinessLayerTeacher obj = new BusinessLayerTeacher ();
string status = BusinessLayerObject.UpdateTeacher(TeacherObj);
return Ok(status);
}
catch
{
return NotFound();
}
}
Now in post man i am sending the put request to update the teacher object.
It is not triggering this updateTeacher() method.
You are instantiating a new BusinessLayerTeacher object inside the method, which looks suspect when you are already passing in BusinessLayerTeacher as a parameter.
Maybe the route mapping isn't working because you're not passing in the right data in the request body.
Maybe you should be using TeacherObj as the parameter type?
Have a review and give that a try, good luck :-)

Web Api c# Get Query Sring from url - Asp.net

I got a url where it's method is post but I want to pass some paramets by get method, I am using c# MVC asp.net
as the follow link
http://site/api/user/seach/?value=here&value2=here2
I am trying to get this using
public IHttpActionResult Get()
{
var queryString = this.Request.GetQueryNameValuePairs();
}
And I already tried to use
string p = Request.QueryString["value"];
But it seems to work only in controller base exteds
Is there some way to get this value get in a post method ?
Sounds like you'd like to use the POST verb but send data through querystring, in that case you can:
public IHttpActionResult Post([FromUri]string value)
{
// do whatever you need to do here
}

Testing the web api that accepts JSON as input

I am creating a web api that needs to accept JSON as input that is sent by the called client side application. Below is the Code
public class SetNameController : ApiController
{
[HttpPost]
public async Task<IHttpActionResult> Get([FromBody] CodeDTO.RootObject bCode)
{
string Bar_Code = bCode.Barcode.ToString();
if (Bar_Code == "" || Bar_Code == null)
{
....
return OK(response)
}
Here I am not sure How the client application call this Web API, the URL can be just like http://localhost:41594/api/SetName can it accept the JSON? Also can I test this using PostMan or Fiddler?
Specify the following:
Method: POST
Header: Content Type
Then, provide the payload json data in Body as raw:
Also, change the name of the action Get which might cause confusion. If you still cannot hit your api, you can use route urls by decorating the action with [Route('yourURL')] attribute and change that accordingly in postman.

Sending an array of json objects to web api, how to format the url?

I have written asp.net web-api project with following api-s:
Controller Method: Uri:
GetAllItems: /api/items (works)
GetItem(int id) /api/items/id (works)
and
GetListOfItem(IEnumerable<Items> items) /api/items/List of items (doesn't work)
The function is similar to this (don't care about logic)
public IHttpActionResult GetByArray(IEnumerable<Book> bks)
{
var returnItems = items.Select(it => it).Where(it => it.Price < bks.ElementAt(0).Price || it.Price < bks.ElementAt(1).Price);
if (returnItems == null)
return NotFound();
else
{
return Ok(returnItems);
}
}
I am using postman to send requests and following requests works correct
http://localhost:50336/api/items/
http://localhost:50336/api/items/100
but not
http://localhost:50336/api/items/[{"Owner":"MySelf","Name":"C","Price":151},{"Owner":"Another","Name":"C++","Price":151}]
How should i format the last request where i have a list of items in json format in order to get it works?
You want to decorate your method with a HttpPostAttribute and FromBodyAttribute:
[HttpPost]
public IHttpActionResult GetByArray([FromBody]IEnumerable<Book> bks)
{
}
Then send the json as post body.
Your Postman shoud look like this:
Specifically for
GetListOfItem(IEnumerable<Items> items)
[FromBody] is definitely best option.
In case you are using primitive types you can do following:
GetListOfItem([FromUri] int[] itemIds)
And send request as:
/GetListOfItem?itemIds=1&itemIds=2&itemIds=3

Categories