Getting a WCF service to map POST'd parameters to arguments - wcf

I have a legacy service I'm looking to update to WCF and one of it's behaviours is to allow clients to POST a request that has something like:
MyService.asmx/ProcessDocument
With Post data looking like:
request=<big block of xml>
Now in the ASMX days this service accepted a single string parameter i.e:
public void ProcessDocument(string request) {
}
So far I have only gotten this to work in WCF by using a Stream as of the advice in this post here:
http://www.dennydotnet.com/post/2008/09/16/WCF-REST-and-POST-Lets-Dance!.aspx
A Stream will work, there are just more steps involved to make it work for something that seems to it should be supported out of the box.
I am pretty new to WCF - what am I missing?

OK, this sample got me to most of where I needed to go:
http://msdn.microsoft.com/en-us/library/bb943485.aspx
I now have it working as required.

Related

WCF Rest Service, Request Handling

I have a WCF service using webHTTPBinding. The service can be consumed by a client using some C# program or JavaScript.
The service is running fine and also working exactly I wanted. One of the method in service looks like
public string JSONGetSomedata(List<MyCustomObject> item)
{
// some code here, which is working fine....
}
When this service is accessed using a client or JavaScript, It works fine provided that I'm passing passing data to method as expected.
Now, The case where I'm consuming mentioned service using JavaScript, if I pass nothing or pass item=123 then request does not reach to WCF method at all. And it throws error like
Is there any way by which I can return some friendly error or other Json/XML data...?
I'm not sure how to do it...
Note here that, I'm looking for solution on how to return Json/HTML instead of this error message.

WCF receiving data over querystring

I am looking to integrate SignalR (.net 4.0) and Sharepoint 2010 (.net 3.5 together).
For this to work, I need a WCF server, which can recieve data posted over a querystring. What would be my best WCF option here in terms of binding? I need to post data over a querystring.
I've actually never head of anyone doing that. Is there a reason you have to use WCF? I would think something like ASP.NET MVC 4's Web API would work better.
If you are using the query string, that means it isn't SOAP, and so you can't use the basicHttpBinding or wsHttpBinding.
webHttpBinding might work for you. And depending on how it is hosted, you might see if there is a current web Request object you can get at.
Edit:
Actually, this might help too: Making a WCF Web Service work with GET requests
And with webHttpBinding, you can specify a URL Template like this:
[OperationContract]
[WebGet(UriTemplate = "/url/{one}?two={two}&three={three}")]
object GetStuff(string one, int two, string three);
assuming you know all the query string parameters.

Force WCF to call a method on every request before entering actual function

I have a RESTful WCF service with many different functions. For each function I need to call an authentication method that I have written. I can manually call this method on every request but I was looking for a way to force the WCF engine to call this method before these functions are entered. Does anyone know if this is possible?
Cheers
You could use the "Custom Behavior" approach.
You would need to write a Class that implements IDispatchMessageInspector. The following MSDN magazine article gives a nice explanation of this: Extending WCF with Custom Behaviors (link points to Wayback Machine cached copy; downloads likely don't work).
To force WCF REST Service to first call a method especially if it's for authorization
customize/override CheckAccessCore method of System.ServiceModel.ServiceAuthorizationManager
refer: http://msdn.microsoft.com/en-us/library/ms731774(v=vs.110).aspx
If it's for authorization, can't you use the built in services?
For instance, there is the PrincipalPermission attribute. Does that help in your case?
You could think about creating a WCF routing service. You would call a fixed endpoint - your authentication method - and then from there on, route your calls to the actual methods, based on some indication in the request.
For .NET 4, the Routing Service functionality will be included into WCF out of the box.
What I don't know is how that all matches REST, though.
I came across this post, while searching for the same thing.None of the answer's were simple/quick solution so if you just want a function to be called before every method then you can do what i just did:
I created a zero argument constructor:
public class myService : ImyService
{
myService ()
{
ConnectToDatabAse();
FunctionYouWantToCallBeforeEveryMethodCall();
//Add here more
}
}

Type 'System.Web.HttpRequest' cannot be serialized

I am trying to design an Picture Upload feature into a web site.
I am using ASP.NET 3.5, C#, and WCF.
I have been asked to accomplish the following:
1) Make the Uploader a Web Service
2) Return progress updates to the user as files are uploaded.
3) Log other relevant user-selected options in the database.
So, I have started off by creating a WCF web client with the
below service contract:
IService.UploadPictures(HttpRequest request);
private UploadServiceClient upload;
protected void Page_Load(object sender, EventArgs e)
{
upload = new UploadServiceClient();
upload.UploadPictures(Request.Files);
}
When I compile, I get the below error:
Type 'System.Web.HttpRequest' cannot
be serialized. Consider marking it
with the DataContractAttribute, and
marking all of its members you want
serialized with the
DataMemberAttribute attribute.
So, I went back into my service contract and
changed [OperationContract] to [DataContract]
but the change produced the same error.
Can somebody kindly tell me what I am doing wrong
and provide examples as to how to best move forward?
Thanks for your time.
You cannot use something like a HttpRequest as a WCF parameter. The error messages says it all - the HttpRequest is not serializable, and in order to work with WCF, types have to be serializable.
Also, you need to remember: you're not just passing an object instance to a method here - what you're really doing is having the WCF runtime serialize your request (the method name to call plus all the parameters passed in) into a message (think: e-mail or xml file), sending it to the server, deserialising there and building up a new copy of the given datatype (as defined in your DataContract), and doing something with it.
Your WCF service could well be self-hosted, e.g. running in a NT Service or console app - no HttpRequest available in those circumstances!
You need to definitely rearchitect your solution - you need to either check into WCF streaming to upload files to WCF (google for it - you'll find plenty of hits) or you'll need to find another way to pass the relevant info (e.g. list of filenames) to the WCF service without use of a HttpRequest object.
Marc
You are submitting a request as a parameter to a request. This is not what you want to do. I'm assuming that "Request.Files" is an array of files. This is what you want to upload. So something like:
IService.UploadPictures(List<SomeFileType> request);

View underlying SOAP message using vb.net

I have a VB.NET web service that calls a third party web service. How can I view the SOAP message generated by .NET before it is sent to the third party web service and how can I see the SOAP response before it is serialized by .NET.
When creating a standalone EXE, I see the Reference.vb file that is automatically generated, but don't see a similar file when my project is a web service. I have found lots of C# code to do this, but none in VB.NET.
Edit - Fiddler and TCP loggers are great, but will not work for my purposes. I need to be able to access the raw SOAP messages from within the application so I can log them or modify them. I need to do more than just see the messages going back and forth.
You can use fiddler or a tcp sniffer to filter and identify all outgoing and incoming traffic on your host.
This is if you want to see the xml request and response.
How about using an extension to allow you to examine the SOAP message?
Accessing Raw SOAP Messages in ASP.NET Web Services
http://msdn.microsoft.com/en-us/magazine/cc188761.aspx
I was trying to do the same thing and this seems to work for me:
Dim message As String = OperationContext.Current.RequestContext.RequestMessage.ToString()
I didn't think it would be that easy since most of the time ToString() returns the name of the class, but I tried it out and low and behold.
I know you asked this back in January so if since then you've figured out a better way let me know.
Please note that if you're catching the exception in a class that implements IErrorHandler then you have to perform this operation from within the ProvideFault() method instead of the HandleError() method because the context is closed before it gets to call the HandleError() method.
Hope this helps.