Communication is working, showing generic error, showing simple preview
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
|
||||
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
using QuestPDF.Previewer;
|
||||
|
||||
namespace QuestPDF.UnitTests
|
||||
{
|
||||
public class PreviewerTests
|
||||
{
|
||||
[Test]
|
||||
public void SendError()
|
||||
{
|
||||
Document
|
||||
.Create(container =>
|
||||
{
|
||||
container.Page(page =>
|
||||
{
|
||||
page.Size(PageSizes.A4);
|
||||
page.Margin(2, Unit.Centimetre);
|
||||
page.PageColor(Colors.White);
|
||||
page.DefaultTextStyle(x => x.FontSize(20));
|
||||
|
||||
page.Header()
|
||||
.Text("Hello PDF!")
|
||||
.SemiBold().FontSize(36).FontColor(Colors.Blue.Medium);
|
||||
|
||||
page.Content()
|
||||
.PaddingVertical(1, Unit.Centimetre)
|
||||
.Column(x =>
|
||||
{
|
||||
x.Spacing(20);
|
||||
|
||||
x.Item().Text(Placeholders.LoremIpsum());
|
||||
x.Item().Image(Placeholders.Image(200, 100));
|
||||
});
|
||||
|
||||
page.Footer()
|
||||
.AlignCenter()
|
||||
.Text(x =>
|
||||
{
|
||||
//throw new Exception("Dupa!");
|
||||
x.Span("Page ");
|
||||
x.CurrentPageNumber();
|
||||
});
|
||||
});
|
||||
})
|
||||
.ShowInPreviewer();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,108 +0,0 @@
|
||||
using System;
|
||||
using QuestPDF.Drawing;
|
||||
using QuestPDF.Fluent;
|
||||
using QuestPDF.Helpers;
|
||||
using QuestPDF.Infrastructure;
|
||||
using SkiaSharp;
|
||||
|
||||
namespace QuestPDF.Previewer
|
||||
{
|
||||
public class ExceptionDocument : IDocument
|
||||
{
|
||||
private Exception Exception { get; }
|
||||
|
||||
public ExceptionDocument(Exception exception)
|
||||
{
|
||||
Exception = exception;
|
||||
}
|
||||
|
||||
public DocumentMetadata GetMetadata()
|
||||
{
|
||||
return DocumentMetadata.Default;
|
||||
}
|
||||
|
||||
public void Compose(IDocumentContainer document)
|
||||
{
|
||||
document.Page(page =>
|
||||
{
|
||||
page.ContinuousSize(PageSizes.A4.Width);
|
||||
page.Margin(50);
|
||||
page.DefaultTextStyle(x => x.FontSize(16));
|
||||
|
||||
page.Foreground().PaddingTop(5).Border(10).BorderColor(Colors.Red.Medium);
|
||||
|
||||
page.Header()
|
||||
.ShowOnce()
|
||||
.PaddingBottom(5)
|
||||
.Row(row =>
|
||||
{
|
||||
row.Spacing(15);
|
||||
|
||||
row.AutoItem()
|
||||
.PaddingTop(15)
|
||||
.Width(48)
|
||||
.AspectRatio(1)
|
||||
.Canvas((canvas, size) =>
|
||||
{
|
||||
const float iconSize = 24;
|
||||
using var iconPath = SKPath.ParseSvgPathData("M23,12L20.56,14.78L20.9,18.46L17.29,19.28L15.4,22.46L12,21L8.6,22.47L6.71,19.29L3.1,18.47L3.44,14.78L1,12L3.44,9.21L3.1,5.53L6.71,4.72L8.6,1.54L12,3L15.4,1.54L17.29,4.72L20.9,5.54L20.56,9.22L23,12M20.33,12L18.5,9.89L18.74,7.1L16,6.5L14.58,4.07L12,5.18L9.42,4.07L8,6.5L5.26,7.09L5.5,9.88L3.67,12L5.5,14.1L5.26,16.9L8,17.5L9.42,19.93L12,18.81L14.58,19.92L16,17.5L18.74,16.89L18.5,14.1L20.33,12M11,15H13V17H11V15M11,7H13V13H11V7");
|
||||
|
||||
using var paint = new SKPaint()
|
||||
{
|
||||
Color = SKColors.Red,
|
||||
IsAntialias = true
|
||||
};
|
||||
|
||||
canvas.Scale(size.Width / iconSize);
|
||||
canvas.DrawPath(iconPath, paint);
|
||||
});
|
||||
|
||||
row.RelativeItem()
|
||||
.Column(column =>
|
||||
{
|
||||
column.Item().Text("Exception").FontSize(36).FontColor(Colors.Red.Medium).Bold();
|
||||
column.Item().PaddingTop(-10).Text("Don't panic! Just analyze what's happened...").FontSize(18).FontColor(Colors.Red.Medium).Bold();
|
||||
});
|
||||
});
|
||||
|
||||
page.Content().PaddingVertical(20).Column(column =>
|
||||
{
|
||||
var currentException = Exception;
|
||||
|
||||
while (currentException != null)
|
||||
{
|
||||
column.Item()
|
||||
.PaddingTop(25)
|
||||
.PaddingBottom(15)
|
||||
|
||||
.Padding(-10)
|
||||
.Background(Colors.Grey.Lighten3)
|
||||
.Padding(10)
|
||||
|
||||
.Text(text =>
|
||||
{
|
||||
text.DefaultTextStyle(x => x.FontSize(16));
|
||||
|
||||
text.Span(currentException.GetType().Name + ": ").Bold();
|
||||
text.Span(currentException.Message);
|
||||
});
|
||||
|
||||
foreach (var trace in currentException.StackTrace.Split('\n'))
|
||||
{
|
||||
column
|
||||
.Item()
|
||||
.ShowEntire()
|
||||
.BorderBottom(1)
|
||||
.BorderColor(Colors.Grey.Lighten2)
|
||||
.PaddingVertical(5)
|
||||
.Text(trace.Trim())
|
||||
.FontSize(12);
|
||||
}
|
||||
|
||||
currentException = currentException.InnerException;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace QuestPDF.Previewer;
|
||||
|
||||
internal static class Helpers
|
||||
{
|
||||
public static Task<HttpResponseMessage> PostAsJsonAsync<TValue>(this HttpClient client, string? requestUri, TValue value, JsonSerializerOptions? options = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var json = JsonSerializer.Serialize(value);
|
||||
var jsonContent = new StringContent(json, Encoding.UTF8, "application/json");
|
||||
|
||||
return client.PostAsync(requestUri, jsonContent, cancellationToken);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
#if NET6_0_OR_GREATER
|
||||
#if NETCOREAPP3_0_OR_GREATER
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -11,12 +11,12 @@ namespace QuestPDF.Previewer
|
||||
{
|
||||
public static class Extensions
|
||||
{
|
||||
public static void ShowInPreviewer(this IDocument document, int port = 12500)
|
||||
public static void ShowInPreviewer(this IDocument document, int port = 5000)
|
||||
{
|
||||
document.ShowInPreviewerAsync(port).ConfigureAwait(true).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
public static async Task ShowInPreviewerAsync(this IDocument document, int port = 12500)
|
||||
public static async Task ShowInPreviewerAsync(this IDocument document, int port = 5000)
|
||||
{
|
||||
var previewerService = new PreviewerService(port);
|
||||
|
||||
@@ -26,39 +26,34 @@ namespace QuestPDF.Previewer
|
||||
await previewerService.Connect();
|
||||
await RefreshPreview();
|
||||
|
||||
HotReloadManager.UpdateApplicationRequested += (_, _) => RefreshPreview();
|
||||
|
||||
await WaitForPreviewerExit(cancellationTokenSource.Token);
|
||||
//
|
||||
// //HotReloadManager.UpdateApplicationRequested += (_, _) => RefreshPreview();
|
||||
//
|
||||
// await WaitForPreviewerExit(cancellationTokenSource.Token);
|
||||
|
||||
Task RefreshPreview()
|
||||
{
|
||||
var pictures = GetPictures();
|
||||
return previewerService.RefreshPreview(pictures);
|
||||
|
||||
ICollection<PreviewerPicture> GetPictures()
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
return DocumentGenerator.GeneratePreviewerPictures(document);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
var exceptionDocument = new ExceptionDocument(exception);
|
||||
return DocumentGenerator.GeneratePreviewerPictures(exceptionDocument);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async Task WaitForPreviewerExit(CancellationToken cancellationToken)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
return;
|
||||
|
||||
await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
|
||||
var pictures = DocumentGenerator.GeneratePreviewerPictures(document);
|
||||
return previewerService.ShowDocumentPreview(pictures);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
return previewerService.ShowGenericError(exception);
|
||||
}
|
||||
}
|
||||
//
|
||||
// async Task WaitForPreviewerExit(CancellationToken cancellationToken)
|
||||
// {
|
||||
// while (true)
|
||||
// {
|
||||
// if (cancellationToken.IsCancellationRequested)
|
||||
// return;
|
||||
//
|
||||
// await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using QuestPDF.Infrastructure;
|
||||
|
||||
#if NET6_0_OR_GREATER
|
||||
#if NETCOREAPP3_0_OR_GREATER
|
||||
|
||||
namespace QuestPDF.Previewer
|
||||
{
|
||||
@@ -14,8 +14,8 @@ namespace QuestPDF.Previewer
|
||||
{
|
||||
public string Id { get; } = Guid.NewGuid().ToString("N");
|
||||
|
||||
public float Width { get; init; }
|
||||
public float Height { get; init; }
|
||||
public float Width { get; set; }
|
||||
public float Height { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,47 @@
|
||||
#if NET6_0_OR_GREATER
|
||||
#if NETCOREAPP3_0_OR_GREATER
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Json;
|
||||
using System.Threading;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Threading.Tasks;
|
||||
using QuestPDF.Drawing;
|
||||
|
||||
namespace QuestPDF.Previewer
|
||||
{
|
||||
|
||||
|
||||
internal sealed class GenericError
|
||||
{
|
||||
public string ExceptionType { get; set; }
|
||||
public string Message { get; set; }
|
||||
public string StackTrace { get; set; }
|
||||
public GenericError? InnerException { get; set; }
|
||||
}
|
||||
|
||||
internal sealed class ShowLayoutErrorApiRequestVersion
|
||||
{
|
||||
public GenericError? Error { get; set; }
|
||||
}
|
||||
|
||||
|
||||
internal sealed class UpdateDocumentPreviewApiRequest
|
||||
{
|
||||
public ICollection<PageSnapshot> PageSnapshots { get; set; }
|
||||
|
||||
public class PageSnapshot
|
||||
{
|
||||
public string ResourceId { get; } = Guid.NewGuid().ToString("N");
|
||||
public int PageNumber { get; set; }
|
||||
|
||||
public float Width { get; set; }
|
||||
public float Height { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
internal class PreviewerService
|
||||
{
|
||||
private int Port { get; }
|
||||
@@ -31,20 +62,80 @@ namespace QuestPDF.Previewer
|
||||
};
|
||||
}
|
||||
|
||||
public async Task ShowDocumentPreview(ICollection<PreviewerPicture> pictures)
|
||||
{
|
||||
using var multipartContent = new MultipartFormDataContent();
|
||||
|
||||
var pages = new List<UpdateDocumentPreviewApiRequest.PageSnapshot>();
|
||||
|
||||
foreach (var picture in pictures)
|
||||
{
|
||||
var page = new UpdateDocumentPreviewApiRequest.PageSnapshot
|
||||
{
|
||||
Width = picture.Size.Width,
|
||||
Height = picture.Size.Height
|
||||
};
|
||||
|
||||
pages.Add(page);
|
||||
|
||||
var pictureStream = picture.Picture.Serialize().AsStream();
|
||||
multipartContent.Add(new StreamContent(pictureStream), "snapshots", page.ResourceId);
|
||||
}
|
||||
|
||||
var request = new UpdateDocumentPreviewApiRequest
|
||||
{
|
||||
PageSnapshots = pages
|
||||
};
|
||||
|
||||
var json = JsonSerializer.Serialize(request);
|
||||
var jsonContent = new StringContent(json, Encoding.UTF8, "application/json");
|
||||
multipartContent.Add(jsonContent, "request");
|
||||
|
||||
using var response = await HttpClient.PostAsync("/v1/update/preview/document", multipartContent);
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
foreach (var picture in pictures)
|
||||
picture.Picture.Dispose();
|
||||
}
|
||||
|
||||
public async Task ShowGenericError(Exception exception)
|
||||
{
|
||||
var payload = new ShowLayoutErrorApiRequestVersion
|
||||
{
|
||||
Error = MapException(exception)
|
||||
};
|
||||
|
||||
await HttpClient.PostAsJsonAsync("/v1/update/error/generic", payload);
|
||||
|
||||
static GenericError? MapException(Exception? exception)
|
||||
{
|
||||
if (exception == null)
|
||||
return null;
|
||||
|
||||
return new GenericError
|
||||
{
|
||||
ExceptionType = exception.GetType().FullName,
|
||||
Message = exception.Message,
|
||||
StackTrace = exception.StackTrace,
|
||||
InnerException = MapException(exception.InnerException)
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public async Task Connect()
|
||||
{
|
||||
var isAvailable = await IsPreviewerAvailable();
|
||||
|
||||
|
||||
if (!isAvailable)
|
||||
{
|
||||
StartPreviewer();
|
||||
await WaitForConnection();
|
||||
//StartPreviewer();
|
||||
//await WaitForConnection();
|
||||
}
|
||||
|
||||
var previewerVersion = await GetPreviewerVersion();
|
||||
CheckVersionCompatibility(previewerVersion);
|
||||
//var previewerVersion = await GetPreviewerVersion();
|
||||
//CheckVersionCompatibility(previewerVersion);
|
||||
}
|
||||
|
||||
|
||||
private async Task<bool> IsPreviewerAvailable()
|
||||
{
|
||||
try
|
||||
@@ -57,107 +148,107 @@ namespace QuestPDF.Previewer
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<Version> GetPreviewerVersion()
|
||||
{
|
||||
using var result = await HttpClient.GetAsync("/version");
|
||||
return await result.Content.ReadFromJsonAsync<Version>();
|
||||
}
|
||||
|
||||
private void StartPreviewer()
|
||||
{
|
||||
try
|
||||
{
|
||||
var process = new Process
|
||||
{
|
||||
StartInfo = new()
|
||||
{
|
||||
FileName = "questpdf-previewer",
|
||||
Arguments = $"{Port}",
|
||||
UseShellExecute = false,
|
||||
CreateNoWindow = true
|
||||
}
|
||||
};
|
||||
|
||||
process.Start();
|
||||
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await process.WaitForExitAsync();
|
||||
process.Dispose();
|
||||
OnPreviewerStopped?.Invoke();
|
||||
});
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new Exception("Cannot start the QuestPDF Previewer tool. " +
|
||||
"Please install it by executing in terminal the following command: 'dotnet tool install --global QuestPDF.Previewer'.");
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckVersionCompatibility(Version version)
|
||||
{
|
||||
if (version.Major == RequiredPreviewerVersionMajor && version.Minor == RequiredPreviewerVersionMinor)
|
||||
return;
|
||||
|
||||
throw new Exception($"Previewer version is not compatible. Possible solutions: " +
|
||||
$"1) Update the QuestPDF library to newer version. " +
|
||||
$"2) Update the QuestPDF previewer tool using the following command: 'dotnet tool update --global QuestPDF.Previewer --version {RequiredPreviewerVersionMajor}.{RequiredPreviewerVersionMinor}'");
|
||||
}
|
||||
|
||||
private async Task WaitForConnection()
|
||||
{
|
||||
using var cancellationTokenSource = new CancellationTokenSource();
|
||||
cancellationTokenSource.CancelAfter(TimeSpan.FromSeconds(10));
|
||||
|
||||
var cancellationToken = cancellationTokenSource.Token;
|
||||
|
||||
while (true)
|
||||
{
|
||||
await Task.Delay(TimeSpan.FromMilliseconds(250));
|
||||
|
||||
if (cancellationToken.IsCancellationRequested)
|
||||
throw new Exception($"Cannot connect to the QuestPDF Previewer tool. Please make sure that your Operating System does not block HTTP connections on port {Port}.");
|
||||
|
||||
var isConnected = await IsPreviewerAvailable();
|
||||
|
||||
if (isConnected)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task RefreshPreview(ICollection<PreviewerPicture> pictures)
|
||||
{
|
||||
using var multipartContent = new MultipartFormDataContent();
|
||||
|
||||
var pages = new List<PreviewerRefreshCommand.Page>();
|
||||
|
||||
foreach (var picture in pictures)
|
||||
{
|
||||
var page = new PreviewerRefreshCommand.Page
|
||||
{
|
||||
Width = picture.Size.Width,
|
||||
Height = picture.Size.Height
|
||||
};
|
||||
|
||||
pages.Add(page);
|
||||
|
||||
var pictureStream = picture.Picture.Serialize().AsStream();
|
||||
multipartContent.Add(new StreamContent(pictureStream), page.Id, page.Id);
|
||||
}
|
||||
|
||||
var command = new PreviewerRefreshCommand
|
||||
{
|
||||
Pages = pages
|
||||
};
|
||||
|
||||
multipartContent.Add(JsonContent.Create(command), "command");
|
||||
|
||||
using var _ = await HttpClient.PostAsync("/update/preview", multipartContent);
|
||||
|
||||
foreach (var picture in pictures)
|
||||
picture.Picture.Dispose();
|
||||
}
|
||||
//
|
||||
// private async Task<Version> GetPreviewerVersion()
|
||||
// {
|
||||
// using var result = await HttpClient.GetAsync("/version");
|
||||
// return await result.Content.ReadFromJsonAsync<Version>();
|
||||
// }
|
||||
//
|
||||
// private void StartPreviewer()
|
||||
// {
|
||||
// try
|
||||
// {
|
||||
// var process = new Process
|
||||
// {
|
||||
// StartInfo = new()
|
||||
// {
|
||||
// FileName = "questpdf-previewer",
|
||||
// Arguments = $"{Port}",
|
||||
// UseShellExecute = false,
|
||||
// CreateNoWindow = true
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// process.Start();
|
||||
//
|
||||
// Task.Run(async () =>
|
||||
// {
|
||||
// await process.WaitForExitAsync();
|
||||
// process.Dispose();
|
||||
// OnPreviewerStopped?.Invoke();
|
||||
// });
|
||||
// }
|
||||
// catch
|
||||
// {
|
||||
// throw new Exception("Cannot start the QuestPDF Previewer tool. " +
|
||||
// "Please install it by executing in terminal the following command: 'dotnet tool install --global QuestPDF.Previewer'.");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private void CheckVersionCompatibility(Version version)
|
||||
// {
|
||||
// if (version.Major == RequiredPreviewerVersionMajor && version.Minor == RequiredPreviewerVersionMinor)
|
||||
// return;
|
||||
//
|
||||
// throw new Exception($"Previewer version is not compatible. Possible solutions: " +
|
||||
// $"1) Update the QuestPDF library to newer version. " +
|
||||
// $"2) Update the QuestPDF previewer tool using the following command: 'dotnet tool update --global QuestPDF.Previewer --version {RequiredPreviewerVersionMajor}.{RequiredPreviewerVersionMinor}'");
|
||||
// }
|
||||
//
|
||||
// private async Task WaitForConnection()
|
||||
// {
|
||||
// using var cancellationTokenSource = new CancellationTokenSource();
|
||||
// cancellationTokenSource.CancelAfter(TimeSpan.FromSeconds(10));
|
||||
//
|
||||
// var cancellationToken = cancellationTokenSource.Token;
|
||||
//
|
||||
// while (true)
|
||||
// {
|
||||
// await Task.Delay(TimeSpan.FromMilliseconds(250));
|
||||
//
|
||||
// if (cancellationToken.IsCancellationRequested)
|
||||
// throw new Exception($"Cannot connect to the QuestPDF Previewer tool. Please make sure that your Operating System does not block HTTP connections on port {Port}.");
|
||||
//
|
||||
// var isConnected = await IsPreviewerAvailable();
|
||||
//
|
||||
// if (isConnected)
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public async Task RefreshPreview(ICollection<PreviewerPicture> pictures)
|
||||
// {
|
||||
// using var multipartContent = new MultipartFormDataContent();
|
||||
//
|
||||
// var pages = new List<PreviewerRefreshCommand.Page>();
|
||||
//
|
||||
// foreach (var picture in pictures)
|
||||
// {
|
||||
// var page = new PreviewerRefreshCommand.Page
|
||||
// {
|
||||
// Width = picture.Size.Width,
|
||||
// Height = picture.Size.Height
|
||||
// };
|
||||
//
|
||||
// pages.Add(page);
|
||||
//
|
||||
// var pictureStream = picture.Picture.Serialize().AsStream();
|
||||
// multipartContent.Add(new StreamContent(pictureStream), page.Id, page.Id);
|
||||
// }
|
||||
//
|
||||
// var command = new PreviewerRefreshCommand
|
||||
// {
|
||||
// Pages = pages
|
||||
// };
|
||||
//
|
||||
// multipartContent.Add(JsonContent.Create(command), "command");
|
||||
//
|
||||
// using var _ = await HttpClient.PostAsync("/update/preview", multipartContent);
|
||||
//
|
||||
// foreach (var picture in pictures)
|
||||
// picture.Picture.Dispose();
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<Nullable>enable</Nullable>
|
||||
<TargetFrameworks>net462;netstandard2.0;netcoreapp2.0;netcoreapp3.0;net6.0</TargetFrameworks>
|
||||
<TargetFrameworks>netcoreapp3.0;</TargetFrameworks>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
</PropertyGroup>
|
||||
@@ -69,8 +70,4 @@
|
||||
<ItemGroup>
|
||||
<Compile Remove="Previewer\Models\GenericError.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Previewer\Models" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user