A small update to Benjamins post. We have create a complete solution for our portals that are all running in multiportal context since version 4.x. With every webapi call we provide the current portalId within the header data like it is done with moduleId and tabId.
DotNetNuke.Web\Api\Internal\DnnContextMessageHandler.cs:
private static PortalSettings SetupPortalSettings(HttpRequestMessage request)
{
//hotfix ITM: 2015-02-06
var portalId = -1;
IEnumerable<string> headerValues;
var keyFound = request.Headers.TryGetValues("PortalId", out headerValues);
if (keyFound)
{
Int32.TryParse(headerValues.FirstOrDefault(), out portalId); ;
}
if (portalId < 0)
{
var domainName = TestableGlobals.Instance.GetDomainName(request.RequestUri);
var alias = PortalAliasController.Instance.GetPortalAlias(domainName);
portalId = alias.PortalID;
}
int tabId;
ValidateTabAndModuleContext(request, portalId, out tabId);
//hotfix end
var portalSettings = new PortalSettings(portalId);
request.GetHttpContext().Items["PortalSettings"] = portalSettings;
return portalSettings;
}
...\Library\Framework\ServicesFrameworkImpl.cs:
public void RegisterAjaxScript(Page page)
{
var path = ServicesFramework.GetServiceFrameworkRoot();
if (String.IsNullOrEmpty(path))
{
return;
}
JavaScript.RegisterClientReference(page, ClientAPI.ClientNamespaceReferences.dnn);
ClientAPI.RegisterClientVariable(page, "sf_siteRoot", path, /*overwrite*/ true);
ClientAPI.RegisterClientVariable(page, "sf_tabId", PortalSettings.Current.ActiveTab.TabID.ToString(CultureInfo.InvariantCulture), /*overwrite*/ true);
//hotfix ITM: 2015-02-06
ClientAPI.RegisterClientVariable(page, "sf_portalId", PortalSettings.Current.PortalId.ToString(CultureInfo.InvariantCulture), /*overwrite*/ true);
//hotfix end
.....
}
js\dnn.servicesframework.js (here in pretty print)
(function ($) {
$.dnnSF = function (moduleId) {
var base = this;
base.getServiceRoot = function (moduleName) {
var serviceRoot = dnn.getVar("sf_siteRoot", "/");
serviceRoot += "DesktopModules/" + moduleName + "/API/";
return serviceRoot;
};
base.getTabId = function () {
return dnn.getVar("sf_tabId", -1);
};
base.getModuleId = function () {
return moduleId;
};
//hotfix ITM: 2015-02-06
base.getPortalId = function() {
return dnn.getVar("sf_portalId", -1);
};
//hotfix end
base.setModuleHeaders = function (xhr) {
var tabId = base.getTabId();
if (tabId > -1) {
xhr.setRequestHeader("ModuleId", base.getModuleId());
xhr.setRequestHeader("TabId", tabId);
//hotfix ITM: 2015-02-06
xhr.setRequestHeader("PortalId", base.getPortalId());
//hotfix end
}
var afValue = base.getAntiForgeryValue();
if (afValue) {
xhr.setRequestHeader("RequestVerificationToken", afValue);
}
};
base.getAntiForgeryKey = function () {
return "__RequestVerificationToken";
};
base.getAntiForgeryValue = function () {
return $('[name="__RequestVerificationToken"]').val();
};
return base;
};
$.ServicesFramework = function (moduleId) {
return new $.dnnSF(moduleId);
};
})(jQuery);