I am trying to learn Web API and MVC. I, initially created a basic MVC project. Now, in the controllers folder ,I added a WebAPI controller.
In the WebAPI controller, I added the below code
public class SampleController : ApiController
{
[HttpPost]
public IHttpActionResult SampleData()
{
var userID = User.Identity.GetUserId();
return Ok();
}
}
The Method User.Identity.GetUserId() works fine in MVC.
I searched about on SO and found the following thread
User.Identity.GetUserId() method not working in a Web Api 2 Controller
This was not that helpful for me, as in my case I have added the API controller as part of the MVC project itself in the controllers folder.I have not created a separate project for WebAPI.
The above mentioned thread talks about the accesstoken already being present in code , whereas in my case, I dont see that code anywhere, as I just added only a single web api controller.
I am using POSTMAN for calling the API.
I have also looked at the following link
https://learn.microsoft.com/en-us/aspnet/web-api/overview/security/individual-accounts-in-web-api
In this case too, a separate WebAPI project is being talked about and not a single controller.
If I am mistaken somewhere, kindly guide me on the same.
Related
I'm trying to deploy my ASP.NET Core MVC Web App with Web API, i.e. I have both MVC and API controllers in the same folder.
It works fine on localhost but on IIS when I create a Virtual Directory, the path gets added to the domain.
I can find it using window.location.pathname
I can append the 'api/Get' and it works like (questions is my virtual directory)
http://example.com/questions/api/Question/GetAll
But when I navigate to other pages then then controller name also gets appended and then it causes issues.
e.g. if I navigate to the 'Question' page (QuestionController), the URL becomes
http://example.com/questions/newquestion/api/Question/Create
instead of
http://example.com/questions/api/Question/Create
How can I fix it?
Here is my Asp.Net core api.
[ApiController]
public class ScheduleController : ControllerBase
{
[HttpGet]
public List<PathologistSchedule> GetPathologistScheduleByDate(DateTime taskDate)
{
return pathologistRepository.GetPathologistScheduleByDate(taskDate).ToList();
}
}
I call this api from PathologistScheduleController's view using jquery.
Here's the error I get:
GET http://localhost:51434/PathologistSchedule/api/Schedule/?sort=&group=&filter=&taskDate=2020-11-13T21%3A16%3A47.507Z 404 (Not Found)
TIA.
A
If you have API and MVC projects in one solution you have to config your solution to run multiple projects.
You can use route attribute like this for each of your APIs
[Route("~/api/Question/GetAll")]
will give you Url http://example.com/api/Question/GetAll.
Or
[Route("~/api/Question/Create")]
will give Url http://example.com/api/Question/Create.
And it will not depend on the controller name or folder.
UPDATE because of the question update:
Use this code please:
public class ScheduleController : ControllerBase
{
[Route("~/api/Schedule/GetPathologistScheduleByDate/{taskDate?}")]
public List<PathologistSchedule> GetPathologistScheduleByDate(DateTime taskDate)
{
return pathologistRepository.GetPathologistScheduleByDate(taskDate).ToList();
}
}
for testing try this route in your browser:
http://localhost:51434/api/Schedule/GetPathologistScheduleByDate/2020-11-13T21%3A16%3A47.507Z
But basically for APIs you don't need to use any controller or action name. You can use any names you like, for example:
[Route("~/api/Pathologist/GetSchedule/{taskDate?}")]
or
[Route("~/api/GetPathologistSchedule/{taskDate?}")]
or even
[Route("~/api/{taskDate?}")]
The route just should be unique.
I added a variable in the 'appsettings.json' and 'appsettings.Development.json' called baseURL and had 'appsettings.json' set to '/VirtualDirectoryName/' and kept the one in 'appsettings.Development.json' as '/'.
Appended this variable when calling APIs.
I'm new to asp.net mvc and web api. I'm reading a book which says:
ASP.NET MVC uses: System.Web.HttpRequest
and Web API Equivalent is System.Net.Http.HttpRequestMessage
and below is a picture that describes the request and result flow of web api
So my question is, how does hosting environment(which will typically be IIS) know that it should create a HttpRequestMessage object to represent the request from the client? I mean if the application is a MVC application, IIS should create a HttpRequest object instead of HttpRequestMessage, so how does IIS know which one to create?
As you can see from the picture you posted, the HttpRequestMessage exists only inside the "hosting" environment, web browser client does not know anything about that.
In the "hosting" world, IIS app pool is running the code you have built and deployed which knows very well wich framewok you are using as your code also contains the using assemblies you listed, System.Web... or System.Net...
Consider that even if you have shown separation between hosting, Controller and Action, all of that is running in same App Pool in IIS which, again, runs your code so knows what it is about as your IL assemblies were built from your specific source code.
I am not sure if I understand your question but this might be what you're looking for:
I mean if the application is a MVC application, IIS should create a
HttpRequest object instead of HttpRequestMessage, so how does IIS know
which one to create?
You must remember how you differentiate between a normal MVC Controller and a Web API Controller...
WebAPI Controllers enforces this annotation [ApiController] and must inherits from ControllerBase:
[ApiController]
public class PeopleController : ControllerBase {
//Your API methods here
}
A normal MVC Controller only inherits from Controller base class:
public class PeopleController : Controller {
//Your Action methods here...
}
Those already create configuration for your APP which becomes easier for you Hosting environment to know what is going and what to return when.
I hope you find this helpful.
I am following this tutorial on how to create a simple database web application with ASP.NET MVC. I am having a problem with the 2nd Create controller method in the home controller (in Listing 4). Specifically, the error - when the web app is built - is with the AddToMovieSet method that actually saves the entries to the database.
It is worth noting that I am using VS 2016, whereas the tutorial uses a much older version (2008); this might be the reason to the problem. But, nevertheless, what is the code for this Create controller method?
This is the code in the Create action method in the home controller:
public ActionResult Create(Movie movieToCreate)
{
if (!ModelState.IsValid)
return View();
_db.AddToMovieSet(movieToCreate);
_db.SaveChanges();
return RedirectToAction("Index");
}
Make sure you have proper view created for this action method. Else create view or return view explicitly with name.
I'm trying to pass configuration values to bootstrap a single page AngularJs app hosted within an MVC app that utilises WebApi (see below from the Razor view, this is achieved by inheriting a BasePage and dependency injecting a Serializer/FinancialYears service).
<script>
var angularInitConfig = #Html.Raw(Serializier.Serialize(new {
financialYears = FinancialYearsService.GetFinancialYears()
}));
</script>
This works perfectly, however I would really like to be able to extend it to include the routes from my WebApi app to avoid having to configure the endpoints in both the WebApi app AND the AngularJs app individually.
Having poked around in the RouteTable.Routes class I can see that the information I require is available and accessible from within the view, however I've been unable to extract it.
So what I'd ideally like to do is generate a collection of objects as defined below from the RouteTable.Routes class, serialize them and spit them out in the bootstrap config for the AngularJS app to consume.
new {
name = "SomeService",
route = "api/{financialYearId}/someservice",
method = "POST"
}
Does anybody have an idea how to extract this information from RoutesTable.Routes? Is there an easier way to generate the data required?
NB. All WebApi routes are configured explicitly using the Routes attribute as such:
[HttpGet]
[Route("api/{financialYearId}/someservice")]
If you create default template asp.net Mvc or WebAPi using Visual Studio, you will get Help in Folder > Areas\HelpPage...and if you access your application in : Http://yourportapplication/api/Help if project webapi...
then, you can see the code how to get information...just for started what you looking for,....
I'm implementing a REST Web API. I'm using the examples from Adam Freeman's Pro ASP.NET MVC5 as a starting point but adapting it into the Web API way of doing it.
The below is my code:
public class AdminController : ApiController
{
private IUserRepository _repository;
public AdminController(IUserRepository repository)
{
_repository = repository;
}
public ActionResult Index()
{
return View(_repository.Users);
}
}
In the book, AdminController implemented Controller not ApiController, but if I do that then I get errors about there being no parameterless constructor. I need the constructor to take parameters so that I can inject the dependencies. So that's why I changed to ApiController but now it won't recognise View.
What do I need to use instead of View for an ApiController?
I did find this question but the answer was basically "you don't need to use an ApiController here, just use Controller" so that didn't help me.
You are having two different problems. Let's solve them separately.
1. Do I need to use ApiController or Controller?:
Someone already answered this here: Difference between ApiController and Controller in ASP.NET MVC.
The first major difference you will notice is that actions on Web API
controllers do not return views, they return data.
ApiControllers are specialized in returning data. For example, they
take care of transparently serializing the data into the format
requested by the client.
So, if you want to return a View you need to use the simple ol' Controller. The WebApi "way" is like a webservice where you exchange data with another service (returning JSON or XML to that service, not a View). So whenever you want to return a webpage (View) for a user you don't use the Web API.
In other words, the Web API is about returning data to another service (to return a JSON or XML), not to a user.
2. But if I use Controller then I get "parameterless constructor" errors.
Okay, now we've got to your real problem. Don't try to reinvent the wheel and fight with ASP.NET about doing dependency injection! A tool already exists to resolve dependency injection and sort out the "parameterless constructor" error: Ninject.
If you're already using Ninject and still getting that error, you're doing something wrong with Ninject. Try to repeat the installation and configuration steps, and see some tutorials or questions about parameterless error with Ninject use
An API controller is a controller which provides a RESTful response. You cannot return a view from it. Instead of doing that, consider returning a response (values) which forces the client that asks for an action to redirect to another controller (passing arguments if necessary) to return a view.
Your case does not look like you need an API; in this case just try this (change what you inherit):
public class AdminController : Controller
{
private IUserRepository _repository;
public AdminController(IUserRepository repository)
{
_repository = repository;
}
public ActionResult Index()
{
return View(_repository.Users);
}
}
I will try to explain what an API should do anyway. A web API should return just information. An HTTP response about what the action should do.
For example, to create a new customer, an API should have a method (decorated with POST) to get information from a client application (could be anything: web, windows, mobile, windows service, etc.). This information should be processed by the API (or other layers in a possible architecture) and return an HTTP status code, for example 200 - OK if it was fine or 400 - Bad Request if an error happened. So, when I said you should consider returning information, you could just return a DTO object to provide a result.
Both types of project use MVC principles, but they are used in a different context. Take a look at these articles:
Web Api 2.0 Tutorial
Difference between MVC and WEB API
Also take a look at the ASP.NET website about how they work:
ASP.NET WEB API
ASP.NET MVC
Use Controller to render your normal views. ApiController action only return data that is serialized and sent to the client.
But still you want to render view from APIcontroller, then there may be a another way, click on below link for reference :
https://aspguy.wordpress.com/2013/09/10/web-api-and-returning-a-razor-view/