How to call WebAPI from a MVC Controller in a different project? - c#

I have to create a Web API for my existing MVC project and make API Controllers calling the Service Layer and Models, which is contained in separate projects but in the same Solution, then create and map to DTOs.
Layout of my Projects Solution in VS
( ignore the BookService.cs. I was just trying to do a WebAPI tutorial and I put it in the same solution temporarily).
I have been reading up on WebAPI and how it functions for the past 2 days, but I am not being able to fully grasp an understanding on how to create a API Controllers for my MVC project without referencing it? I also have to make Views at the end, in my main project calling the uri, but I am very confused at this point.
It would help me out a lot if someone can please clarify how I am to tackle this or point me to a tutorial or some sort of source to learn the process of working with Web API. Thank you.

The Web Api project will be a separate "website", that you will need to host individually. Your MVC project will make requests to the Web Api using HttpClient.
Since the Web Api will be separate, you won't be able to utilize helpers like Url.RouteUrl, etc. to get URLs for the Web Api actions. You will also just need to know the full URI to the Web Api, including it's domain. There will be no way to programmatically ascertain this information, so I would recommend making use of Application Settings to avoid hardcoding in your MVC project.
Right-click on your MVC project in the Solution Explorer and choose Properties. Then click over to the Settings tab. Here, you can add strongly-typed settings that your MVC application can utilize. Importantly, these settings are still persisted in the Web.config, so you can change them using config transforms. Your Web Api will likely have different URLs depending on whether you're in development vs. production, for example, so that will make it very easy to ensure that you're hitting the right thing in the right environment.
You can add a setting like WebApiUri, and give it a type of System.Uri. Then, set it to the string value of where your Web Api is hosted in development, i.e. http://localhost:12345. It's important that the setting be specific to your development environment, as config transforms are not applied in development. For staging, production, etc. you'll change this setting appropriately in the applicable config transform, and it will be updated to the right value for the right environment when you publish.
Then, when you need to work with it, you'll just do something like:
var client = new HttpClient();
client.BaseAddress = Properties.Settings.Default.WebApiUri;
Then, just make requests as normal through the client. For more information on working with HttpClient, see the documentation.

Related

c# web api 2 - any way to wrap all routes for "site is down"?

The high level problem I'm trying to solve:
Given our design of
- c# web api to modify entities and retrieve view models
- react SPA frontend
I want to be able to conditionally turn the c# web api "off" and tell the SPA the "site is down for maintenance". The purpose for this is to prevent odd errors in the client in the case someone is using the site during the transition.
The initial idea I had to solve this was to wrap each call in a web.config check to see if the site is down, and if so, return a hard-coded error response which the frontend knows what to do with. However the cleanest approach I can think of is to inject a service into each web api controller and invoke it at the beginning of each route. I was instead hoping for a way to avoid this boilerplate.
In node I would decorate all the routes in a wrapper function that does this. C# is a little more foreign to me.
If you host your WebAPI as its own ASP.NET site then you can place an app_offline.htm file in the IIS root, and it will automatically go into maintenance mode.
ASP.NET will immediately server 503's and the page contents for all new requests, while allowing existing requests to complete.

Discovering and sharing controllers between aspnet mvc and webapi in aspnet core 2

We have a Spa client, which runs inside of a aspnet core web app (aspnet core spa template). The Api project is where the business logic and data access reside and can be called by other clients such as native, other Spas, etc… The web app is protected by a cookie middlewre with external providers to sign-in, while the web api is protected by bearer tokens.
We have noticed that if we add a reference in the Web app to the Api project, the Controllers defined in the Api project are available in the web app. So just by adding a reference, we can make a local ajax call to /api/data from Spa residing in the Web app. There is nothing extra we’re doing here, no custom controller resolvers, assembly loading, etc…
Is that how things now work in aspnet core mvc? Are we correct to assume that the web app will just discover the controllers, but ignore any program.cs/startup.cs from the Api project when it configures the host?
No. This is not how it works. First, the delineation between "MVC" and "Web Api" is more pedantic than anything at this point. In Core, they are the same. If your project is only going to be an API, you can leave a few things out of the standard MVC services, but it still use "MVC". As a result, calling something an "API" or "MVC" project doesn't really mean anything. You can mix and match to whatever degree you need.
If you have two separate projects, then you should follow that and keep everything separate. One should not have a dependency on the other. You can always "call" your API from your MVC project, just as with any other HTTP-hosted service. However, you won't be able to take advantage of things like UrlHelper to generate URLs for your API action from your MVC project. You would just need to "know" these.
If you want the two projects to be tightly integrated, then they shouldn't be two projects. Just have one website project, and move all your API and MVC stuff into it. Then, you'll truly have everything shared.

Calling Web API vs adding reference to underlying dlls

This is more of an Architecture question, and I want to know all the possible pros and cons of the approach.
In my org, we have an ASP.NET Application, a Web API Project, and underlying DLLs which calls App Tier which is physically on different server. In ASP.NET Application, for a particular piece, we are having a SPA.
For most of the things (I would say 99 % of the things) , we are making ajax call from our SPA to Web-API to access underlying functionality.
SPA and WebAPI are both deployed and hosted on same Web Server as different applications and WebAPI has reference to underlying DLLs so these DLLs are deployed with WebAPI.
For one of the functionality some server side processing needs to be done on ASPX page's code behind.
I am suggesting to my team to do keep calling from SPA to WebAPI using http client and maintain loose coupling that we have between Application and the dlls via WebAPI, but many (I would say everybody else in my team) is in favor of adding direct reference of DLLs to ASP.NET application, so now these DLLs will be deployed with ASP.NET Application alongside.
Is my suggestion not so good provided ease of implementation that we would be getting with adding direct reference for DLLs in ASP.NET Application? Let me know if I am not explanatory enough.
I would be in favor of using a DLL directly if you could get rid of the Web API altogether. Since it does not sound like you are planning to do that, I think your suggestion to continue using the Web API from your application:
Using the DLL from two places creates a deployment liability: every time you update it, both places must be updated
Changing the code in DLL requires testing the change from two paths - A-D and A-W-D
Fixing a bug in the way that you call your DLL would likely have to go to both A and W, instead of going to W alone.
Of course, the path A-W helps you exercise your Web API component, too, helping you detect bugs early.

Is there such a thing as an entirely empty website project?

I'm looking at working my long-standing API to run on IIS rather than in a desktop app as it is now. Everything on the API is working so I'd rather not change too much if I don't have to. I know about the new Web API template in ASP.NET MVC 4 and I've worked with it, but I found that it didn't give me the control over everything that this particular project needs.
So my question is, is there any way to build an application for IIS that has something like an entry-point where I can just get a web request then use entirely my own code from there? Or do I have to build something that uses the Web API?
Yes, you'll want an ASP.NET handler.
How To Create an ASP.NET HTTP Handler by Using Visual C# .NET
http://support.microsoft.com/kb/308001
You'll need to handle parsing the request and serializing the result yourself. It's probably much better to create a web-api facade in front of your services than trying to do it manually.

Can an asp.net mvc application also have a web service?

I have an asp.net mvc application and now I need to add a web service to go along with it. What is the best solution for this? Just create a new web service project and add it to my solution then deploy it to the same web server using a different url? I would like it to be a part of the mvc application only because I have all my database code in there.
Any suggestions would be appreciated. Thanks.
There's no reason not to add a web service project.
You state that all your database code is in your MVC project. I strongly recommend you remove it from there into a separate class library project. This third project would be used both by the web service and by the MVC application.
I also strongly recommend that you not use ASMX web services for any new development.
Use WCF only, unless you have no choice at all. There's a misconception that WCF services don't do SOAP - they do, and WCF has replaced ASMX.
Web service could mean a soap based web service or a RESTful web service. I can't think of any reason why you would not be able to simply add an asmx file to your project and be in business. That is the soap based route. If you want to be really cool though you can simple return xml from a controller action and implement a RESTful solution right over the MVC framework.
If you want to use a regular ASP.NET asmx web service, it's certainly possible. Here's an example from Scott Hanselman that does just what you are asking about and it throws in some other ASP.NET technologies for good measure.
All you have to do is File -> New Item -> Web Service and it should work like a regular ASP.NET application in your Mvc project.
i think there's a couple of things here.
you can indeed add a web service to an MVC application. you may even consider identifying the web service(s) as a script service to make REST like operations easier to perform via javascript. this may not be necessary due to your circumstances.
i think there is a stronger question as to the underlying architecture. If you are placing the web service withing your mvc application, because, your database code is already there...should it be? it might be a good time to abstract your data layer out a little. However, if you're dealing with a relatively small project and don't need the flexibilty, then certainly, add a web service right in. i guess what it really boils down to is addressing the true needs of your application.
MVC is built on the asp.net framework. You should be able to include a web service within the same project. I haven't done it but I know that you can combine asp.net forms applications with MVC applications in the same project. The same should go for web services.
Unless your application is very small I would recommend you create different projects for each logical part of the application. A good staring point is having a project for each of these:
Domain objects
Data access
Web Services
UI (your ASP.NET MVC app)
This provides a clean separation corresponding to your architecture and supports reuse.

Categories

Resources