Quicksilver – ServiceApi: fixing issues

From what I heard, developers seem to love both QuickSilver – as a template – and ServiceApi – as a REST server – very much. Despite of being relatively new on the field, they are being used quite frequently – QuickSilver is the preferred choice for MVC template while many sites are using ServiceApi to update the catalogs. What’s about the combination of these two? Would it be the best-of-bread for Episerver Commerce. I would say yes, but after you have fixed the issue.

The installation of ServiceApi.Commerce package to Quicksilver site should be easy and painless. Update the database and build the project, you should be expecting to have a working site.

Note quite. You should be seeing this error:

It’s because

is called twice (as it’s called in ServiceApi as well). So naturally, let’s try by commenting that line in SiteInitalization.cs, and build it again.

This can also be solved by adding this into appSettings:

Which will signal ServiceAPI to skip calling

A new error would show up:

 

This is, again, caused by some duplication in QuickSilver and ServiceApi – the OwinStartupAttribute. We need to change this line in Startup.cs

To add the friendly name for the OwinStartupAttribute

And add this to appSettings section in web.config

Build it again. It should be working this time! No YSOD, which is good, still, there is something not working:

This error happens because GlobalConfiguration.Configure were called multiple times – both in ServiceApi and QuickSilver. The solution? This code in SiteInitialization.cs should be changed from:

To simply

Now it’s working:

Quicksilver is working, again, now with ServiceApi
Quicksilver is working, again, now with ServiceApi

Is it done? No, not yet. By configuring QuickSilver’s Startup to be run, we are surpassing the ServiceApi’s Startup. We need to include the code somehow – so we can configure the path for ServiceApi token

This needs to be in Quicksilver Startup.Configuration:

In QuickSilver 3.0+, this has been changed and should be

7 thoughts on “Quicksilver – ServiceApi: fixing issues”

  1. I have problem with Quicksilver 10.4.3 with serviceapi 3.0.
    duplicate:
    I download Quicksilver version 10.4.3 (https://github.com/episerver/Quicksilver).
    setup EpiServer.ServiceApi.Commerce and follow your guide.
    error:
    There is no configuration specified for Microsoft.Owin.Security.OAuth.IOAuthAuthorizationServerProvider
    error line: Line 89: app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
    I change:
    app.UseServiceApiMembershipTokenAuthorization(new ServiceApiTokenAuthorizationOptions
    {
    AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(60)
    });
    and use /episerverapi/token to get token return error: “Default Membership Provider must be specified.”
    client.BaseAddress = new Uri(“https://ecom4.dev.nis:433”);
    var fields = new Dictionary
    {
    { “grant_type”, “password” },
    { “username”, “sy.nguyen” },
    { “password”, “Jenny@211184” }
    };
    try
    {
    var response = client.PostAsync(“/episerverapi/token”, new FormUrlEncodedContent(fields)).Result;
    if (response.StatusCode == HttpStatusCode.OK)
    {
    var content = response.Content.ReadAsStringAsync().Result;
    token = Newtonsoft.Json.Linq.JObject.Parse(content).GetValue(“access_token”);
    }

    }
    i guess cause of problem is missing some configure. please help me. Many thanks.

    1. @Sy Nguyen: Please contact Episerver developer support service. I’d like to help, but I don’t know the problem already and this is outside my ability to spend time working on it.

  2. I added the source code into the Startup.cs as your suggestion :
    app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
    {
    AllowInsecureHttp = true,

    TokenEndpointPath = new PathString(“/episerverapi/token”),
    AccessTokenExpireTimeSpan = TimeSpan.FromMinutes(10),
    Provider = ServiceLocator.Current.GetInstance()
    });

    // token consumption
    app.UseOAuthBearerAuthentication(new OAuthBearerAuthenticationOptions());

    but the error message occurred as :

    Server Error in ‘/’ Application.

    No default Instance is registered and cannot be automatically determined for type ‘Microsoft.Owin.Security.OAuth.IOAuthAuthorizationServerProvider’

    There is no configuration specified for Microsoft.Owin.Security.OAuth.IOAuthAuthorizationServerProvider

    1.) Container.GetInstance(Microsoft.Owin.Security.OAuth.IOAuthAuthorizationServerProvider)

    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

    Exception Details: StructureMap.StructureMapConfigurationException: No default Instance is registered and cannot be automatically determined for type ‘Microsoft.Owin.Security.OAuth.IOAuthAuthorizationServerProvider’

    There is no configuration specified for Microsoft.Owin.Security.OAuth.IOAuthAuthorizationServerProvider

    1.) Container.GetInstance(Microsoft.Owin.Security.OAuth.IOAuthAuthorizationServerProvider)

    Source Error:

    Line 82: //EnableGoogleAccountLogin(app);
    Line 83:
    Line 84: app.UseOAuthAuthorizationServer(new OAuthAuthorizationServerOptions
    Line 85: {
    Line 86: AllowInsecureHttp = true,

    Source File: C:\DemoSites\Quicksilver-master – Addon\Sources\EPiServer.Reference.Commerce.Site\Infrastructure\Owin\Startup.cs Line: 84

    Stack Trace:

    [StructureMapConfigurationException: No default Instance is registered and cannot be automatically determined for type ‘Microsoft.Owin.Security.OAuth.IOAuthAuthorizationServerProvider’

    There is no configuration specified for Microsoft.Owin.Security.OAuth.IOAuthAuthorizationServerProvider

    1.) Container.GetInstance(Microsoft.Owin.Security.OAuth.IOAuthAuthorizationServerProvider)
    ]
    StructureMap.SessionCache.GetDefault(Type pluginType, IPipelineGraph pipelineGraph) in c:\BuildAgent\work\a395dbde6b793293\src\StructureMap\SessionCache.cs:63
    StructureMap.Container.GetInstance(Type pluginType) in c:\BuildAgent\work\a395dbde6b793293\src\StructureMap\Container.cs:337
    EPiServer.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType, String key) +55

    [ActivationException: Activation error occurred while trying to get instance of type IOAuthAuthorizationServerProvider, key “”]
    EPiServer.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType, String key) +156
    EPiServer.ServiceLocation.ServiceLocatorImplBase.GetInstance() +62
    EPiServer.Reference.Commerce.Site.Infrastructure.Owin.Startup.Configuration(IAppBuilder app) in C:\DemoSites\Quicksilver-master – Addon\Sources\EPiServer.Reference.Commerce.Site\Infrastructure\Owin\Startup.cs:84

    [TargetInvocationException: Exception has been thrown by the target of an invocation.]
    System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) +0
    System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) +128
    System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) +146
    Owin.Loader.c__DisplayClass12.b__b(IAppBuilder builder) +93
    Owin.Loader.c__DisplayClass1.b__0(IAppBuilder builder) +209
    Microsoft.Owin.Host.SystemWeb.OwinAppContext.Initialize(Action1 startup) +843
    Microsoft.Owin.Host.SystemWeb.OwinBuilder.Build(Action
    1 startup) +51
    Microsoft.Owin.Host.SystemWeb.OwinHttpModule.InitializeBlueprint() +101
    System.Threading.LazyInitializer.EnsureInitializedCore(T& target, Boolean& initialized, Object& syncLock, Func`1 valueFactory) +137
    Microsoft.Owin.Host.SystemWeb.OwinHttpModule.Init(HttpApplication context) +172
    System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers) +618
    System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context) +172
    System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context) +402
    System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext) +343

    [HttpException (0x80004005): Exception has been thrown by the target of an invocation.]
    System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +539
    System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +125
    System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +731

    1. In Quicksilver 3.0+ the configuration has changed, you should use this

      app.AddCmsAspNetIdentity();

      // Use cookie authentication
      app.UseCookieAuthentication(new CookieAuthenticationOptions
      {
      AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
      LoginPath = new PathString(“/util/login.aspx”),
      Provider = new CookieAuthenticationProvider
      {
      OnValidateIdentity = SecurityStampValidator.OnValidateIdentity, ApplicationUser>(
      validateInterval: TimeSpan.FromMinutes(30),
      regenerateIdentity: (manager, user) => manager.GenerateUserIdentityAsync(user))
      }
      });

      // Enable bearer token authentication using ASP.NET Identity for Service Api
      app.UseServiceApiIdentityTokenAuthorization, ApplicationUser>();

      instead

    1. I’d say probably no. It was there for a reason and we would not want it to be override-able.

      Btw – the MVC controllers work very well in Quicksilver. If you are using the controllers for C in MVC, then it should be no problem. But if you want to have some RESTful APIs built on WebAPI, then it’s another story.

  3. Hi Quan,

    today I tried checkout the latest QuickSilver from https://github.com/episerver/Quicksilver
    I installed EPiServer.ServiceApi.Commerce without any 3rd package, but always fail when try to access to https://myhost/episerverapi/token
    it often occurs when install EPiServer.ServiceApi.Commerce, for this time I also tried many time & fixed as your suggestion.
    I dont know why always feel unstable with EPiServer :), when my system is integrating with Kentico, Siteco,SharePoint,… beside EPiServer but never facing confusion issues as EPiServer even install packages of EPiServer without 3rd

    can you give me suggestion to make this more stable for any installing ?

    Thanks

Leave a Reply

Your email address will not be published. Required fields are marked *