Мы занимались этой проблемой некоторое время, и я вернулся к запросу в службу поддержки год назад и был можно продвинуться немного дальше, чем указано в сообщении на форуме. Мы используем CMS 11 и Commerce 13, я установил правильные пакеты ServiceApi и ServiceApi.Commerce в нужных местах и имею класс Startup.cs. Инженер из Optimizely в заявке сказал следующее:
"После некоторых раздумий внутри команды нам удалось запустить сайт. Мы увидели, что в MediaTypeFormatterCollection не было возвращено XmlFormatterType.
Пожалуйста, посмотрите прикрепленный снимок экрана и прикрепленный фрагмент кода customInit.cs."
Они предоставили этот файл, и
Код: Выделить всё
using EPiServer.Data.SchemaUpdates;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.ServiceApi;
using EPiServer.ServiceLocation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Formatting;
using System.Web;
using System.Web.Http;
namespace CMS.Ellsworth
{
[InitializableModule, ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
public class customInit : IConfigurableModule
{
///
/// Configure the IoC container before initialization.
///
///
The context on which the container can be accessed.
public void ConfigureContainer(ServiceConfigurationContext context)
{
}
///
/// Initializes this instance.
///
/// The context.
///
/// Gets called as part of the EPiServer Framework initialization sequence. Note that it will be called
/// only once per AppDomain, unless the method throws an exception. If an exception is thrown, the initialization
/// method will be called repeatedly for each request reaching the site until the method succeeds.
///
public void Initialize(InitializationEngine context)
{
GlobalConfiguration.Configure(config =>
{
config.Formatters.Add(new XmlMediaTypeFormatter());
});
}
///
/// Preloads the module.
///
/// The parameters.
///
/// This method is only available to be compatible with "AlwaysRunning" applications in .NET 4 / IIS 7.
/// It currently serves no purpose.
///
public void Preload(string[] parameters)
{ }
///
/// Resets the module into an uninitialized state.
///
/// The context.
///
///
/// This method is usually not called when running under a web application since the web app may be shut down very
/// abruptly, but your module should still implement it properly since it will make integration and unit testing
/// much simpler.
///
///
/// Any work done by as well as any code executing on should be reversed.
///
///
public void Uninitialize(InitializationEngine context)
{ }
}
}
Код: Выделить всё
EPiServer.Framework.Initialization.InitializationException: Initialize action failed for Initialize on class EPiServer.ServiceApi.IntegrationInitialization, EPiServer.ServiceApi, Version=5.6.1.0, Culture=neutral, PublicKeyToken=8fe83dea738b45b7 ---> System.ArgumentException: A route named 'MS_attributerouteWebApi' is already in the route collection. Route names must be unique.
Parameter name: name
at System.Web.Routing.RouteCollection.Add(String name, RouteBase item)
at System.Web.Http.WebHost.Routing.HostedHttpRouteCollection.Add(String name, IHttpRoute route)
at System.Web.Http.Routing.AttributeRoutingMapper.MapAttributeRoutes(HttpConfiguration configuration, IInlineConstraintResolver constraintResolver, IDirectRouteProvider directRouteProvider)
at System.Web.Http.HttpConfigurationExtensions.MapHttpAttributeRoutes(HttpConfiguration configuration)
at EPiServer.ServiceApi.IntegrationInitialization.c.b__2_0(HttpConfiguration config)
at System.Web.Http.GlobalConfiguration.Configure(Action`1 configurationCallback)
at EPiServer.ServiceApi.IntegrationInitialization.Initialize(InitializationEngine context)
at EPiServer.Framework.Initialization.Internal.ModuleNode.c__DisplayClass2_0.b__0()
at EPiServer.Framework.Initialization.Internal.ModuleNode.Execute(Action a, String key)
at EPiServer.Framework.Initialization.Internal.ModuleNode.Initialize(InitializationEngine context)
at EPiServer.Framework.Initialization.InitializationEngine.InitializeModules()
--- End of inner exception stack trace ---
at EPiServer.Framework.Initialization.InitializationEngine.InitializeModules()
at EPiServer.Framework.Initialization.InitializationEngine.ExecuteTransition(Boolean continueTransitions)
at EPiServer.Framework.Initialization.InitializationEngine.Initialize()
at EPiServer.Framework.Initialization.InitializationModule.c.b__7_0(InitializationEngine e)
at EPiServer.Framework.Initialization.InitializationModule.EngineExecute(HostType hostType, Action`1 engineAction)
at EPiServer.Framework.Initialization.InitializationModule.FrameworkInitialization(HostType hostType)
at EPiServer.Global..ctor()
at CMS.Ellsworth.EPiServerApplication..ctor()
at ASP.global_asax..ctor() in
Код: Выделить всё
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Web;
using System.Web.Http;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using Newtonsoft.Json;
namespace CMS.Ellsworth.Business.Initialization
{
[InitializableModule]
[ModuleDependency(typeof(FrameworkInitialization))]
public class WebApiConfig : IInitializableModule
{
public static string ApiRoute = "api";
public void Initialize(InitializationEngine context)
{
// Enable Web API routing
GlobalConfiguration.Configure(config =>
{
// Attribute routing
config.MapHttpAttributeRoutes();
var formatters = GlobalConfiguration.Configuration.Formatters;
var jsonFormatter = formatters.JsonFormatter;
var settings = jsonFormatter.SerializerSettings;
var enumConverter = new Newtonsoft.Json.Converters.StringEnumConverter();
jsonFormatter.SerializerSettings.Converters.Add(enumConverter);
config.Formatters.Add(new BrowserJsonFormatter());
settings.Formatting = Formatting.Indented;
config.Formatters.Remove(config.Formatters.XmlFormatter);
config.Routes.MapHttpRoute(
name: "DefaultEpiApi",
routeTemplate: ApiRoute + "/{controller}/{id}",
defaults: new {id = RouteParameter.Optional});
});
}
public void Uninitialize(InitializationEngine context)
{
}
}
public class BrowserJsonFormatter : JsonMediaTypeFormatter
{
public BrowserJsonFormatter()
{
this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
this.SerializerSettings.Formatting = Formatting.Indented;
}
public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
{
base.SetDefaultContentHeaders(type, headers, mediaType);
headers.ContentType = new MediaTypeHeaderValue("application/json");
}
}
}
Код: Выделить всё
{
"Message": "An error has occurred.",
"ExceptionMessage": "The object has not yet been initialized. Ensure that HttpConfiguration.EnsureInitialized() is called in the application's startup code after all other initialization code.",
"ExceptionType": "System.InvalidOperationException",
"StackTrace": " at System.Web.Http.Routing.RouteCollectionRoute.get_SubRoutes()\r\n at System.Web.Http.Routing.RouteCollectionRoute.GetRouteData(String virtualPathRoot, HttpRequestMessage request)\r\n at System.Web.Http.WebHost.Routing.HttpWebRoute.GetRouteData(HttpContextBase httpContext)"
}
Код: Выделить всё
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Formatting;
using System.Net.Http.Headers;
using System.Web;
using System.Web.Http;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using Newtonsoft.Json;
namespace CMS.Ellsworth.Business.Initialization
{
[InitializableModule]
[ModuleDependency(typeof(FrameworkInitialization))]
public class WebApiConfig : IInitializableModule
{
public static string ApiRoute = "api";
public void Initialize(InitializationEngine context)
{
// Enable Web API routing
GlobalConfiguration.Configure(config =>
{
// Attribute routing
// config.MapHttpAttributeRoutes();
var formatters = GlobalConfiguration.Configuration.Formatters;
var jsonFormatter = formatters.JsonFormatter;
var settings = jsonFormatter.SerializerSettings;
var enumConverter = new Newtonsoft.Json.Converters.StringEnumConverter();
jsonFormatter.SerializerSettings.Converters.Add(enumConverter);
config.Formatters.Add(new BrowserJsonFormatter());
settings.Formatting = Formatting.Indented;
config.Formatters.Remove(config.Formatters.XmlFormatter);
config.Routes.MapHttpRoute(
name: "DefaultEpiApi",
routeTemplate: ApiRoute + "/{controller}/{id}",
defaults: new { id = RouteParameter.Optional });
config.EnsureInitialized();
});
}
public void Uninitialize(InitializationEngine context)
{
}
}
public class BrowserJsonFormatter : JsonMediaTypeFormatter
{
public BrowserJsonFormatter()
{
this.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
this.SerializerSettings.Formatting = Formatting.Indented;
}
public override void SetDefaultContentHeaders(Type type, HttpContentHeaders headers, MediaTypeHeaderValue mediaType)
{
base.SetDefaultContentHeaders(type, headers, mediaType);
headers.ContentType = new MediaTypeHeaderValue("application/json");
}
}
}
using System.Net.Http.Formatting;
using System.Web.Http;
using EPiServer.Framework;
using EPiServer.Framework.Initialization;
using EPiServer.ServiceLocation;
namespace CMS.Ellsworth.Infrastructure
{
[InitializableModule, ModuleDependency(typeof(EPiServer.Web.InitializationModule))]
public class ServiceInit : IConfigurableModule
{
///
/// Configure the IoC container before initialization.
///
///
The context on which the container can be accessed.
public void ConfigureContainer(ServiceConfigurationContext context)
{
}
///
/// Initializes this instance.
///
/// The context.
///
/// Gets called as part of the EPiServer Framework initialization sequence. Note that it will be called
/// only once per AppDomain, unless the method throws an exception. If an exception is thrown, the initialization
/// method will be called repeatedly for each request reaching the site until the method succeeds.
///
public void Initialize(InitializationEngine context)
{
GlobalConfiguration.Configure(config =>
{
config.Formatters.Add(new XmlMediaTypeFormatter());
config.EnsureInitialized();
});
}
///
/// Preloads the module.
///
/// The parameters.
///
/// This method is only available to be compatible with "AlwaysRunning" applications in .NET 4 / IIS 7.
/// It currently serves no purpose.
///
public void Preload(string[] parameters)
{
}
///
/// Resets the module into an uninitialized state.
///
/// The context.
///
///
/// This method is usually not called when running under a web application since the web app may be shut down very
/// abruptly, but your module should still implement it properly since it will make integration and unit testing
/// much simpler.
///
///
/// Any work done by as well as any code executing on should be reversed.
///
///
public void Uninitialize(InitializationEngine context)
{
}
}
}
Наконец, если я добавлю обратно в config.MapHttpAttributeRoutes (); в WebApiConfig.cs я получаю следующую ошибку: Я также могу подтвердить, что в базе кода больше нигде не вызывается этот метод или не выполняется подобное сопоставление маршрутов. Я даже закомментировал RouteRegister в Global.asax.cs.
Код: Выделить всё
EPiServer.Framework.Initialization.InitializationException: Initialize action failed for Initialize on class EPiServer.ServiceApi.IntegrationInitialization, EPiServer.ServiceApi, Version=5.6.1.0, Culture=neutral, PublicKeyToken=8fe83dea738b45b7 ---> System.ArgumentException: A route named 'MS_attributerouteWebApi' is already in the route collection. Route names must be unique.
Parameter name: name
at System.Web.Routing.RouteCollection.Add(String name, RouteBase item)
at System.Web.Http.WebHost.Routing.HostedHttpRouteCollection.Add(String name, IHttpRoute route)
at System.Web.Http.Routing.AttributeRoutingMapper.MapAttributeRoutes(HttpConfiguration configuration, IInlineConstraintResolver constraintResolver, IDirectRouteProvider directRouteProvider)
at System.Web.Http.HttpConfigurationExtensions.MapHttpAttributeRoutes(HttpConfiguration configuration)
at EPiServer.ServiceApi.IntegrationInitialization.c.b__2_0(HttpConfiguration config)
at System.Web.Http.GlobalConfiguration.Configure(Action`1 configurationCallback)
at EPiServer.ServiceApi.IntegrationInitialization.Initialize(InitializationEngine context)
at EPiServer.Framework.Initialization.Internal.ModuleNode.c__DisplayClass2_0.b__0()
at EPiServer.Framework.Initialization.Internal.ModuleNode.Execute(Action a, String key)
at EPiServer.Framework.Initialization.Internal.ModuleNode.Initialize(InitializationEngine context)
at EPiServer.Framework.Initialization.InitializationEngine.InitializeModules()
Подробнее здесь: https://stackoverflow.com/questions/786 ... ce-13-site