I am new to Web API & MVC I have created new WEB API & MVC solution separately now i want to refer Web API action method in MVC so for that following code i written,
Web Api Project Side,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Data;
using System.Net.Http;
using System.Web.Http;
using AttributeRouting.Web.Mvc;
using RegisterStudent_WebAPI.Models;
namespace Register_Student_WebAPI.Controllers
{
public class RegisterStudentController : ApiController
{
[Route("api/student")]
[HttpGet]
public IEnumerable<Student> GetStudents()
{
RegisterStudent_API_DB objRegisterStudent = new RegisterStudent_API_DB();
List<Student> lstStudent = objRegisterStudent.GetStudent();
return lstStudent ;
}
} }
WEB.Config File from API,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
namespace RegisterStudent_WebAPI
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// Uncomment the following line of code to enable query support for actions with an IQueryable or IQueryable<T> return type.
// To avoid processing unexpected or malicious queries, use the validation settings on QueryableAttribute to validate incoming queries.
// For more information, visit http://go.microsoft.com/fwlink/?LinkId=279712.
//config.EnableQuerySupport();
// To disable tracing in your application, please comment out or remove the following line of code
// For more information, refer to: http://www.asp.net/web-api
config.EnableSystemDiagnosticsTracing();
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new System.Net.Http.Headers.MediaTypeHeaderValue("text/html"));
}
}
}
in MVC Project i have written following code in script tag(on load form) to refer WEB API Service,
$(document).ready(function () {
jQuery.support.cors = true;
$.ajax({
url: 'http://localhost:18715/api/student',
type: 'GET',
dataType: 'json',
success: function (data) {
alert('success');
},
error: function (x) {
alert(x.status);
}
});
});
If i add reference of Web API project to MVC project then it's working fine but one of my friend told services should not be referred like that, Please guide me how to refer/include the hosted/cross domain running web api project to my MVC Project?
What you have done is not bad(at least - it is not forbidden ;)) but by referencing WebAPI directly in a MVC project you are binding it to the one, specific application, what will prevent you from reusing API in other projects/services.
In my opinion, WebAPI project should be hosted as another application(it is up to you whether it should be a self-hosted OWIN application/webservice/simple API application), what gives you some benefits:
it is separated from your MVC application logic
it can be deployed separately
it can be used by other applications/services
it is easier to maintain
Think of WebAPI as a RESTful webservice, an API which can be used by your applications or third-party applications.
To be honest using WebAPI directly in MVC just to feed your views some data seems like a little waste. What you are doing can be done thanks to JsonResult actions in your MVC controller. It is not ideal, but prevents you from creating another API project.
Related
We are developing a new API version in our application, so that we basically have a
namespace Bla.V1.Controllers
[ApiController]
[ApiVersion("1")]
public partial class SampleController : ControllerBase {}
and a
namespace Bla.V2.Controllers
[ApiController]
[ApiVersion("2")]
public partial class SampleController : ControllerBase {}
We've also configured API versioning (AddApiVersioning), so that when somebody tries to access e.g. api/v3/sample/action, he will get a version not supported error response, provided by the API versioning middleware.
Now the V2 version is in development and we want to make it available only for the development stage. The controllers code will be deployed to production, we want however to disable the V2 version for production.
We would do it with a feature flag, but what should be done to hide the V2 controllers?
I was thinking:
Somehow do not register the V2 controllers. Didn't find a suitable option in AddControllers()
Set maximum version to V1 in the API versioning middleware. This works only for headers, doesn't block access to V2 controllers
I'm currently thinking about writing an authorization attribute that would deny access based on the feature flag status and apply it to V2 controllers. Is there a better and more elegant way to do this?
Well, in case somebody is interested at some point. Our controller code is autogenerated from a Swagger definition. So I added the following code to the generation template, which gets invoked in each controller method:
if (!this.IsV2Enabled())
{
var protocol = this.Request.IsHttps ? "https" : "http";
return this.BadRequest(new
{
error = new {
code = "UnsupportedApiVersion",
message = $"The HTTP resource that matches the request URI '{protocol}://{this.Request.Host}{this.Request.Path}' does not support the API version '1'."
}
});
}
I am trying to make n-tier application where web api is kept on a different class library. I made a TestController controller class in a different class library and my code goes like this
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
namespace PkrUni.SMS.Api
{
[ApiController]
[Produces("application/json")]
[Route("api/[controller]")]
public class TestController : ControllerBase
{
public IEnumerable<string> Get()
{
return new string[] { "Chris", "Hadfield" };
}
}
}
Now my question is how can I access this web api on my main project. I had already added a reference to that class library on main project but it doesn't working. My api is not working. 404 Page Not Found error shows up while trying to access the api.
This is my project structure.
What am I doing wrong please help me.
Try to install Microsoft.AspNetCore.Mvc package in the razor class library.
And in startup.cs use:
services.AddMvc().AddApplicationPart(Assembly.Load(new AssemblyName("PkrUni.SMS.Area.Api")));
Refer to here.
I test your scenario by creating a asp.net core2.2 MVC project and razor class library without any problem. Below is my structure:
I've been stumped on this one for a few days now. I am a beginner to CORS so navigating this has been very confusing.
What's going wrong: I created a asp.net web api which can successfully send POST requests to my SQL database. I have used POSTMAN to send the data successfully. Once I enable CORS I can no longer send the data. I receive a 400 Bad Request.
Some References of my code:
My Controller which handles the POST request:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using ClientsDataAccess;
namespace MS_Clients_Post.Controllers
{
public class ClientsController : ApiController
{
public HttpResponseMessage Post([FromBody] Client client)
{
try
{
using (NewlandiaEntities entities = new NewlandiaEntities())
{
entities.Clients.Add(client);
entities.SaveChanges();
var message = Request.CreateResponse(HttpStatusCode.Created, client);
message.Headers.Location = new Uri(Request.RequestUri +
client.Id.ToString());
return message;
}
}
catch (Exception ex)
{
return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ex);
}
}
}
}
My webAPIconfig.cs file (where I enabled CORS):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using System.Web.Http.Cors;
namespace MS_Clients_Post
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
//enabling cors. The "*","*","*" attributes allow all to access. This should be more limited acccess in the future.
var cors = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(cors);
//end of cors code.
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}
What I'm seeing in Fiddler:
OPTIONS Response 200 (Only returned with Angular APP, not POSTMAN
along with POST Response 400 BAD REQUEST (With POSTMAN or Angular APP
TLDR;
POST request using ASP.net Web API works before enabling CORS. Why doesn't it work after?
Any help is greatly appreciated!
I found the solution to my problem. This was a failure to identify what was actually going wrong. Couple different things:
When my application was deployed by VSTS to my development webserver it removed the SQL server login credentials from IIS application. (Advanced settings on IIS application pool).
Secondly and more importantly, the Syntax of my Angular Application was indeed not correct. Therefore the syntax was wrong from the Angular Application, but correct from POSTMAN (in postman I would use a GET method to get the JSON from server, and copy-paste the JSON to do a POST request).
Lesson learned, if it says 400 Bad Syntax, double check the syntax of what you are sending!
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 have written several WCF data services and find them quite useful. However, I have found routing to be quite a pain. I have seen conversations that indicate that you can host a data service in an ASP.Net MVC app (I have always used ASP.Net web sites). However, I do not seem to be able to find any examples of how to achieve this. Does anybody have any references I could check-out or advice?
The question was posted some time ago but I assume there are still people interested in using WCF Data Services in ASP.NET MVC projects.
Assuming that you have in your project a service called: 'DataSourceService.svc' you can use this service in an MVC project by configuring the routing in 'RouteConfig.cs' as follows:
using System.Data.Services;
using System.ServiceModel.Activation;
using System.Web.Mvc;
using System.Web.Routing;
namespace <YourNamespace>
{
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
// the controller should NOT contain "DataSourceService"
constraints: new { controller = "^((?!(DataSourceService)).)*$" }
);
routes.Add(new ServiceRoute("DataSourceService", new DataServiceHostFactory(), typeof(DataSourceService)));
}
}
}
Make sure that you have in Web.config the following configuration:
<configuration>
...
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>
...
</configuration>
Now you can check that everything works fine by running your project in the browser and using the following url:
http://localhost:port_number/DataSourceService/$metadata
... which should return your metadata.
The WCF web api may do what you're looking for. Here's their getting started page. You host the service inside of the MVC app, and even hook into into the same routing that MVC uses.