API Calls to controller is breaking after deploying to IIS - c#

I am invoking API calls to get JSON data from server using javascript.
$(function () {
var customersTable = $('#Customers');
var returnCustomersTable = UpdateDataTable(customersTable, "/Customers/Loaddata");
}
This works fine when I am working with Visual studio Dev environment , because my web application is on root and so all javascripts Works fine.
Example:
My WebSite URL: http://localhost:4391
API Calls will be: http://localhost:4391/Customers/Loaddata
This works fine.
But when I deploy application to IIS, my website URL will be,
My WebSite URL: http://localhost/MyAppName
But API calls would still be,
API Calls will be: http://localhost/Customers/Loaddata, which results in not found.
Since I am using javascript in a separate file , I wont be able to do URL.Action.
The other option would be to create a base URL for dev and prod and the append with each servcie call.
But I am thinking if there is any other way.

The routing configuration in ASP.NET MVC is designed to serve as the single place in the application where all of the URLs can be maintained.
It helps considerably with maintenance of the project if all URLs are generated using routing through one of the UrlHelper based methods, such as Url.Action() rather than hard coded in controllers and views.
As long as your JavaScript is in an MVC view, you can just resolve Url.Action inline.
$(function () {
var customersTable = $('#Customers');
var returnCustomersTable = UpdateDataTable(customersTable,
'#Url.Action("Loaddata", "Customers")');
}
If the JavaScript is in a separate file outside of MVC, consider passing the URL through a variable or function parameter.
This routing feature also makes it easier to deploy ASP.NET MVC, because the generated URLs will adapt to use the application path when the application is not deployed to the root website virtual directory.
Application running in IIS web site root:
/Customers/Loaddata
Application running in virtual subdirectory configured as IIS Application named "MyAppName":
/MyAppName/Customers/Loaddata

Related

.Netcore api with ReactJs dynamic URL Pathname

I'm currently in the process of converting project frontend from .netcore web application (razor page) to reactjs, one of the road block we encounter is the dynamic url path that we applied in razor page.
As the application is deployed on IIS under default website, so the url is construct as https://localhost/Project. One of the project requirement is it can to be replicate and deploy many time, so there will be https://localhost/Project{n}. That mean the url path name need to be configurable so the frontend JavaScript will request to the correct api url. What i done was config the pathname in iis application's webconfig and inject it into the razor page, so javascript can refer to the injected pathname variable.
But when come to reactjs, it is a seperate project from backend but they share the same url, and reactjs has no way to get the configurable pathname so it can only stick to whatever set in the public_url/homepage, and it can only be set before project is build. As it is not set dynamically, the frontend point to the right default page but wrong javascript url, so it cant even run the react main chunk js.
Any lead for me to continue on? Or i need to change the way of configurable pathname?
In React you can use standard JS. So in order to get the current path name from your React application, you can do something like:
const pathname = location.pathname
If you need the pathname in many different places in your React project, you can set it as a context. (See this documentation)
Alternatively, if you only need it on the initial load, you can just do a useEffect in your app.js file like:
const {pathname, setPathname} = React.useState();
React.useEffect(()=>{
setPathname(location.pathname);
}, [])

How to make an HTTP GET request to OWIN self hosted API?

I'm very new to web development but I wanted to create a web api for an existing Windows Service application I created for work.
My goal right now is to create a simple web app consisting of some text input fields where someone can enter their email and subscribe to a mailing list.
I was pointed in the direction of using OWIN to self-host a web api in my existing project so I looked at this guide to get started:
https://www.asp.net/web-api/overview/hosting-aspnet-web-api/use-owin-to-self-host-web-api
This guide shows the console app calling and displaying the API, but I wanted to do the same from a web app. So I tried to do what is accomplished here in the 'Getting Started with ASP.NET Web Api 2' guide using a console application with OWIN.
When I start my console application, I can enter http://localhost:8080/api/values/1 and I get <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">value</string> Which I assume means the web server is running and responds to the request to get my string value that I'm returning from my ValuesController.
However I've been trying to create a simple web page that calls the API to get the value but I haven't been able to figure it out.
Right now my index.html has the following in the body:
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.0.3.min.js"></script>
<script>
var uri = "http://localhost:8080/api/values/1";
$(document).ready(function () {
$.getJSON(uri)
.done(function (data) {
$('#value').text("done");
})
.fail(function (jqXHR, textStatus, err) {
$('#value').text('Error: ' + err);
});
});
</script>
And I just get Error: printed on the page. Again I'm new to working on web related technologies so any guidance would be much appreciated.
Ok so, following the discussion in comments (helping you to debug the app).
The cross-origin security policy in browsers restricts web pages from calling an data source that exists on a different domain. A domain is either a different url, or a different port at the same url.
http://localhost:80
is a different url/domain from:
http://localhost:81
There are two solutions to this, either utilise JSONP, or CORS to make the request to the api, JSONP basically wraps your json data up in a function call. When the api call returns, it executes the callback/function call, bypassing the security restriction.
However, both JSONP and CORS require server support, which brings solution 2...
Serve up the webpage you are trying to use from the API, meaning you server it from the same domain, hence no cross-domain issues!!
Glad you have got it sorted, I know it can be frustrating with web calls.

How do I get a list of all configured WebApi routes in asp.net MVC?

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,....

why do not show alias name in iis?

I create a website by Visual Studio and publish it.
Then in IIS I do:
dd application and
set alias name to CIP and set physical path.
Home page is loaded correctly but other pages have wrong URLs in addressbar.
This is homepage URL: "http://localhost/CIP/Pages/Default.aspx".
When I click on the other link showed below link without CIP(alias name).
"http://localhost/Pages/OperationPersonelProgram.aspx".
You need to have your application make sure that the URLs it's using make sense. This requires some server side code to execute. So, if you're writing an MVC website you would use the UrlHelper class, something like:
<a class="link" href="#Url.Content("~/Pages/HostessPersonalProgram.aspx")">mylink</a>
(The above is Razor syntax, but similar should be possible).
Most of the different "styles" of ASP.Net offer a similar shorthand for obtaining the correct URL, but if all else fails you can always use VirtualPathUtility.ToAbsolute:
var url = VirtualPathUtility.ToAbsolute("~/Pages/HostessPersonalProgram.aspx");

Web api routing in subfolder application

I have a main site running under example.com. Now I'm creating a application into example.com subfolder like example.com/subfolder/subsite/, so I have created a application in the subsite folder and everything is working fine, except the routes.
I have the following route:
RouteTable.Routes.MapHttpRoute("myapi", "api/{controller}/{hash}", defaults: new { hash = RouteParameter.Optional });
The route is working fine if I'm debuging the API in localhost or hosting it somewhere else in the root, but it's not working when running inside the subsite application folder.
Any tips?
Did you really create a new web application instead of just a virtual sub directory?
I just tested it, create a simple api controller which returns a string and create a /test site in a /test/sub site, both running the same web api project.
And it simply works.
If this is not the issue, please provide more details... error msg etc...

Categories