2016-11-22 2 views
1

ソースを公開:https://gist.github.com/sniffdk/7600822System.ArgumentNullException:値をnullにすることはできません - UmbracoのHttpContextを上保存し、

次のコードは、httpリクエストの外での活動によって運営されているので、私はHTTPコンテキストをモックする必要があります。

私はそうのようなHTTPコンテキストを嘲笑している:

public class GetUmbracoServiceMockedHttpContext : IGetUmbracoService 
{ 
    private UmbracoHelper umbracoHelper; 

    public T GetService<T>() 
     where T : IService 
    { 
     UmbracoContext context = UmbracoContext.Current; 

     if (context == null) 
     { 
      var dummyHttpContext = new HttpContextWrapper(new HttpContext(new SimpleWorkerRequest("blah.aspx", "", new StringWriter()))); 
      context = UmbracoContext.EnsureContext(
       dummyHttpContext, 
       ApplicationContext.Current, 
       new WebSecurity(dummyHttpContext, ApplicationContext.Current), 
       UmbracoConfig.For.UmbracoSettings(), 
       UrlProviderResolver.Current.Providers, 
       false); 
     } 

     var serviceTypeProperty = context.Application.Services 
      .GetType() 
      .GetProperties() 
      .SingleOrDefault(x => x.PropertyType == typeof(T)); 

     if (serviceTypeProperty == null) 
     { 
      return default(T); 
     } 

     return (T)serviceTypeProperty 
      .GetValue(context.Application.Services); 
    } 
} 

私はコントローラにこのIGetUmbracoService serviceを注入して呼び出します。

service.GetService<IContentService>().SaveAndPublishWithStatus(item); 

...次のエラーが発生します。

System.ArgumentNullException:値にnullを設定することはできません。パラメータ名: Umbraco.Web.RequestLifespanMessagesFactory.Get()で Umbraco.Web.SingletonHttpContextAccessor.get_Value()でSystem.Web.HttpContextWrapper..ctor(のHttpContext のHttpContext)で のHttpContextをで Umbraco.Core.Services.ContentService Umbraco.Core.ServicesでUmbraco.Core.Services.ContentService.Umbraco.Core.Services.IContentServiceOperations.SaveAndPublish(IContent コンテンツ、のInt32にuserId、ブールraiseEvents)で.SaveAndPublishDo(IContent コンテンツ、のInt32にuserId、ブールraiseEvents) .ContentService.SaveAndPublishWithStatus(IContent コンテンツ、Int32 userId、ブールraiseEvents)

frowned upon HttpContext.Current = ...を使用せずにhttpコンテキストをモックするにはどうすればよいですか?


私は、関連する問題がから来ていると仮定します。

今度はこれの実装を呼び出している

RequestLifespanMessagesFactory.cs

SingletonHttpContextAccessor.cs

答えて

0

ありがとうuser369142

また、SaveandPublish呼び出しでイベントが発生していないことを確認しなければなりませんでした.HttpContextはコンテキストに登録されたメッセージが存在すると予想していますが、私たちは気にしません。 .. raiseイベントが偽であることを確認した場合は、それを気にするコードをスキップします。

public class CustomSingletonHttpContextAccessor : IHttpContextAccessor 
{ 
    public HttpContextBase Value 
    { 
     get 
     { 
      HttpContext context = HttpContext.Current; 
      if (context == null) 
      { 
       context = new HttpContext(new HttpRequest(null, "http://mockurl.com", null), new HttpResponse(null)); 
      } 

      return new HttpContextWrapper(context); 
     } 
    } 
} 

public class CustomRequestLifespanMessagesFactory : IEventMessagesFactory 
{ 
    private readonly IHttpContextAccessor _httpAccessor; 

    public CustomRequestLifespanMessagesFactory(IHttpContextAccessor httpAccessor) 
    { 
     if (httpAccessor == null) 
     { 
      throw new ArgumentNullException("httpAccessor"); 
     } 

     _httpAccessor = httpAccessor; 
    } 

    public EventMessages Get() 
    { 
     if (_httpAccessor.Value.Items[typeof(CustomRequestLifespanMessagesFactory).Name] == null) 
     { 
      _httpAccessor.Value.Items[typeof(CustomRequestLifespanMessagesFactory).Name] = new EventMessages(); 
     } 

     return (EventMessages)_httpAccessor.Value.Items[typeof(CustomRequestLifespanMessagesFactory).Name]; 
    } 
} 

public class CustomBootManager : WebBootManager 
{ 
    public CustomBootManager(UmbracoApplicationBase umbracoApplication) 
     : base(umbracoApplication) 
    { 
    } 

    protected override ServiceContext CreateServiceContext(DatabaseContext dbContext, IDatabaseFactory dbFactory) 
    { 
     //use a request based messaging factory 
     var evtMsgs = new CustomRequestLifespanMessagesFactory(new CustomSingletonHttpContextAccessor()); 

     return new ServiceContext(
      new RepositoryFactory(ApplicationCache, ProfilingLogger.Logger, dbContext.SqlSyntax, UmbracoConfig.For.UmbracoSettings()), 
      new PetaPocoUnitOfWorkProvider(dbFactory), 
      new FileUnitOfWorkProvider(), 
      new PublishingStrategy(evtMsgs, ProfilingLogger.Logger), 
      ApplicationCache, 
      ProfilingLogger.Logger, 
      evtMsgs); 
    } 
} 

public class CustomUmbracoApplication : Umbraco.Web.UmbracoApplication 
{ 
    ... 
    protected override IBootManager GetBootManager() 
    { 
     return new CustomBootManager(this); 
    } 
    ... 
} 
1

私はUmbracoでいくつかの仕事をしてくれましたコンソールアプリケーションから実行し、Umbraco APIを使用してUmbracoを呼び出します。 私はこのプロジェクトに基づいていると信じています:https://github.com/sitereactor/umbraco-console-example

役に立つかもしれません。

+0

特に問題に関連すると思われるものは何ですか?私はここで私の問題に関連して何かを見つけることができません...私は彼らがセーブコマンドを使用することに気づいたが。 – Jimmyt1988

+1

その全体のプロジェクトは、HttpContextなしでUmbraco APIを実行するための大きな回避策/解決策です。したがって、「通常の」UmbracoApplicationBaseを拡張するConsoleApplicationBaseのようなクラスを見ると、これに必要なものがかなりあります私は、HttpContextを嘲笑するだけの単純ではないことを示唆しています。 Umbraco APIを使用して現在のコンテンツ(Umbracoの自動化されたアップグレードツールで使用)に対して作業することができたコンソールアプリケーションは、上記のプロジェクトをベースとして使用していました。 – user369142

+0

ああ、ありがとう。あなたがUmbracoApplicationBaseから継承した事実は、独自のBootManagerを返すことができ、CreateServiceContextをオーバーライドできることを意味します。 – Jimmyt1988

関連する問題