4

DotNetNuke 6 does not appear to support WebMethods due to modules being developed as user controls, not aspx pages.

What is the recommended way to route, call and return JSON from a DNN user module to a page containing that module?

ThinkingStiff
  • 64,767
  • 30
  • 146
  • 239
jhappoldt
  • 2,406
  • 1
  • 21
  • 24

2 Answers2

4

It appears the best way to handle this problem is custom Httphandlers. I used the example found in Chris Hammonds Article for a baseline.

The general idea is that you need to create a custom HTTP handler:

<system.webServer>
  <handlers>
    <add name="DnnWebServicesGetHandler" verb="*" path="svc/*" type="Your.Namespace.Handler, YourAssembly" preCondition="integratedMode" />
  </handlers>
</system.webServer>

You also need the legacy handler configuration:

<system.web>
  <httpHandlers>
    <add verb="*" path="svc/*" type="Your.Namespace.Handler, YourAssembly" />
  </httpHandlers>
</system.web>

The handler itself is very simple. You use the request url and parameters to infer the necessary logic. In this case I used Json.Net to return JSON data to the client.

public class Handler: IHttpHandler
{
    public void ProcessRequest(HttpContext context)
    {
        //because we're coming into a URL that isn't being handled by DNN we need to figure out the PortalId
        SetPortalId(context.Request);
        HttpResponse response = context.Response;
        response.ContentType = "application/json";

        string localPath = context.Request.Url.LocalPath;
        if (localPath.Contains("/svc/time"))
        {
            response.Write(JsonConvert.SerializeObject(DateTime.Now));
        }

    }

    public bool IsReusable
    {
        get { return true; }
    }

    ///<summary>
    /// Set the portalid, taking the current request and locating which portal is being called based on this request.
    /// </summary>
    /// <param name="request">request</param>
    private void SetPortalId(HttpRequest request)
    {

        string domainName = DotNetNuke.Common.Globals.GetDomainName(request, true);

        string portalAlias = domainName.Substring(0, domainName.IndexOf("/svc"));
        PortalAliasInfo pai = PortalSettings.GetPortalAliasInfo(portalAlias);
        if (pai != null)
        {
            PortalId = pai.PortalID;
        }
    }

    protected int PortalId { get; set; }
}

A call to http://mydnnsite/svc/time is properly handled and returns JSON containing the current time.

jhappoldt
  • 2,406
  • 1
  • 21
  • 24
  • @Chris Hammond, you get a pretty thank you since you have enough points as is. – tatigo May 15 '14 at 02:32
  • Would you know why DNN 7.3.3 would be throwing 404 when I try to access ``http://mydnnsite/svc/time`` ? Could it be that this way is no longer supported ? – iiminov Feb 17 '15 at 09:55
  • I want to handle error in this case. For now as is, an alert javascript is show with html with the error throwed. Just a try catch to hide it is not very useful. So how to throw exception to display an error occured ... like a classic portalModuleException ? – Jerome2606 Mar 04 '15 at 10:17
0

does anyone else have an issue of accessing session state/updating user information via this module? I got the request/response to work, and i can access DNN interface, however, when i try to get the current user, it returns null; thus making it impossible to verify access roles.

//Always returns an element with null parameters; not giving current user
var currentUser = UserController.Instance.GetCurrentUserInfo();
xarizmat
  • 71
  • 6