I am doing AngularJS2 with Restful web API , and getting some console errors while calling HTTP post. Errors are listed below,
Hope you help
Controller code snippet
namespace SoomWebApi.Controllers
{
[EnableCors(origins: "http://localhost:64336", headers: "*", methods: "*")]
public class UserController : ApiController
{
public HttpResponseMessage UserLogin([FromBody] LoginRequestData objValidate)
{
UserModelManager _UserModelManagerr = new Models.UserModelManager();
return Request.CreateResponse(HttpStatusCode.OK, _UserModelManagerr.Login(objValidate), GetJSONFormatter());
}
}
}
Webapiconfig code snippet
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
config.EnableCors();
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
It look like a CORS problem .. try to put in your Startup.cs file in WebAPI something like:
using Microsoft.Owin;
using Owin;
public void Configuration(IAppBuilder app)
{
app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);
ConfigureAuth(app);
}
If you want to limit to some specific host ..try something like:
var corspolicy = new corspolicy
{
allowanymethod = true,
allowanyheader = true,
supportscredentials = true,
origins = { "http://www.example.com", "http://localhost:38091", "http://localhost:39372" }
};
app.usecors(new corsoptions
{
policyprovider = new corspolicyprovider
{
policyresolver = context => task.fromresult(corspolicy)
}
});
Your server should support CORS to allow access from different domains. Update your server configuration to allow only predefined set of domains to allow access.
Access-Control-Allow-Origin: "domains"
If you have this problem on debug only and do not plan use CORS after deploy - mostly local web server starts your Angular application on localhost:some-port and server deployed on localhost also - use IE for debugging - it works good even when your angular middleware and backend works on different ports.
If the code in production will be on the same domain as REST API, you can install chrome extension to avoid CORS error:
Chrome CORS extension
Related
I need to add a very simple Web API to an existing library so that Python can communicate with the application. Simple Request/JSON response. This is more challenging than initially thought. I'm used to NodeJS where a library like Express can do this in a few lines of code.
Obviously the web server needs to be integrated in the library. I cannot be dependent on IIS or any web server.
These kinds of tutorials are all over the web:
https://github.com/jbogard/Docs/blob/master/aspnet/web-api/overview/hosting-aspnet-web-api/use-owin-to-self-host-web-api.md
Install: Microsoft.AspNet.WebApi.OwinSelfHost
Main
static void Main(string[] args)
{
string baseAddress = "http://localhost:9000/";
// Start OWIN host
using (WebApp.Start<Startup>(url: baseAddress))
{
// Create HttpCient and make a request to api/values
HttpClient client = new HttpClient();
var response = client.GetAsync(baseAddress + "api/values").Result;
Console.WriteLine(response);
Console.WriteLine(response.Content.ReadAsStringAsync().Result);
Console.ReadLine();
}
}
Startup
public class Startup
{
// This code configures Web API. The Startup class is specified as a type
// parameter in the WebApp.Start method.
public void Configuration(IAppBuilder appBuilder)
{
// Configure Web API for self-host.
HttpConfiguration config = new HttpConfiguration();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
appBuilder.UseWebApi(config);
}
}
Controller
public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/values/5
public string Get(int id)
{
return "value";
}
// POST api/values
public void Post([FromBody] string value)
{
}
// PUT api/values/5
public void Put(int id, [FromBody] string value)
{
}
// DELETE api/values/5
public void Delete(int id)
{
}
}
It seems simple enough, however, it does not work in .NET 6. There seems to be compatibility issues.
I stumbled upon threads like the following ones:
Self Hosting OWIN in .NET Core
NullReferenceException experienced with Owin on Startup .Net Core 2.0 - Settings?
However I'm struggling to find a practical answer onhow to deploy a simple Web API in an existing .NET 6 library. The workaround suggested does not work for me.
Any advice will be appreciated ? Should I rather go for a different library? Is ASP.NET not the right tool to use ?
ASP.NET Core comes with build in and enabled by default web server - Kestrel so there is no need to set up OWIN. The simple setup can look this way (UseKestrel is called internally by WebApplication.CreateBuilder):
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
app.MapGet("/", () => "Hello World!");
app.Run();
See also:
Host and deploy ASP.NET Core.
Servers
Use the ASP.NET Core shared framework
Good day, I am in a bit of a problem with my hosted ASP.NET WebAPI and MVC app hosted on IIS on a web server (MS Windows Server 2016). This is a basic website and includes an API in the same project. The web app has Areas and I suspect this is the problem. Periodically the website (Areas and API) goes down, the weird thing is that the views not under areas work fine, and the ones under areas and API stop working. There is no customization from the boiler template code for creating areas and so forth. I have also profiled requests coming in, but these are all basic calls with not a lot of data. I cannot see anything in the Event Viewer or IIS Logs, please does anyone have a suggestions?
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);//WEB API Registration
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
DiConfig.Register();
//Enable Claims Anti Forgery
AntiForgeryConfig.UniqueClaimTypeIdentifier = ClaimTypes.NameIdentifier;
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.MetadataPropertyHandling = MetadataPropertyHandling.Ignore;
}
Routing Config:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.RouteExistingFiles = true;
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Exports", action = "Index", id = UrlParameter.Optional },
namespaces:new[] {""}
);
}
}
WebAPIConfig:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
//config.MessageHandlers.Add(new TokenValidationHandler());
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/v1/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
//Configure to use XmlSerializer so you don't have to configure namespace in xml request
config.Formatters.XmlFormatter.UseXmlSerializer = true;
config.Formatters.XmlFormatter.SetSerializer<CertificateRequest>(new XmlSerializer(typeof(CertificateRequest)));
config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/octet-stream"));
//Ignore Self Looping References
config.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
//WEB API Throttling
config.MessageHandlers.Add(new ThrottlingHandler()
{
Policy = ThrottlePolicy.FromStore(new PolicyConfigurationProvider()),
Repository = new CacheRepository()
});
//
config.Services.Add(typeof(IExceptionLogger), new ElmahExceptionLogger());
}
}
I have 2 seperate project in different ports, one is asp.net web api and another is angularjsUI, which consumes the webapi service. When i call webapi service from my angular project, the service is not hit.
If both service and angularUi are in same project then there is no issue , i am able to use the service.
Technology used:
Vs2015,
Angularjs1.6,
WebApi2
How to make communication between these two seperate projects in different ports successful.
Example :
Step 1: These files are in my angularUI project
LoginController.js
$scope.RegisterClick=function(myregister) {
var apiRoute = "http://localhost:51002/api/LoginApi";
var registerdata = LoginService.post(apiRoute, registeruserdetails);
}
LoginService.js
myqcapp.service("LoginService", function ($http) {
this.post = function (apiRoute, Model) {
var loginresult = $http({
method: "post",
url: apiRoute,
dataType: 'json',
headers: {
"Content-Type": "application/json; charset=utf-8"
},
data: Model
});
return loginresult;
}
});
Step 2: In my WebApi project
LoginApiController.cs
public class LoginApiController : ApiController
{
[ResponseType(typeof(Register))]
public IHttpActionResult Post(Register registercls)
{
if (ModelState.IsValid)
{
registerbs.Add(registercls);
return CreatedAtRoute("DefaultApi", new { id = registercls.Userid }, registercls);
}
else
{
return BadRequest(ModelState);
}
}
}
WebApiConfig.cs
public static void Register(HttpConfiguration config)
{
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{Controller}/{id}",
defaults: new {
Controller="LoginApi",
id = RouteParameter.Optional
}
);
}
You need to enable cross site scripting on your Project/web app that serves the web API.
Your UI/API consumer is in separate project/port and if cross site scripting (CORS) is disabled the API server won't consider the request as " same origin request ".
You need to call EnableCors() inside the Register(HttpConfiguration conf) method of WebApiConfig class in App_Start folder. If WebApiConfig is not present by default then you may have to add it.
Next you need to decorate your controller with [EnableCors] annotation, say my web page is at localhost:8080, just decorate it as :
[EnableCors(origins: "http://localhost:8080", headers: "*", methods: "*")]
public class LoginApiController : ApiController
{
.....
}
you could also allow any site to access your API by using * wildcard
[EnableCors(origins: "*", headers: "*", methods: "*")]
you need to learn more about CORS. You also need to address the security aspect of CORS.
I have a web api that runs in a WPF C# application. I have used Owin to implement it. If I send request by using /api prefix then it works as I expected.
http://localhost:8080/api/test/config?no=7
However, I need to remove the /api prefix. If I try the request below it does not work when I tried example code below.
http://localhost:8080/test/config?no=7
Is it possible to remove api word from requests?
Here is my code:
WebApp.Start<Startup>(url: "http://*:8080/");
class Startup
{
Type ValuesControllerType = typeof(TestController);
public void Configuration(IAppBuilder Builder)
{
var Instance = new HttpConfiguration();
Instance.MapHttpAttributeRoutes();
Instance.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "{controller}/{action}/{request}",
defaults: new { request = RouteParameter.Optional }
);
Builder.UseWebApi(Instance);
}
}
[RoutePrefix("test")]
public class TestController : ApiController
{
[HttpGet]
[Route("config")]
public string Config(string No)
{
try
{
return No;
}
catch (Exception e)
{
return string.Empty;
}
}
}
I tried the answer in C# web api route for a webservice but did not work.
I get following error:
HTTP Error 503. The service is unavailable.
On the Rest api open your WebApiConfig.cs you should find the following code:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}"
);
Try removing api from there
I faced the same problem in .Net Core 2 WebAPI project
here is my solution
[Produces("application/json")]
[Route("[controller]")]
public class DefaultController : Controller
{
[Route("getUser")]
public IActionResult GetUsers()
{
return Ok();
}
}
the address is http://localhost:port/default/getuser
I have two web API project DLLs in one solution.
Structure of my Project Solution:
In my solution, the projects are located as follows:
1) Base Solution
2) Base Web API
3) Module Web API
Hence, my solution is something like a BASE solution which contains many MODULES. Each Modules can contain its own Web APIs. Also, my Base Solution contains its own Web API
This is our structure.
My Problem:
It is working fine in my local run solution. When I host it to the IIS, it is working for few hours and then it stops working by throwing the error message "Error 404 found". When I try to access through URL directly which is something like "http://127.0.0.1:51/Products/Get", not working.
Visual Studio version:
Visual Studio Professional - 2015
IIS Version:
IIS - 7.5.7600
My approach:
I have a simple project which simulates this scenario. It has the same problem with my original project.
Web API For Base Module:
WepApiConfig under App_Start:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Base API Controller:
public class ValuesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/values/5
public string Get(int id)
{
return "value";
}
}
WebApiConfig.cs For Module Web API:
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
//config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultModuleApi",
routeTemplate: "api/module/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Module API Controller:
public class ModulesController : ApiController
{
// GET api/values
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/values/5
public string Get(int id)
{
return "value";
}
}
NOTE from the above code:
The difference between the two APIConfig files is :
For Module Code:
routeTemplate: "api/module/{controller}/{action}/{id}"
For Base Code:
routeTemplate: "api/{controller}/{action}/{id}"
Global.asax:
namespace BaseSln
{
public class Global : HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
//GlobalConfiguration.Configure(WebApiConfig.Register);
var typesWithMyAttribute =
from a in AppDomain.CurrentDomain.GetAssemblies()
from t in a.GetLoadableTypes().Where(t1 => t1.Name == "WebApiConfig"
&& t1.GetMethod("Register") != null
&& t1.GetMethod("Register").IsStatic)
select new { Type = t, MethodInfo = t.GetMethod("Register") };
//register all the Routes
foreach (var type in typesWithMyAttribute)
{
var mi = type.MethodInfo;
Action<HttpConfiguration> action = null;
try
{
action = Delegate.CreateDelegate(typeof(Action<HttpConfiguration>), mi) as Action<HttpConfiguration>;
}
catch
{
//ignore the errors for now... should be handled somewhere else or logged.
}
if (action != null) GlobalConfiguration.Configure(action);
}
}
}
}
What I tried with the above project:
After hosting in IIS, I tried to access the path which is something like this:
For Base API:
http://localhost:51600/api/Values/Get
Returns:
value1
value2
For Module API
http://localhost:51600/api/Modules/Get
Returns:
value1
value2
My problem:
After sometime, when I try to access the same link, I am unable to get that. It says
status 404. Not Found
I have been working on this issue for 3 days, and I couldn't resolve the problem.
I have searched many articles in stackoverflow, but no luck.
Kindly help me to get rid off from this.
Thanks.
Can you check the GlobalConfiguration.Configuration.Routes in the Base Solution if you have all the routes for both the Base Web API and the Module Web API?