How to get the request URI of a RESTful webservice - c#

I have a webservice that is used under several different websites and want to know which of the sites the request came through (and return different things depending on that data). How do I do this?
I have a website, example.com, that has one webservice in /webservice.svc . When the client comes to this site via http://client1.example.com/webservice.svc/hello I want to say "hello, client1!" and when they come through http://client2.example.com/webservice.svc/hello it should say "hello, client2!".
So client1 or client2 depending on subhost (or application directory)

Ended up getting this done with HttpContext.Current.Request.Url.ToString();
It too returned "Object reference not set to an instance of an object" originally when I tried, but found that setting [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] before my class declaration as well as in web.config did the trick and allowed access to the variables I wanted.

Assuming you are using WCF, you can try:
System.ServiceModel.Web.WebOperationContext.Current.IncomingRequest.Headers["Referer"]
The result will in your example be http://client1.example.com/webservice.svc/hello or http://client2.example.com/webservice.svc/hello. You can then parse that string for presence of client1 or client2.
You may want to check for nulls.

Related

Consume Rest API X-pagination from header

How can I extract the X-Pagination header from a response and use the next link to chain requests?
I've tried in both Postman and C# console application with RestSharp. No success.
Easiest would be a small console application to test. I just need to iterate through the pages.
This is what I get back in the headers X-Pagination:
{
"Page":1,
"PageSize":20,
"TotalRecords":1700,
"TotalPages":85,
"PreviousPageLink":"",
"NextPageLink":"www......./api/products/configurations?Filters=productid=318&IncludeApplicationPerformance=true&page=1",
"GotoPageLinkTemplate":"www..../api/products/configurations?Filters=productid=318&IncludeApplicationPerformance=true&page=0"
}
In Postman you simply retrieve the header, parse it into a Json object then use the value to set a link for your next request.
Make your initial request then in the Test tab do something like:
var nextPageLinkJson = JSON.parse(pm.response.headers.get("X-Pagination"));
var nextPageLink = nextPageLinkJson.NextPageLink;
pm.environment.set("nextPageLink", nextPageLink);
If you don't know how many pages you're going to have then you'll have to play with conditions when to set the nextPageLink variable and what not but that's the general idea.
You can set the request to run using the new link with postman.setNextRequest("request_name") as well.
Additionally this approach will only work in collection runner.

Is it possible to override the UserHostAddress property of the HttpRequest class?

I have a situation where I need to put my application behind a proxy server, this causes all the request's that are coming to my application to have the same set of IP addresses used by the proxy servers. However the Proxy server provides the real IP address of the requestor in a custom header, that I can use through my application so I can know the real IP address of the requestor. This is mainly used for logging and tracking. Is there a way I can have the UserHostAddress property return the value from this custom header? This would save a lot of work, because this property referenced about a few hundred time.
It's not possible to change the behavior of the UserHostAddress property, however what you can do is add an extension method to the Request class (something like GetRealUserHostAddress()) and just do a global replace on UserHostAddress -> GetRealUserHostAddress() to rapidly sort out all the instances of it in your solution.
public static string GetRealUserHostAddress(this HttpRequestBase request)
{
return request.Headers["HeaderName"] ?? request.UserHostAddress;
}
If you are saying that the proxy returns the real ip address of the client making the request, you don't need to use the UserHostAddress to read it; you can simply read the header directly:
string realIP = HttpContext.Request.Headers["actual_header_key"];
No, it's not possible. You can read the custom header and place in the request context and use that later.

Differentiate between client app and browser in ASMX Web Service?

This is a follow-up to Choosing a Connection String based on kind of request for which I got no answer and what I thought worked doesn't.
I have a webservice that needs to choose a specific connection string based on the user calling it from a browser or from a client application.
I tried:
HttpContext.Current != null? ConnectionStrings["Website"].ConnectionString : ConnectionStrings["Client"].ConnectionString
but realized that at some point even if I'm using the client application, there is some HttpContext (if someone can explain why it'd be great) but the Browser field under Request is "Unknown". So, then I tried:
if ( HttpContext.Current != null )
{
if ( HttpContext.Current.Request.Browser != "Unknown" )
{
//browser connection string here
}
else
//client app connection string here
}
else
//client app connection string here
This worked wonders when debugging, but on testing environment it still points to Browser connection string even when calling from the client app, as if at some point the Browser isn't "Unknown" ...
Is there a MUCH easier/simpler way to do this? The way I'm doing it seems really ugly.
I'm quite desperate at the moment as I have no idea why this is happening..
Rather than detecting and switching on the browser type, consider these two suggestions:
Add Custom Request Headers
In your various callers, define a new custom header in your Http request.
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Headers.Add("CallerType", "ClientApp"); // "Browser", etc.
Then you know exactly and reliably what type of client is calling. This would be hard to get wrong, and couldn't be spoofed/mistaken.
Include The Caller Type in the QueryString
myService.asmx?BrowserType=1
Add a simple new querystring parameter to your .asmx webmethod. This will work just the same in a controlled environment, but if other users/developers get it wrong, or malform the expected values, you'd have to take other measures to correct/handle.
Both allow you to easily determine the connString on the incoming value. Perhaps the absense of a modifier/header, you could assume a default. Your sample question has 2 basic outcomes, and either suggested solution will be easy to extend (browser, client app, iPhone, whathaveyou).

Consuming a void service operation in a WCF data service

from a Wcf data service client (inherited from System.Data.Services.Client.DataServiceContext) I would like to invoke a service operation defined on a Wcf Data Service that returns void
[WebGet]
public void Operation()
{
// logic
}
The only reasonable method I found is the Execute, but how could I use it with a void operation?
Thank you
You can use just plain HttpWebRequest to do this. I think it will need to be POST service operation (as GET would assume some response, but since you declare it as void it would have no response). In which case Execute can't be used anyway (as it always issues a GET request).
Using plain HttpWebRequest just issue a simple POST to the service operation URL and just check the response status code (should be 204 No Content).
Currently WCF Data Services doesn't have native client support for service operations, so you need to write one for yourself.
I have found a workaround for this problem.
This website solved me quite a few problems before, so I thought it would be nice to share back.
The quick answer to your question is:
string empty = context.Execute<string>(new Uri("Operation", UriKind.Relative)).FirstOrDefault();
The "empty" string should be null or empty upon response. It "works around" the HttpWebRequest method mentioned on the post above.
Further more, it is also possible to get primitive types back using this technique.
Lets say I have this Method:
[WebGet]
public bool Authenticate(string Username, string Password)
{...do stuff here...}
When you try the normal execution it fails (Vitek Karas explains it well in his reponse above):
var query = context.CreateQuery<bool>("Authenticate").AddQueryOption("Username", "'itye'").AddQueryOption("Password","'123456'");
DataServiceCollection<bool> list = new DataServiceCollection<bool>();
list.Load(query);
But the following will do the trick:
var query = context.CreateQuery<bool>("Authenticate").AddQueryOption("Username", "'itye'").AddQueryOption("Password","'123456'");
bool authenticated = context.Execute<bool>(new Uri(query.RequestUri.ToString().Replace("Authenticate()", "Authenticate"))).FirstOrDefault();
Please note the Replace("Authenticate()", "Authenticate"), which omits () from the query string (otherwise it will cause error).
Hope it helps.
- Itye
Thanks Itye
I was looking for similar solution. Did using HttpWebRequest way first. But your two lines of code helped me doing the same task. Very Happy. Thanks Once Again..
var query = context.CreateQuery("Authenticate").AddQueryOption("Username", "'itye'").AddQueryOption("Password","'123456'");
bool authenticated = context.Execute(new Uri(query.RequestUri.ToString().Replace("Authenticate()", "Authenticate"))).FirstOrDefault();

Check if website is online with ASP.NET C#?

I would like to know how to check if a website is offline or online using C#?
Try to hit the URL using HttpWebClient over an HTTP-GET Request. Call GetResponse() method for the HttpWebClient which you just created. Check for the HTTP-Status codes in the Response.
Here you will find the list of all HTTP status codes. If your request status code is statrting from 5 [5xx] which means the site is offline. There are other codes that can also tell you if the site is offline or unavailable.You can compare the codes against your preferred ones from the entire List.
//Code Example
HttpWebRequest httpReq = (HttpWebRequest)WebRequest.Create("http://www.stackoverflow.com");
httpReq.AllowAutoRedirect = false;
HttpWebResponse httpRes = (HttpWebResponse)httpReq.GetResponse();
if (httpRes.StatusCode==HttpStatusCode.NotFound)
{
// Code for NotFound resources goes here.
}
// Close the response.
httpRes.Close();
First off, define "online" and "offline". However, if your codebehind code is running, your site is online.
For my web apps, I use a setting called Offline, which admin can set on/off.
Then I can check that setting programmatically.
I use this Offline setting, to show friendly maintenance message to my users.
Additionally you can use App_Offline.htm,
reference :
http://www.15seconds.com/issue/061207.htm
http://weblogs.asp.net/scottgu/archive/2005/10/06/426755.aspx
If you mean online/offline state that controls IIS, then you can control this, with custom Web Events (Application Lifetime Events)
http://support.microsoft.com/kb/893664
http://msdn.microsoft.com/en-us/library/aa479026.aspx
You can use Pingdom.com and its API's. Check the source code of the 'Alerter for Pingdom API' at the bottom of this page

Categories

Resources