3

I am trying to deploy a nopCommerce application to AppHarbor.

When I start the page I run into a runtime redirect loop however. I added a bit of debug logging and the problem seems to be this part in Global.asax.cs -> EnsureDatabaseIsInstalled():

if (!webHelper.GetThisPageUrl(false).StartsWith(installUrl, StringComparison.InvariantCultureIgnoreCase))
            {
                this.Response.Redirect(installUrl);
            }

StartsWith comparison is always false because GetThisPageUrl returns http://[name].apphb.com:14275/install

and installUrl (via GetStoreLocation) returns http://[name].apphb.com/install

Has anyone been able to make nopCommerce work with AppHarbor at all?

chg
  • 106
  • 1
  • 7

2 Answers2

6

It looks like you will need to modify nopCommerce to omit the port number. I took a quick look at the source and there seems to be two possible solutions:

1) Changing the boolean argument from false to true in the EnsureDatabaseIsInstalled method should cause the GetThisPageUrl method to pick a different branch that generates the URL without the port number.

2) Updating the else branch in the GetThisPageUrl method (of "WebHelper.cs") to ignore the port number.

It's easier to pick the first solution, but patching the issue at its core will be better so you don't run into similar issues.

Troels Thomsen
  • 11,361
  • 4
  • 28
  • 29
  • I removed the port via regex thanks for the suggestion. Fixes this issue but there are about a dozen others. I think I'm going to abort the experiment with Nop on AppHarbor – chg Dec 26 '11 at 10:34
2

In addition to @TroelsThomsen fix, we use a wrapper in our base controller to ensure that all of our code is oblivious to appharbor port changing.

First, @TroelsThomsen fix in Webhelper.cs:75

public virtual string GetThisPageUrl(bool includeQueryString, bool useSsl)
        {
            string url = string.Empty;
            if (_httpContext == null)
                return url;

            if (includeQueryString)
            {
                string storeHost = GetStoreHost(useSsl);
                if (storeHost.EndsWith("/"))
                    storeHost = storeHost.Substring(0, storeHost.Length - 1);
                url = storeHost + _httpContext.Request.RawUrl;
            }
            else
            {
#if DEBUG
                var uri = _httpContext.Request.Url;

#else
                //Since appharbor changes port number due to multiple servers, we need to ensure port = 80 as in AppHarborRequesWrapper.cs
                var uri = new UriBuilder
                {
                    Scheme = _httpContext.Request.Url.Scheme,
                    Host = _httpContext.Request.Url.Host,
                    Port = 80,
                    Path = _httpContext.Request.Url.AbsolutePath,
                    Fragment = _httpContext.Request.Url.Fragment,
                    Query = _httpContext.Request.Url.Query.Replace("?", "")
                }.Uri;
#endif
                url = uri.GetLeftPart(UriPartial.Path);
            }
            url = url.ToLowerInvariant();
            return url;
        }

So what we did is simply add files from https://gist.github.com/1158264 into Nop.Core\AppHarbor

and modified base controllers:

  • nopcommerce\Presentation\Nop.Web\Controllers\BaseNopController.cs

    public class BaseNopController : Controller
    {
        protected override void Initialize(RequestContext requestContext)
        {
            //Source: https://gist.github.com/1158264
            base.Initialize(new RequestContext(new AppHarborHttpContextWrapper(System.Web.HttpContext.Current),
                                               requestContext.RouteData));
        }
        //Same file from here downwards...
    }
    
  • nopcommerce\Presentation\Nop.Web.Admin\Controllers\BaseNopController.cs

    public class BaseNopController : Controller
    {
    protected override void Initialize(System.Web.Routing.RequestContext requestContext)
    {
        //set work context to admin mode
        EngineContext.Current.Resolve<IWorkContext>().IsAdmin = true;
    
        //Source: https://gist.github.com/1158264
        base.Initialize(new RequestContext(new AppHarborHttpContextWrapper(System.Web.HttpContext.Current), requestContext.RouteData));
    
        //base.Initialize(requestContext);
    }
        //Same file from here downwards...
    }
    
Korayem
  • 12,108
  • 5
  • 69
  • 56