I have a WCF POX (RESTful) service which is working well. It can be accessed at a Url which takes the format https://APPLICATIONNAME/service.svc/postdata
The APPLICATIONNAME is the host name and DNS name, to map the call through to IIS 7.
The question I have now, is that ideally I wouldn't want to use the "service.svc" part of the url and just use the following Url to post to the application;
https://APPLICATIONNAME/postdata
Any pointers on how I do this? Ideally I wouldn't want to use aspnetcompatibility. I would have thought this would be a standard thing to do - but can't fine on tips on how to do it.
Many thanks
Related
I have one API and two different domain. How can I check which domain host triggered api request?
Example:
API: example.API.com
Domain1: example.Domain1.com
Domain2: example.Domain2.com
and I want to know which domain call my API?
I used C# for my code, maybe there is a ready way to solve my problem but if not then maybe some advice on how to approach the problem?
I try code.
string host = _httpContextAccessor.HttpContext?.Request.Headers.Referer.FirstOrDefault();
This code gives me the full url of the client, but I don't know if that's a good way because
this can be null.
I want to register my WebAPI to Consul service discovery and for that I should provide URL of my WebAPI (for example: http://service1.com) and health check endpoint (http://service1.com/health/check). How can I get that URL?
I found this piece of code:
var features = app.Properties["server.Features"] as FeatureCollection;
var addresses = features.Get<IServerAddressesFeature>();
var address = addresses.Addresses.First();
var uri = new Uri(address);
It returns 127.0.0.1:16478 instead of localhost:5600. I think first one used by dotnet.exe and second one is IIS which forwards 5600 to 16478. How can I get localhost:5600 in Startup.cs?
Well, there are multiple solutions for this problem. Your address is this:
string myurl = $"{this.Request.Scheme}://{this.Request.Host}{this.Request.PathBase}";
It returns 127.0.0.1:16478 instead of localhost:5600
You got this right yes. One is from IIS and one from dotnet. So, you have a problem of trying to get correct url. Ok, so what happens if you service is behind reverse proxy? https://en.wikipedia.org/wiki/Reverse_proxy
Then your service will not be exposed directly to internet, but requests made to specific url will be passed from reverse proxy to your service. Also, you can configure reverse proxy to forward additional headers that are specifying where the original request came from. I think that most reverse proxies are using X-Forwarded-For (Some of them are using X-Original-Host etc).
So if you have proper header set on RP, then you can get url like this:
url = url.RequestContext.HttpContext.Request.Headers["X-Forwarded-For"]
Url is of type UrlHelper. To simplify this method, you can create extension method (GetHostname(this UrlHelper url)) and then us it in your controller or wherever you want. Hope it helps
I don't think it is possible since there is usually a reverse proxy in production that handles public address and the application itself should not be exposed to public and, therefore, be aware of public address. But there can be some workarounds:
Place URL is some kind of config file that can be updated during deploy steps to have the correct URL.
Application can get full URL of the request like this, so after first actual request to the application we can get hostname.
EDIT: I reread your question. You wanted to know how to do this in Startup.cs. You can, but with fewer fallbacks. Your only choices are configuration or raw DNS.GetHostName(), which are less than ideal. Instead, upon any request to your service, lazily register your API. This is when you have context. Prior to that, your service knows nothing Jon Snow. The first request to your API is likely going to be health-checks, so that will kick off your registration with consul.
A solution I've used is a combination of configuration and headers in a fallback scenario.
Rely first on the X-Forwarded-For header. If there are cases where that doesn't apply or you have a need to... you can fallback to configuration.
This works for your use case, discovery. That said, it also works when you want to generate links for any reason, (e.g. for hypermedia for JSON API or your own REST implementation).
The fallback can be useful when there are reconfigurations occuring, and you have a dynamic configuration source that doesn't require a redeployment.
In the ASP.NET Core world, you can create a class and inject it into your controllers and services. This class would have a method that knows to try config first (to see if overriding is needed) and then the X-Forwarded-For header, and if neither is appropriate, fallback further to HttpContext.Request to get relevant URI parts.
What you're doing is enabling your API to be contextless and resiliency (to change) by giving it some contextual awareness of where "it lives".
This happens when you try to get current URL in Startup.cs. I've faced this issue before. What i did as Solution for my problem is. I Just declared Custom Setting in AppSettings in web.config(For Local) file and web.release.config(For Live)
like following
in web.config
<appSettings>
<add key="MyHost" value="http://localhost:5600" />
</appSettings>
in web.release.config
<appSettings>
<add key="MyHost" value="http://myLiveURL.com" />
</appSettings>
in startup.cs
string hostSetting = ConfigurationSettings.AppSettings["MyHost"];
And different host in release file. so what it helped is i can get Localhost URL in local website from web.config and Live URL from web.release.config.
if you are using Azure for live. it will be more easier for live(you would not need to add setting web.release.config file). add app setting in your website application setting https://learn.microsoft.com/en-us/azure/app-service/configure-common
In Case of ASP.NET Core you can use appsettings.json instead of web.config
The Setup
I am building an app using ASP.NET MVC3, the application makes use of sub domains, i added the following in my hosts file : 127.0.0.1 students.localhost.
This all seems fine, when i debug, the browser opens up localhost:{PORT}, i can browse the site, i can also open up: students.localhost:{PORT}, and the site works perfectly.
In case you were wondering, i made use of: Maarten Balliauw's code to achieve the routing requirements in MVC and subdomains
The Problem
I need to somehow find out what subdomain the user is accessing the site from. If i debug, my and go to my subdomain:http://students.localhost:{PORT} Request.Url is : http://localhost:{PORT}, for some reason the deubugger (or ASP.NET Development Server) is not picking up students.
Please do not go into the TLD descussion trying to explain what a subdomain really is, all i need is the first string after http://. in local and production this WILL be my subdomain.
Thanx in advance
UPDATED:
I managed to get the desired result by making use of:Request.Headers["host"], it would be interesting to find out why Request.Url does not contain the students substring.
The easy way to do this is to put a fully qualified domain name in hosts. If the production site is subdomain.domain.com, I like to use subdomain.domain.local and just map this to 127.0.0.1.
new System.Uri(Request.RawUrl).Host
I think this will be the real hostname.
I have several RESTful endpoints like such:
System.Security.Role.svc
System.Security.User.svc
etc.
This is meant to be a namespace so our RESTful URL's would look like:
/rest/{class namespace}/{actions}
I have tried a few examples to get the SVC extension removed when my endpoint has multiple periods in it, however, nothing seems to work.
I have tested with the WCF REST Contrib package (http://wcfrestcontrib.codeplex.com/), this example (http://www.west-wind.com/weblog/posts/570695.aspx), and another StackOverflow post (How to remove the ".svc" extension in RESTful WCF service?).
This works great when my endpoint is something like this:
Echo.svc
It will properly remove the SVC extension.
Any ideas on how to handle endpoints with multiple periods in the endpoint name?
EDIT:
After some further testing, I found out that it is failing because whenever you do:
string path = HttpContext.Current.Request.AppRelativeCurrentExecutionFilePath;
If the endpoint contains multiple periods, it strips off everything after the endpoint causing all of the standard IHttpModule's to fail.
Example:
If I call http://localhost/services/Echo/test, my relative app file path has a returned value of:
~/echo/test
However, if I make a call as http://localhost/services/System.Security.User/test, then my relative app file path has a returned value of:
~/system.security.user
I am missing the '/test' on the end in that situation.
Have you tried this solution - How to remove the ".svc" extension in RESTful WCF service?
Okay, simple situation: I'm writing a simple console application which connects to a SOAP web service. I've imported a SOAP Service reference and as a result, my application has a default endpoint build into it's app.config file.
The web service, however, can run on multiple servers and the URL to the proper web service is passed through the commandline parameters of my application. I can read the URL, but how do I connect the web service to this custom URL?
(It should be very simple, in my opinion. It's something I'm overlooking.)
Is this using an auto-generated class deriving from SoapHttpClientProtocol? If so, just set the Url property when you create an instance of the class.
Well, .NET can provide some very useless error messages sometimes. In IIS, the service was configured to AutoDetect cookieless mode. As a result, I had to append "?AspxAutoDetectCookieSupport=1" to the URL. Although that would fix the problem, it was just easier to go to the IIS console, open the properties of the service, go to the ASP.NET tab page, click the "Edit configuration" button, to to "State Management" in the newly popped up screen and change "Cookieless mode" into something other than "AutoDetect"...
Excuse me. Dumb error. Am going to hit myself on the head a few times for this. ;-)
As Jon said, you set the Url, as in:
Namespace.ClassName nwe = new Namespace.ClassName();
nwe.Url = "http://localhost/MyURL/site.asmx";