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();
Related
I'm working with the pipedrive API and trying to update a record (deal, but the endpoint isn't important). The format of the is as follows.
https://companyDomain.pipedrive.com/api/v1/deals/DealID?api_token=API-Token
Where companydomain specifies your account with them, dealID is the ID we're updating and API token is the token supplied by pipedrive to access the API. It's not a token that's returned by logging in, it's static one, given on day one and never changes.
HttpClient seems to want a base address so "https://companyDomain.pipedrive.com/", then something like the following:
HttpResponseMessage response = await client.PutAsJsonAsync(
$"api/v1/deals/{dealId}/", args);
Where args is a class with the field/s and value/s I want to update.
If I include the api_token as fields in "args", it returns a 404 not found. If I append it to the base url or the $api/v1/deals/{dealID}/ it returns permission denied.
Any suggestions as to how I can handle this?
I've managed to make a living coding for 30 years avoiding the web, now it's all anyone seems to want. Appears I have to finally get a handle on this, hence the recent questions! ;-)
Thanks in advance
Jim
Append it with a "?"
So your URL should look like api/v1/deals/YOUR_ID?api_token=THE_TOKEN
HttpResponseMessage response = await client.PutAsJsonAsync(
$"api/v1/deals/{dealId}?api_token={apiToken}", args);
My web service calls a url which returns a value which I must capture and use in a different function.
I've only recently starting working with web services and am very new to the concept of calling a url within a web service (Previously asked and answered on this forum for those requiring more information)
Webservice method to call a url
My web service is: Insurance Service.
My client sends me data through the Insurance service which calls a url which returns an Insurance Number.
How do I capture this insurance number? I thought I could use session to capture it but I was so wrong insurance Number comes as null with an object reference error.
int insuranceNo;
insuranceNo = Convert.ToInt16(HttpContext.Current.Session["insuranceNo"]);
It must have something to do with response right?
I thought I could try google what I am looking for but I honestly don't know what to call this in order to search for it. Thought I'd give it another shot in this forum since I found the answer to the first part of this function here.
code to call url:
string url = string.Format("www.insuranceini.com/insurance.asp?fileno1={0},&txtfileno2={1}&username={2}&userid={3}&dteinsured={4}&dteDob={5}&InsurerName={6}", txtfileno1, txtfileno2, username, userid, dteinsured,dteDob,InsurerName)
WebRequest request = HttpWebRequest.Create(url);
using(WebResponse response = request.GetResponse())
{
using(StreamReader reader = new StreamReader(response.GetResponseStream()))
{
string urlText = reader.ReadToEnd();
//Do whatever you need to do
}
}
I would be grateful for any sort of pointers or places to start looking or any advice.
Code began giving different errors. Closing this and referring to : Datetime Conversion and Parsing
Thank you everyone for the helpful comments.
Recently my team was asked to implement an HttpModule for an ASP.NET MVC application that handled double-encoded URLs on IIS 7 and .NET 3.5. Here's the crux of the problem:
We sometimes get URLs that have double-encoded forward slashes that look like so:
http://www.example.com/%252fbar%5cbaz/foo
There are other formats that we have to handle as well, but they all have something in common, they have a double-encoded forward slash.
To fix this, we wrote an HttpModule that only acts when a URL has a double encoded forward slash, and we redirect it to a sane URL. The details aren't important, but there are two bits that are:
We can't control the fact that these URLs have double-encoded forward slashes
And we have not ugpraded to .NET 4.0 yet, nor is it on the immediate horizon.
Here's the problem:
The first request after IIS starts up shows a different URL than the second request does.
If we used the URL from the above example, the first request to IIS would look like:
http://www.example.com/bar/baz/foo
and the second request would look like:
http://www.example.com/%252fbar%5cbaz/foo
This was done by inspecting the Application.Request.Url.AbsolutePath property while debugging.
Here's the smallest code example that should reproduce the problem (create a new MVC application, and register the following HttpModule):
public class ForwardSlashHttpModule : IHttpModule
{
internal IHttpApplication Application { get; set; }
public void Dispose()
{
Application = null;
}
public void Init(HttpApplication context)
{
Initialize(new HttpApplicationAdapter(context));
}
internal void Initialize(IHttpApplication context)
{
Application = context;
context.BeginRequest += context_BeginRequest;
}
internal void context_BeginRequest(object sender, EventArgs e)
{
var url = Application.Request.Url.AbsolutePath; //<-- Problem point
//Do stuff with Url here.
}
}
Then, call the same URL on localhost:
http://www.example.com/%252fbar%5c/foo
NB: Make sure to insert a Debugger.Launch() call before the line in context_BeginRequest so that you'll be able to see it the first time IIS launches
When you execute the first request, you should see:
http://example.com/bar/foo
on subsequent requests, you should see:
http://example.com//bar/foo.
My question is: Is this a bug in IIS? Why does it provide different URLs when calling Application.Request.Url.AbsolutePath the first time, but not for any subsequent request?
Also: It doesn't matter whether the first request is for a double encoded URL or not, the second request will always be handled appropriately by IIS (or at least, as appropriate as handling double-encoded forward slashes can be). It's that very first request that is the problem.
Update
I tried a few different properties to see if one had different values on the first request:
First Request
string u = Application.Request.Url.AbsoluteUri;
"http://example.com/foo/baz/bar/"
string x = Application.Request.Url.OriginalString;
"http://example.com:80/foo/baz/bar"
string y = Application.Request.RawUrl;
"/%2ffo/baz/bar"
bool z = Application.Request.Url.IsWellFormedOriginalString();
true
The only interesting thing is that the Application.Request.RawUrl emits a single-encoded Forward slash (%2f), and translates the encoded backslash (%5c) to a forwardslash (although everything else does that as well).
The RawUrl is still partially encoded on the first request.
Second Request
string u = Application.Request.Url.AbsoluteUri;
"http://example.com//foo/baz/bar"
string x = Application.Request.Url.OriginalString;
"http://example.com:80/%2ffoo/baz/bar"
string y = Application.Request.RawUrl;
"/%2ffoo/baz/bar"
bool z = Application.Request.Url.IsWellFormedOriginalString();
false
Interesting points from the second request:
IsWellFormedOriginalString() is false. On the first request it was true.
The RawUrl is the same (potentially helpful).
The AbsoluteUri is different. On the second request, it has two forward slashes.
Update
Application.Request.ServerVariables["URL"] = /quotes/gc/v12/CMX
Application.Request.ServerVariables["CACHE_URL"] = http://example.com:80/%2ffoo/baz/bar
Open Questions
This seems like a bug in either IIS or .NET. Is it?
This only matters for the very first request made by an application after an iisreset
Besides using RawUrl (as we'd have to worry about a lot of other problems if we parsed the Raw Url instead of using the 'safe' URL provided by .NET), what other methods are there for us to handle this?
Keep in mind, the physical impact of this problem is low: For it to be an actual problem, the first request to the web server from a client would have to be for the above specific URL, and the chances of that happening are relatively low.
Request.Url can be decoded already - I wouldn't trust it for what you are doing.
See the internal details at:
Querystring with url-encoded ampersand prematurely decoded within Request.Url
The solution is to access the values directly via Request.RawUrl.
I realize your prob is with the path, but it seems the same thing is going on. Try the RawUrl - see if it works for you instead.
This really isn't an answer, but possibly a step in the right direction. I haven't had time to create a test harness to prove anything.
I followed this.PrivateAbsolutePath through Reflector and it goes on and on. There is a lot of string manipulation when it's accessed.
public string AbsolutePath
{
get
{
if (this.IsNotAbsoluteUri)
{
throw new InvalidOperationException(SR.GetString("net_uri_NotAbsolute"));
}
string privateAbsolutePath = this.PrivateAbsolutePath; //HERE
if (this.IsDosPath && (privateAbsolutePath[0] == '/'))
{
privateAbsolutePath = privateAbsolutePath.Substring(1);
}
return privateAbsolutePath;
}
}
Ok, its been a while since I've worked with a Web References. I need a refresher. I think I have about 80% of the code I need to get a response going but I'm missing something. Maybe you can help me :)
Given:
A web method called GetSomething in the list of methods when pointing to a .wsdl url.
This produces a few classes/objects:
GetSomethingRequest
GetSomethingCompletedEventHandler
GetSomethingCompletedEventArgs
myComplexType
Which I use to create this code:
void someMethodToTestResponse()
{
GetSomethingRequest request = new GetSomethingRequest();
// fill in the request
request.myComplexType.Property1 = "Blah";
request.myComplexType.Property2 = "Kachoo";
GetSomethingCompletedEventHandler handler = GetSomethingCompleted_Response;
//.... ok now what?
//handler.Invoke(???)
// at this point I'm supposed to send an object for source (request maybe?)
// and a new instance of GetSomethingCompletedEventArgs but that class is
// asking for stuff that makes me think that is not the right idea.
}
void GetSomethingCompleted_Response(object source, GetSomethingCompletedEventArgs args)
{
// get the result
var result = args.Result;
}
What am I doing wrong? What am I missing? Thanks in advance.
You don't need web service source codes. The web service can be implemented in Java. Creating service reference woks the same, as we really don't know what is on the other side.
So, try Add Service Reference in VS2008 and enter the url to working web service. VS will examine the wsdl on server and generate needed classes for you.
From than on, you just call the service as some ordinary method call. Meaning you don't have to fiddle with requests and http and such details. All that is hidden from you. Except in app.config where many WCF settings can be changed.
Ok, I figured out that I needed to find a Service type class. See this SO Post where it mentions:
private com.nowhere.somewebservice ws;
The issue was that the class they provide wasn't intellisensing for me and I figured it wasn't what I was looking for.
Here is how I would solve my problem:
blah.webservice.SomeMainServiceClass service = new SomeMainServiceClass();
GetSomethingRequest request = new GetSomethingRequest();
// fill in the request
request.myComplexType.Property1 = "Blah";
request.myComplexType.Property2 = "Kachoo";
object myResponse = service.GetSomething(request);
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).