Search code examples
c#asp.netdotnetnukedotnetnuke-module

DNN 6 Module - How to leverage asynchronous calls


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?


Solution

  • 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.