I am just trying to figure out what would be the easiest and quickest way to get particular value from WebApi controller.
my web API controller
public IEnumerable<string> Get()
{
return new string[] { fullname,lastname, email};
}
when I try to consume this web API in the angular controller by using the below method
this._httpService.get('/api/user').subscribe(values => {
this.details= values.json() as string[];
});
it returns all the values (fullname,lastname, email). but what I am trying to get here is lastname.
something like this.details.lastname
For clarity, if you are using Angular (not AngularJS), then the code is called a component not a controller.
Which version of Angular are you using? If it is > 4.3, then you don't need the .json() anymore. The mapping is handled for you automatically.
To answer your question ... the "quickest" way would be something like this (assuming Angular v6):
this.http.get<>('/api/user').subscribe(
details => this.lastName = details.lastName
);
Assuming that details is one item, not an array.
But this is definitely not the "best" way.
The best way would be to define an interface for your details and then build a proper client-side service to encapsulate your data access.
Related
I have an application developed in ASP.NET Core MVC with a set of controllers for normal view responses and Web API.
I am trying to figure a correct way to wrap all Web API responses with a consistent class.
My first question is what would be a correct approach to wrap the responses coming from Web API controllers. Since I have two controller types, I would need to distinguish between them as the responses should only be wrapped for API controller, and not view controllers.
As I understand there are two choices a middleware or an action filter.
At first I thought the middleware would be the best choice, but then I realized that I would still need to figure out what kind of request is being processed which would add more potential headache with maintenance?
Then I looked at an action filter and it seems that it would be a better choice to plugin the wrapping handling.
For example an action filter can be added to a base controller just for Web API and not controllers handling the views.
So the question is whether the action filters are best approach to achieve this?
I would recommend you to look at result filters for this. Result filters run after a controller action has produced a result, and it allows you to look at that result and then perform some action.
For example, when you return View in a controller action, then what gets returned is a ViewResult which makes it easy to identify results that would cause a Razor view to be rendered.
Within an API controller, you would usually return a ActionResult<T>, some model object directly, or an ObjectResult. The former two will be automatically converted into an ObjectResult as the action gets executed. So you can just look for ObjectResults and then change the result to have some wrapper object instead. This would look something like this:
public class WrapApiResponseResultFilter : IResultFilter
{
public void OnResultExecuting(ResultExecutingContext context)
{
var result = context.Result;
if (result is ObjectResult)
{
// wrap the inner object
var newValue = new WrapperObject(result.Value);
// replace the result
context.Result = new ObjectResult(newValue)
{
// copy the status code
StatusCode = result.StatusCode,
};
}
}
public void OnResultExecuted(ResultExecutedContext context)
{ }
}
I a newbie to webapi and have created a web api project. Different controller method here needs image as parameter. I am using an external 3rd party api to check if the image uploaded by the users is not any profane image. So instead of checking it at actionMethod level ,i thought it might be a good idea to check using a filter that way it will save me time of checking it individually. But i haven't got a clue as to how to start writing the code for this.
public class ImageFilter : FilterAttribute,IFilter
{
public void OnActionExecuting(HttpActionContext httpActionContex)
{
if(!httpActionContex.ActionDescriptor.) // ???? what should come
}
}
please guide me. Don't need the exact code just the correct direction and guidance .. thanks
A FilterAttribute is, as its name implies, an attribute that can be set globally on the WebAPI pipeline, or individually on a specific controller method. You can simply slap the [ImageFilter] attribute on your specific controller method, and the WebAPI pipeline will execute the filter before executing the action method - giving you a chance to filter what requests make it to the method.
For the actual implementation of your custom logic, you can access the HttpContext.Current.Request in your OnActionExecuting method, allowing you to access the incoming HTTP request. You can then read the data from it, pass it to your 3rd party API, and if it doesn't pass the filter, you can access the Response and end it before it even reaches the controller:
var response = HttpContext.Current.Response;
response.StatusCode = (int)HttpStatusCode.BadRequest; // or whatever
response.End();
I've got an ASP.NET Web API project that I'm working on. I've got an APIController called SpellbookController that has basic CRUD operations to an EntityFramework repository.
However, when I try to add a method that takes a parameter that's not an id, I can't seem to get it to route correctly.
Here's what it looks like:
// GET: api/Spellbooks/user#email.com
[ResponseType(typeof(List<Spellbook>))]
[Route("api/Spellbooks/{username}")]
public IHttpActionResult GetSpellbook(string username)
{
List<Spellbook> spellbooks = db.Spellbooks.Where(x=>x.Username == username).ToList();
if (spellbooks == null)
{
return NotFound();
}
return Ok(spellbooks);
}
So I'm trying to hit http://localhost:xxxx/api/Spellbooks/emailaddress,
but I get a 404 every time.
It's definitely an APIController, and I have config.MapHttpAttributeRoutes(); turned on.
What am I missing?
Where is your username parameter?
Your call should looks like this-
http://localhost:xxxx/api/Spellbooks/emailaddress/David
Update
Try to declare the parameter as string {username:string}
Update 2
The problem is with your '.' as you can see in this link.
You can send the email without the point in the parameter and then replace ite back to you regular mode or you can use all the good advice that the link provide.
If you step through it, do you get a value when looking at username? Or is it always null?
If your route is not working, a simple way to debug the route is to make a request to http://localhost:xxxx/api/Spellbooks/?emailaddress=thisemailaddress and see if you can get a response. In fact, from a REST standard, it can be argues that it's a cleaner route, since you will be returning a collection of elements, rather than a single object.
So I have two separate projects (one Web Api 2 and one MVC) like this diagram:
The MVC has controllers and a service layer. The services from the MVC app call to the web api controllers. For example:
await _service.GetGiftCards("/api/GiftCards/ViewAllByUser", email);
The Web Api controllers have their routes defined like so:
[RoutePrefix("api/giftcards")]
[Route("ViewAllByUser")]
public async Task<List<GiftCard>> GetGiftCardsForUser(string email){}
So to define the endpoint route in the MVC app I simply pass a string like "/api/GiftCards/ViewAllByUser" above.
My question is, is there a better way to sort of "strongly type" the endpoints of the Web Api routes that are defined so I can do something like?:
await _service.GetGiftCards(GiftCardController.ViewAllByUser, email);
I guess at a minimum I could always just store the endpoint strings in a static class like so, so they at least can all be updated in one place:
public static class ApiEndpoints(){
public string GetAllGiftCards = "api/GiftCards/ViewAllByUser";
}
but I'm looking to know if there are better ways or other suggestions. Thanks!
API routes shouldn't specify actions. You want your routes to be logical paths to a record or group of records. Example, in your case the route should look something like this:
GET
api/giftcards/{userID:int:min(1)}
You want to be able to walk up the url basically and get what you would expect. In the case of the example route you would get gift cards based on the user id. If you were to take off the user id page and just call api/giftcards you would expect to get all gift cards by all users. I'm using an ID here but you would do the same with email.
Pleas try with 'ActionName' Attribute on action like this :
[ActionName("SelectAll")]
public IEnumerable<Customer> Get()
{
...
}
calling this action name like:
$("#getdata").click(function () {
var options = {};
options.url = "/api/customer/SelectAll";
options.type = "GET";
...
...
$.ajax(options);
});
note: 'getdata' is id of control which click event will be fired and calling 'api method' and getdata from api
Here's a library that may be what you're looking for.
Although I like static strings so you don't always have to show future developers on your team how to use said library when updates are needed on the clients.
I currently have a MVC 3 Web Application with around 50 Views.
Is it somehow possible to provide some kind of API next to my Views so everything still works fine and dandy?
My kinda perfect world idea:
Server is running and every request gets to its view. The user can decide in his get request if he wants the raw data in lets say JSON. Additional to the raw data also the Structure/Names of the Viewmodel will be parsed so the Modelbinder can do his stuff.
or another approach might be to somehow deactivate my Views to have only the API available (again with raw data and structure).
Is this even possible (the modelbinder is kinda a big concern) and maybe even without much effort/trouble to do?
If you don't want to do everything all over again with WebAPI, you can implement some ActionFilterAttribute to change the ActionResult based on some querystring f.i.
Something like this:
public class ResultSwitcherAttribute: ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.HttpContext.Request["data"] != null && filterContext.HttpContext.Request["data"] == "json")
{
filterContext.Result = new JsonResult
{
Data = (filterContext.Result as ViewResult).Model,
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
}
}
}
Then, you'll register that either in application_start or per controller/action like this:
[ResultSwitcherAttribute]
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new TestModel()
{
Web = "http://www.mywebpage.com", Name = "Yngve"
});
}
}
When you now access your url with ?data=json you'll get a JSON-representation of the Model, instead of the view.
EDIT: Code sample updated
Consider adding an ASP.NET Web API to your app. It's extremely simple to implement, entailing little more than adding an API controller with methods corresponding to your REST actions. I don't know how one would go about adding this to an MVC 3 app, but I have a recipe for MVC 4 Internet Applications in this stackoverflow question. So, if you're fine with upgrading your project so that it is Web API capable, perhaps to MVC 4, I think it'd represent a good alternative.
To learn ASP.NET Web API, this tutorial is a good place to start.