2017-08-23 8 views
0

Ich bin neu. ASP.net Kern. Ich teste einen Controller, der eine Ansicht auf einen String rendert und dann evo pdf verwendet, um die Ansicht zu rendern.Asp.Net Core 2.0 Xunit Tests

Alles funktioniert perfekt und ich bin auch in der Lage, mit Postboten erfolgreich zu testen. Allerdings meine Test-App-Fehler, wenn ich vs 2017 Test Explorer verwenden, um meinen Test (Xunit) zu debuggen. Searched Locations within the razor engine Der Fehler tritt innerhalb meiner RenderViewToString -Methode auf, da meine Rasierer-Ansichts-Engine die zu rendernde Ansicht nicht finden kann. Die Pfade, die gesucht werden, um die Ansichten zu finden, sind wie erwartet. Jede Anleitung wird geschätzt.

//Unit Test Code 
    [Fact] 
    public async void GetPdf() 
    { 
     var response = await _client.PostAsJsonAsync<Common.DTO.Invoice>("/api/values/1", GetDummyData()); 

     using (var file = System.IO.File.Create(@"c:\\Test" + DateTime.Now.ToString("yyyyyMMddHHmmss") + ".pdf")) 
      { 
      //create a new file to write to 
      await response.Content.CopyToAsync(file); 
      await file.FlushAsync(); // flush back to disk before disposing 
      } 


    } 

    //Render view to string service 
    public interface IViewRenderService 
    { 
    Task<string> RenderToStringAsync(string viewName, ViewDataDictionary viewData); 
    } 
    public class ViewRenderService : IViewRenderService 
    { 
    private readonly IRazorViewEngine _razorViewEngine; 
    private readonly ITempDataProvider _tempDataProvider; 
    private readonly IServiceProvider _serviceProvider; 

    public ViewRenderService(IRazorViewEngine razorViewEngine,ITempDataProvider tempDataProvider,IServiceProvider serviceProvider) 
    { 
     _razorViewEngine = razorViewEngine; 
     _tempDataProvider = tempDataProvider; 
     _serviceProvider = serviceProvider; 
    } 

    public async Task<string> RenderToStringAsync(string viewName, ViewDataDictionary viewData) 
    { 
     var httpContext = new DefaultHttpContext { RequestServices = _serviceProvider }; 
     var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); 

     using (var sw = new StringWriter()) 
     { 
      var viewResult = _razorViewEngine.FindView(actionContext, viewName, false); 

      if (viewResult.View == null) 
      { 
       throw new ArgumentNullException($"{viewName} does not match any available view"); 
      } 


      var viewContext = new ViewContext(
       actionContext, 
       viewResult.View, 
       viewData, 
       new TempDataDictionary(actionContext.HttpContext, _tempDataProvider), 
       sw, 
       new HtmlHelperOptions() 
      ); 

      await viewResult.View.RenderAsync(viewContext); 
      return sw.ToString(); 
     } 
    } 

    } 

Antwort

0

Ich bekam den gleichen Fehler mit Core 2.0. Das Problem ist RazorViewEngine funktioniert nicht wie erwartet mit leeren RouteData Objekt;

Also ich injiziert IHttpContextAccessor und habe HttpContext und RouteData daraus;

Startup.cs:

public void ConfigureServices(IServiceCollection services) 
    { 
     services.AddScoped<IViewRenderService, ViewRenderService>(); 
     services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>(); 
     services.AddMvc(); 
    } 

RazorToStringHelper.cs:

public interface IViewRenderService 
{ 
    Task<string> RenderToStringAsync(string viewName, object model); 
} 

public class ViewRenderService : IViewRenderService 
{ 
    private readonly IRazorViewEngine _razorViewEngine; 
    private readonly ITempDataProvider _tempDataProvider; 
    private readonly IHttpContextAccessor _httpContextAccessor; 

    public ViewRenderService(
     IRazorViewEngine razorViewEngine, 
     IHttpContextAccessor httpContextAccessor, 
     ITempDataProvider tempDataProvider) 
    { 
     _razorViewEngine = razorViewEngine; 
     _tempDataProvider = tempDataProvider; 
     _httpContextAccessor = httpContextAccessor; 
    } 

    public async Task<string> RenderToStringAsync(string viewName, object model) 
    { 
     var httpContext = _httpContextAccessor.HttpContext; 

     var actionContext = new ActionContext(httpContext, httpContext.GetRouteData(), new ActionDescriptor()); 

     var viewResult = _razorViewEngine.FindView(actionContext, viewName, false); 

     if (viewResult.View == null) 
     { 
      throw new ArgumentNullException($"{viewName} does not match any available view"); 
     } 

     using (var sw = new StringWriter()) 
     { 
      var viewDictionary = new ViewDataDictionary(new EmptyModelMetadataProvider(), new ModelStateDictionary()) 
      { 
       Model = model 
      }; 

      var viewContext = new ViewContext(
       actionContext, 
       viewResult.View, 
       viewDictionary, 
       new TempDataDictionary(actionContext.HttpContext, _tempDataProvider), 
       sw, 
       new HtmlHelperOptions() 
      ); 

      await viewResult.View.RenderAsync(viewContext); 
      return sw.ToString(); 
     } 
    } 

} 
+0

Vielen Dank für die Informationen werde ich dies versuchen. –

Verwandte Themen