Implementing a WCF Service within Orchard

Topics: Writing modules
Mar 27, 2012 at 10:07 PM

So, I've tried numerous things so far and all have failed. Rather than posting all of my source code and hacking it up, does anyone know of the easiest way to get a HelloWorld WCF service implemented in an Orchard module? I need to post data from a form to the WCF form using jQuery.

Mar 28, 2012 at 6:35 PM

So, I think I finally have some sort of structure that shows potential. However, with every GET request to my WCF method, I continually receive a 400 Bad Request. I'm not sure if it's something missing in the config and project structure or what.

My web.config for the service is stored in the same module as the service. Is that correct or should it be in the main web's web.config?

The config looks like the following:

<system.serviceModel>
    <behaviors>
        <endpointBehaviors>
            <behavior name="CustomizedAjaxBehavior">
                <enableWebScript />
                <webHttp automaticFormatSelectionEnabled="true" />
            </behavior>
        </endpointBehaviors>
        <serviceBehaviors>
            <behavior name="">
                <serviceMetadata httpGetEnabled="true" />
                <serviceDebug includeExceptionDetailInFaults="false" />
            </behavior>
        </serviceBehaviors>
    </behaviors>
    <services>
        <service name="MyModule.TestService">
            <endpoint address="" behaviorConfiguration="CustomizedAjaxBehavior" binding="webHttpBinding" contract="MyModule.Services.ITestService" />
        </service>
    </services>
</system.serviceModel>

The service looks like the following:

    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
    public class TestService : ITestService
    {
        JavaScriptSerializer _jsSerializer = new JavaScriptSerializer();

        [WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "HelloWorld")]
        public string HelloWorld(string firstName)
        {            WebOperationContext.Current.OutgoingResponse.ContentType = "text/json";
            return _jsSerializer.Serialize("Hello, " + firstName);
        }
    }

Which inherits from the following interface:

[ServiceContract(Namespace = "")]
public interface ITestService : IDependency
{
    [OperationContract(Name = "HelloWorld")]
    string HelloWorld(string firstName);
}

When I hit http://mydomain.com/Services/MyService, I get the proper WCF page. However, when I try to hit the method http://mydomain.com/Services/MyService/HelloWorld, I get the 400 Bad Request exception. I've tried this both by using a browser and by using the following jQuery:

function helloWorld() {
    var dataToPost = '{ "firstName": "Jason" }';

    $.ajax({
        cache: false,
        async: true,
        type: "GET",
        dataType: "json",
        url: "http://mydomain.com/Services/TestService/HelloWorld",
        data: dataToPost,
        contentType: "application/json;charset=utf-8",
        success: function (msg) {
            var status = JSON.parse(msg).HelloWorldResult;
            alert('Yes!');
        },
        error: function (msg) {
            alert('No!\n\n' + msg.statusText);
        }
    });
}

Thanks in advance for any pointers!

Developer
Mar 28, 2012 at 7:37 PM

Jason, you might want to look at Bertrands older post about Orchard 1.1 features - there is a description of the WCF support: http://weblogs.asp.net/bleroy/archive/2011/04/20/orchard-1-1-what-s-in-it-for-developers.aspx

Where do you have your .svc file? I guess it's needed to make everything work. Correct me please if I'm wrong.

Also regarding the Web.config - I'm pretty sure it should go to the main one.

Developer
Mar 28, 2012 at 7:48 PM
Edited Mar 28, 2012 at 7:56 PM

Ok, the .svc file is not needed, but you need to provide an appropriate ServiceRoute in your Routes.cs file.

You might find this discussion useful: http://orchard.codeplex.com/discussions/256924. There is a workaround for the problems you might run into. Btw, that workaround could also fix your previous issue with WebAPI.

EDIT This thread may also be useful: http://orchard.codeplex.com/discussions/262524

EDIT 2 Wow, I forgot about that one :) http://stackoverflow.com/questions/5795632/orchard-mvc-wcf-service-url-with-area. There are the steps you need to make in order to make everything work.

Mar 28, 2012 at 8:56 PM

Guess it would have helped for me to also post my Routes.cs. It's here:

    public class Routes : IRouteProvider {
        private static readonly ServiceRoute _testService = new ServiceRoute("Services/TestService", new OrchardServiceHostFactory(), typeof (ITestService));

        public IEnumerable<RouteDescriptor> GetRoutes()
        {
            return new[] { new RouteDescriptor { Priority = 20, Route = _testService } };
        }

        public void GetRoutes(ICollection<RouteDescriptor> routes)
        {
            foreach (var routeDescriptor in GetRoutes())
                routes.Add(routeDescriptor);
        }
    }
Mar 28, 2012 at 10:44 PM

Nice discussion.

Anyone can help on how to secure exposed wcf services in orchard, so a winforms app has to pass orchard credentials to access service?

Mar 29, 2012 at 1:52 AM

First, I'd break that into a separate thread just so it has greater exposure. Secondly, are you just looking to use Orchard's built-in authentication model? Depending on your WCF configuration (ie: REST, etc.) you can likely create a custom OrchardAuthorization attribute that requires an authorization token to be passed with the service and validate that user account within Orchard. I haven't done anything within Orchard, but I have with standard WCF services.

Check out http://msdn.microsoft.com/en-us/library/ms731925.aspx for some pointers on security with WCF.

Mar 29, 2012 at 1:53 AM
pszmyd wrote:

Ok, the .svc file is not needed, but you need to provide an appropriate ServiceRoute in your Routes.cs file.

You might find this discussion useful: http://orchard.codeplex.com/discussions/256924. There is a workaround for the problems you might run into. Btw, that workaround could also fix your previous issue with WebAPI.

EDIT This thread may also be useful: http://orchard.codeplex.com/discussions/262524

EDIT 2 Wow, I forgot about that one :) http://stackoverflow.com/questions/5795632/orchard-mvc-wcf-service-url-with-area. There are the steps you need to make in order to make everything work.

Piotr, I did post my routes. Sorry that I didn't quote you on my posting. It's the 3rd up from this one. I'm still running into 400 Bad Request errors.

Mar 29, 2012 at 2:12 AM

Try this fix.

http://orchard.codeplex.com/SourceControl/changeset/changes/e513e914ca6c

Mar 29, 2012 at 2:47 AM
ravetam wrote:

Try this fix.

http://orchard.codeplex.com/SourceControl/changeset/changes/e513e914ca6c

Tried it with no luck. Same response. I am still on v1.3 so I had to add that change in manually in case anything else in that file has changed between 1.3 and 1.4.

Developer
Mar 29, 2012 at 3:00 PM

Hey Jason, I'll try to reimplement your scenario locally and try if I run into similar problems. You're running on a clean Orchard install, or have you made any customizations that touch routing (besides adding the WCF routes)?

That sounds either as something caused by custom stuff or it may be a regression bug, because it worked before. Will check.

Mar 29, 2012 at 4:42 PM

It's a fairly clean install. The only thing I did was add a custom theme and basic content. That's it. Nothing to extend routing besides the WCF routes. I did dabble with the WebAPI routes, but I moved past that and removed that module.

Mar 30, 2012 at 3:13 PM

When i was implementing WCF Data Services, i notice it doesn't work with a .svc file. So i just rename the extension to .cs, and it works.

Developer
Apr 5, 2012 at 6:32 AM

@jgaylord Have you managed to make it work?

Apr 5, 2012 at 3:06 PM

I have not. I actually stepped away from it as I needed to get some things out the door first.

Apr 5, 2012 at 3:46 PM
Edited Apr 5, 2012 at 3:47 PM

Try this fix: http://orchard.codeplex.com/SourceControl/changeset/changes/a1f00fd194b8

This fix was required for me to get my WCF service working @ 1.4.0

Sep 10, 2012 at 8:45 AM
Edited Sep 10, 2012 at 8:45 AM

@AimOrchard The correct answer, thank you very much..