Parsing Attribute Routed URL in ASP.Net Web API - c#

I'm trying to get the parameters of specific attribute routed URL on ActionFilterAttribute. For instance I have an action like below:
[Route("/v1/test/{userId}/{udid}")]
public object GetNewObject(int userId, string udid)
And in action filter attribute the absolute url is coming something like "http://test.example.com/v1/test/1/123-asda-231-asd". However I want to parse these parameters as userId=1 and udid=... within a collection.
Is it possible?

Anyway I found the answer,
Within RouteData of ControllerContext we may able to retrieve the specified value.
actionContext.ControllerContext.RouteData.Values["udid"]

[Route("...")] is possible only in MVC 5.
I think you want to do something like this
[RoutePrefix("api/users")]
public class UsersController : ApiController
{
// GET api/users
[Route("")]
public IEnumerable<User> Get() { ... }
// GET api/user/5
[Route("{id:int}")]
public Book Get(int id) { ... }
// POST api/users
[Route("")]
public HttpResponseMessage Post(User book) { ... }
}
where each User contains your properties
public class User
{
int UserId{get;set;}
string Udid{get; set;}
}

Related

Handling multiple IDs in Route

As far as I can understand, the conventional routing in .NET Core MVC is [controller]/[action]/{id?}
However, I have the following POST request I'm trying to catch which looks like this:
myDomain/MyController/MyAction/userID/anotherID/myInfo
I have tried the following, but it doesn't seem to be working:
public class MyController : Controller
{
[HTTPPost]
[Route("MyAction/{userID:minlength(2)}/{anotherID:int}/myInfo")]
public IActionResult MyAction([FromRoute] string userID, [FromRoute] int anotherID, [FromBody] string stuffIWant)
{
return Ok();
}
}
Obviously I'm not handling the routing correctly, but I'm not sure how I would get userID and anotherID from that route. I've published this action to my site, and tried to do a test post with the same URL, but didn't get a response.
Change to:
public class MyController : Controller
{
[HTTPPost]
[Route("MyAction/{userID:minlength(2)}/{anotherID:int}/myInfo")]
public IActionResult MyAction(string userID, int anotherID, [FromBody] string stuffIWant)
{
return Ok();
}
}

Web API routing with DTO object - C#

I have two projects, one is SPA and the other one is ASP.NET aspx project.
Normally those two projects communicate with each other via web API.
There is a running method like this (from SPA to ASP.NET)
[HttpPost]
[Route("DenyInvoice/{approvalId:long}")]
public IHttpActionResult DenyInvoice(long approvalId)
{
string exMsg = "";
if (DenyInvoice(approvalId, this.UserId, this.Email, out exMsg))
return Ok();
return BadRequest(exMsg);
}
This method works as I wanted, but I want to write a method that accepts a DTO variable like;
[HttpPost]
[Route("InvoiceDetailUpdate/{invoices : invoiceDetailDtoModel}")]
public IHttpActionResult InvoiceDetailUpdate(invoices : invoiceDetailDtoModel)
{
....
}
Is it possible? How should I do this?
Can you help?
Thank you..
Use [FromBody] to pass in the POST parameter. See https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-web-api#implement-the-other-crud-operations for more details.
[HttpPost]
[Route("InvoiceDetailUpdate")]
public IHttpActionResult InvoiceDetailUpdate([FromBody]InvoiceDetailDtoModel invoices)
{
....
}
You want to retrieve parameter via post so there is no required for get parameter routing.
[HttpPost]
[Route("InvoiceDetailUpdate")]
public IHttpActionResult InvoiceDetailUpdate(InvoiceDetailDtoModel invoices)
{
....
}
Also, be careful with the name convention of a class.
In the following code, you can use like this :
public class BooksController : ApiController
{
[Route("api/books")]
public IEnumerable<Book> GetBooks() { ... }
[Route("api/books/{id:int}")]
public Book GetBook(int id) { ... }
[Route("api/books")]
[HttpPost]
public HttpResponseMessage CreateBook(Book book) { ... }
}
Now , you can see this link attribute-routing-in-web-api-2
and change your code to above figure
[Route("api/YourController/InvoiceDetails")]
public IHttpActionResult InvoiceDetailUpdate(InvoiceDetails invoiceDetailsDto)

ASP.Net Web API: How to achieve url parameter and attribute based versioning with same Controller methods

Is it possible to achieve url parameter and attribute based versioning with same Controller methods. To explain that, suppose I have one controller like,
[RoutePrefix("api/{apiVersion:apiVersionConstraint(v2)}/values")]
public class ValuesController : ApiController
{
// GET api/v2/values
[Route("")]
public IEnumerable<string> Get()
{
return new string[] { "v2-value1", "v2-value2" };
}
// GET api/v2/values/5
[Route("{id}")]
public string Get(int id)
{
return "v2-value-" + id;
}
}
Now, I want to access the API endpoint by both of the following URL's:
http://hostname/context/api/v1/values
http://hostname/context/api/values?v=1
Is it possible?
N.B. I'm using the example at WebApiNamespaceVersion in GitHub

How to put multiple GET methods in Web API2 controller?

I am doing a Web API 2 application and I have controller named NCT_ProcessSettings and already I have two GET methods as below.
1. public IEnumerable<Process_Settings> Get()
2. public HttpResponseMessage Get(int id)
Now I want to have third one as below (Same as first one but inside I will write different logic).
3. public IEnumerable<Process_Settings> Get() //Compiler will confuse which to pick?
I tried as below.
[HttpGet]
[Route("GetGlobalSettings")]
public IEnumerable<NCT_Process_Settings> GetGlobalSettings()
{
return entityObject.NCT_Process_Settings.Where(c => c.project_id == 0).ToList();
}
Below is my angularcode to call api.
var url = '/api/NCT_ProcessSettings/GetGlobalSettings';
May I have some idea how to fix this? Any help would be appreciated?
Enable attribute routing in WebApiConfig.cs before convention-based routes.
config.MapHttpAttributeRoutes();
Next update controller to use routing attributes. (note the route prefix)
[RoutePrefix("api/NCT_ProcessSettings")]
public class NCT_ProcessSettingsController : ApiController {
//GET api/NCT_ProcessSettings
[HttpGet]
[Route("")]
public IEnumerable<Process_Settings> Get() { ... }
//GET api/NCT_ProcessSettings/5
[HttpGet]
[Route("{id:int}")]
public HttpResponseMessage Get(int id) { ... }
//GET api/NCT_ProcessSettings/GetGlobalSettings
[HttpGet]
[Route("GetGlobalSettings")]
public IEnumerable<NCT_Process_Settings> GetGlobalSettings() { ... }
}
Read up more documentation here Attribute Routing in ASP.NET Web API 2
Used Action Name attribute
[ActionName("Get")]
public IEnumerable<Process_Settings> Get1()//used any name here
{
}

How do I write REST service to support multiple Get Endpoints in .net MVC Web API?

So I am familiar with how to write the default Get, Post, Put, Delete
//GET api/customer
public string Get(){}
//GET api/customer/id
public string Get(int id){}
//POST api/customer
public void Post([FromBody]string value){}
//PUT api/customer/id
public void Put(int id, [FromBody]string value){}
//DELETE api/customer/id
public void Delete(int id){}
But how would I write add another Get endpoint w/o having to create a whole new controller? I want to grab the customer's metadata? do I need to make any changes to the routeConfig? if so how would I do that? and then how would I use the new route in javascript?
//GET api/customer/GetMetaData
public string GetMetaData(){
}
You use the Attribute Route. This attribute was added in WebApi 20 and you can use it at Method level to define new route or more routes and the way you use it is like [Route("Url/route1/route1")]:
Using one of your examples above it will be like:
//GET api/customer/GetMetaData
[Route("api/customer/GetMetaData")]
public string Get2(){
//your code goes here
}
If you will be declaring several Routes in your class then you can use RoutePrefix attribute like [RoutePrefix("url")] at class level. This will set a new base URL for all methods your in Controller class.
For example:
[RoutePrefix("api2/some")]
public class SomeController : ApiController
{
// GET api2/some
[Route("")]
public IEnumerable<Some> Get() { ... }
// GET api2/some/5
[Route("{id:int}")]
public Some Get(int id) { ... }
}
Note: In the example above I showed one example where Route allowed us to set type constraints as well.

Categories