WCF REST URIs ending in %20 fail with 404 - wcf

A WCF REST web service provides a lookup in the format:
https://mysite/mycontract/search/{searchtext}
A search text of hello, or hello%20world, and the service performs correctly. However, when using text ending in whitespace as in https://mysite/mycontract/search/hello%20 the service will fail with a 404. There is no custom routing.
What limitations in wcf routing causes this, and what workarounds (ideally besides changing the uri structure) are available?
Edit w/ additional implementation info:
contract
[ServiceContract(SessionMode = SessionMode.NotAllowed)]
public interface IPointOfSale
{
.......
[WebInvoke(UriTemplate = "search/{SKU}", Method = "GET")]
System.Xml.Linq.XElement ProductLookup(string SKU);
}
method
public XElement ProductLookup(string SKU)
{
//product search here.
}

I have been working with the same issue today, and found other posts telling that, in .NET 4, the solution lies in setting the following in web.config:
<httpRuntime relaxedUrlToFileSystemMapping="true" />
This solved the problem for me!

Related

WCF RIA services and WSDL generation

Need help on an issue I am having. I inherited this WCF RIA project and am trying to understand a couple of things.
When I publish the project, how does the WSDL get generated and put on the URL that I published to?
And I want to incorporate FaultException handling so as to transmit the exceptions to the client side. I read some stuff regarding the FaultException on the web and was able to get a small sample working with the regular WCF service.
I thought it would be similar within my actual project. But unfortunately I am running into some issues(probably due to my lack of WCF + RIA services knowledge).
So in my actual project my Context class derives off of LinqToEntitiesDomainService.
I created a new ContextFaultException class which had some methods to capture some custom error messaging.
Then I applied the [FaultContract(typeof(ContextFaultException))] to some of the methods in my Context class. Everything compiles and all is fine. But when I published to a website and then when I added this service reference to the client, I don't see my new ContextFaultException in the Reference.cs file that's generated.
I thought may be moving it within the Context class will solve the issue. So I made my ContextFaultException class as an inner class of this Context class but I am running into some other issues. Before I try to figure out these issues, I just want to know if this the right approach?
Any suggestions/pointers??
TIA
The URL must be formatted to get to the namespace wdsl
for example:
namespace My.Namespace.Services
{
[EnableClientAccess()]
public partial class MyClassName : LinqToEntitiesDomainService<XXX>
{
....
}
}
Then use the following pattern for the url
http://YOURHOST/APP/Services/My-Namespace-Services-MyClassName.svc?wsdl
Use "-" for the "."

How to allow all Operations and Namespaces

I'm new to WCF, but not new to C# and .Net. and am using Visual Studio 2008 and .Net 3.5.
I'm trying to build a Web Service that can receive any inbound Request XML and any namespaces. It would behave like a transparent receiver and simply intake the inbound request XML.
Once I get the request I'm going to pass it to some custom .Net C# Project to invoke a MQPUT to IBM MQ Series.
Right now I have the WCF Web Service Application receiving a generic inbound operation called RunTest(). I consume the WSDL into SoapUI, build a sample request and breakpoint and it works. But, when I try to pass our company request XML it doesn't land on the breakpoint.
Here is the ServiceContract and Operation:
[ServiceContract(Name="IService1",Namespace="cfg-env=http://www.co.com/schemas/cfg- env/")]
//[ServiceContract]
public interface IService1
{
[OperationContract]
void RunTest();
[OperationContract]
void CFX();
Here is the Method for the Operation:
public void RunTest()
{ <<<it does break here using the request from the WSDL
string serviceName;
string queueManager;
string queue;
string requestMessage;
//Capture the Service Name
serviceName = "";
//Save the QueueManager
queueManager = "";
//Save the Request Queue
queue = "";
//Save the Message
requestMessage = "";
//Call MQ Put
Engine eng = new Engine();
try
{
eng.Put(serviceName, queue, requestMessage, queueManager);
}
The main thing I need to do is receive the inbound XML, interogate it for a few pieces of information and call this Method to do the MQPUT function on MQ.
The inbound namespace will look like the above but I'd like to ensure I can receive and interogate any XPATH that may be namespace qualified. If I have to I can work with the cfg-env namespace prefix exclusively as our services do use that as a standard.
What are my key hurdles in doing this in VS 2008 WCF? If you have any links please pass them along if you can.
I believe you specify the name property on the OperationContract attribute as "*" to accept all requests. To make the parameter itself schema agnostic, it should be of type System.ServiceModel.Channels.Message.
What you are building is a "WCF router".
Included in the latest .NET release is a configurable Routing Service.
If the routing service doesn't meet your needs, building your own router is possible but can get really complicated when secure messages are a requirement. This set of MSDN articles is the best resource. They answer your question of how to have a service accept any message, and then continue on into addressing and security issues.
Building a WCF Router, Part 1
Building a WCF Router, Part 2

How to access a Service Reference from JavaScript?

(WCFDS = WCF Data Services 5,backed by Entity Framework, using oData v3, formatted as JSON, served up via IIS7 and protected by Windows authentication.)
The crux is accessing the WCFDS in an authenticated manner from an AJAX call.
To this end, I have a client as an ASP.Net Web Application with Windows authentication set in Web.config and a Service Reference pointing to the WCFDS.
I want to use client-side JavaScript to access the Service Reference. How can I do this?
I thought about creating an aspx page, hosting in the client and direct calls from JavaScript code to this page, which would then retrieve data through the Service Reference - but I'm at a loss over how to expose the full functionality of the Service Reference in this manner (there are dozens of entities).
Can anyone help with advice?
The Windows authorization settings in web.config are not directly related to WCF Data Services, so you probably won't need to set anything there. You WILL need to set your settings up properly in IIS.
There are a number of good articles out there about using Windows authorization over WCF Data Services; in a nutshell you have a wide degree of freedom in how you choose to expose authorization (ranging from filtering out individual entities from a feed to throwing 401/403s).
A couple of good articles to read through:
http://msdn.microsoft.com/en-us/data/gg192997
http://blogs.msdn.com/b/astoriateam/archive/2010/07/21/odata-and-authentication-part-7-forms-authentication.aspx (yes, I know that's forms auth but the auth part of this is entirely orthogonal to what the code looks like in your WCF Data Services)
http://blogs.msdn.com/b/astoriateam/archive/2010/07/19/odata-and-authentication-part-5-custom-httpmodules.aspx
The simplest code you could possibly write would be something along the lines of:
namespace Scratch.Web
{
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class ScratchService : DataService<ScratchContext>
{
[QueryInterceptor("Products")]
public Expression<Func<Product, bool>> ProductsAuthorization()
{
if (!HttpContext.Current.Request.IsAuthenticated)
{
return (p) => false;
}
return (p) => HttpContext.Current.User.IsInRole("AllowAccessToProducts");
}
// ...rest of service code...
}
}
Note that everything on the client side is controlled by the browser, so you don't really need to do anything there (the biggest step might be to add the site to Trusted Sites so it doesn't prompt you for your credentials if you're on a domain-joined machine).

What can I put in the namespace for WCF?

I just started learning on WCF and is trying to create a WCF service for my client application.
From the msdn tutorial, I have went through all the individuals steps and sort of grasp how WCF works and now I am trying to start coding the service on my part. For the first step it says, defining a service contract. and the sample code msdn gives are as follows
namespace Microsoft.ServiceModel.Samples
{
class Program
{
static void Main(string[] args)
{
}
}
}
and the service contract.
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
what i would like to ask is, what can i actually substitute the namespace with since I am developing for my own application?
The namespace can be a string - typically it's a URI, like in your question, but it could also be a simple dotted namespace
[ServiceContract(Namespace = "Microsoft.ServiceModel.Samples")]
Contract namespaces are just strings to resolve possible conflicts (can be useful when versioning, for example). If you omit it your WSDL will contain http://tempuri.org. Not what you want in production. However, it's not that easy to just set proper name in ServiceContractAttribute, there are also binding and schema namespaces. For better understanding WSDL namespaces in context of WCF I highly recommend this blog post.

Why am I having so much trouble uploading a file in WCF4?

This has stumped me now for over 4 hours. I can't find a simple example anywhere?
My web application has a WCF Data Service, I would love to be able to just upload an image to a custom operation on that.
Alternatively I have WCF REST TEMPLATE SERVICE that has only a .cs, NO .config to play with and NO .svc file. It does have a route in the global.asax
// Edit the base address of Service1 by replacing the "Service1" string below
RouteTable.Routes.Add(new ServiceRoute("upload", new WebServiceHostFactory(), typeof(UploadService)));
My operation looks like this:
[WebInvoke(Method ="POST", UriTemplate = "update-pic/{id}")]
public Message UploadPic(string id, Stream fileContents)
{
System.Drawing.Image.FromStream(fileContents).Save(string.Format("{0:ddmmss}.jpg"));
return WebOperationContext.Current.CreateTextResponse("Success: " + id);
}
But no matter what I do on the client, when I call the service I get a 400 response. I could facing problems with message size limits, but I don't know how to configure this with the WCF RestTemplate style.
If I do not set the anything to the response stream, then I manage to hit the service.
Does anyone have an end to end service and client example for WCF4 - I'm not interested in 3.5