Skip to content

Commit 92eb929

Browse files
committed
small issue fixing after testing
1 parent b21cb8e commit 92eb929

File tree

9 files changed

+210
-86
lines changed

9 files changed

+210
-86
lines changed
Binary file not shown.

samples/GroupDocs.Viewer.UI.SelfHosted.App.NetFramework.Sample/Global.asax.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,20 @@ protected void Application_Start()
1818
{
1919
AreaRegistration.RegisterAllAreas();
2020
var viewerType = ViewerType.HtmlWithEmbeddedResources;
21-
GlobalConfiguration.Configure(config =>
22-
{
23-
var serviceCollection = MvcBuilderExtensions.AddGroupDocsViewerSelfHostApi(null, config =>
21+
var serviceCollection = new ServiceCollection();
22+
serviceCollection.AddGroupDocsViewerSelfHostApi(viewConfig =>
2423
{
25-
config.SetViewerType(viewerType);
24+
viewConfig.SetViewerType(viewerType);
2625
//Trial limitations https://docs.groupdocs.com/viewer/net/evaluation-limitations-and-licensing-of-groupdocs-viewer/
2726
//Temporary license can be requested at https://purchase.groupdocs.com/temporary-license
28-
config.SetLicensePath("c:\\licenses\\GroupDocs.Viewer.lic"); // or set environment variable 'GROUPDOCS_LIC_PATH'
27+
//config.SetLicensePath("c:\\licenses\\GroupDocs.Viewer.lic"); // or set environment variable 'GROUPDOCS_LIC_PATH'
2928
})
3029
.AddLocalStorage(HttpContext.Current.Server.MapPath("~/App_Data/Files"))
3130
.AddLocalCache(HttpContext.Current.Server.MapPath("~/App_Data/Cache"));
3231

33-
var serviceProvider = serviceCollection.Services.BuildServiceProvider();
32+
var serviceProvider = serviceCollection.BuildServiceProvider();
33+
GlobalConfiguration.Configure(config =>
34+
{
3435
config.DependencyResolver = new ViewerDependencyResolver(serviceProvider);
3536
ViewerApiEndpointRouteBuilder.RegisterViewerApi(config, options =>
3637
{

samples/GroupDocs.Viewer.UI.SelfHosted.App.NetFramework.Sample/GroupDocs.Viewer.UI.SelfHosted.App.NetFramework.Sample.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,6 @@
143143
</PackageReference>
144144
</ItemGroup>
145145
<ItemGroup>
146-
<Folder Include="App_Data\Cache\" />
147146
<Folder Include="Controllers\" />
148147
<Folder Include="Models\" />
149148
</ItemGroup>
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# GroupDocs.Viewer.UI Self-Hosted App (.NET Framework)
2+
3+
This document provides an overview and setup guide for the GroupDocs.Viewer.UI Self-Hosted App built with .NET Framework. The sample project integrates the GroupDocs.Viewer UI with a backend API and showcases how to view various document types.
4+
5+
## Features
6+
- **Document Viewing**: Render documents as HTML with embedded resources.
7+
- **Local File and Cache Management**: Store documents and cache locally in the application.
8+
- **Customizable API Path**: Configure API endpoints for the Viewer.
9+
- **Embedded UI Integration**: Provides a user interface for document viewing.
10+
11+
## Prerequisites
12+
- .NET Framework 4.6.2 or higher.
13+
- Visual Studio 2019 or later.
14+
- GroupDocs.Viewer library and Viewer.UI components.
15+
- A valid GroupDocs.Viewer license (optional for non-trial limitations).
16+
17+
## Project Structure
18+
The sample project includes the following:
19+
20+
1. **Global.asax**: Handles application lifecycle events and sets up the Viewer API and UI.
21+
2. **App_Data**:
22+
- `Files`: Directory to store uploaded or local files.
23+
- `Cache`: Directory for caching document data.
24+
3. **Routes**: Configures API and UI routes.
25+
26+
## Setting Up the Application
27+
28+
### 1. Register Areas and Routes
29+
In `Application_Start`, the `AreaRegistration` and `RouteConfig` are registered to set up the required routing for MVC and API endpoints.
30+
31+
```csharp
32+
AreaRegistration.RegisterAllAreas();
33+
RouteConfig.RegisterRoutes(RouteTable.Routes);
34+
```
35+
36+
### 2. Configure GroupDocs.Viewer Services
37+
Use `ServiceCollection` to register GroupDocs.Viewer services, including file storage, caching, and Viewer type.
38+
39+
```csharp
40+
var serviceCollection = new ServiceCollection();
41+
serviceCollection.AddGroupDocsViewerSelfHostApi(viewConfig =>
42+
{
43+
viewConfig.SetViewerType(ViewerType.HtmlWithEmbeddedResources);
44+
})
45+
.AddLocalStorage(HttpContext.Current.Server.MapPath("~/App_Data/Files"))
46+
.AddLocalCache(HttpContext.Current.Server.MapPath("~/App_Data/Cache"));
47+
48+
var serviceProvider = serviceCollection.BuildServiceProvider();
49+
```
50+
51+
### 3. Set Up Viewer API Endpoints
52+
Configure Viewer API endpoints using `ViewerApiEndpointRouteBuilder`:
53+
54+
```csharp
55+
GlobalConfiguration.Configure(config =>
56+
{
57+
config.DependencyResolver = new ViewerDependencyResolver(serviceProvider);
58+
ViewerApiEndpointRouteBuilder.RegisterViewerApi(config, options =>
59+
{
60+
options.ApiPath = "/viewer-api";
61+
});
62+
});
63+
```
64+
65+
### 4. Configure the Viewer UI
66+
Define the UI path and API endpoint for the Viewer UI:
67+
68+
```csharp
69+
ViewerUIConfig viewerConfig = new ViewerUIConfig
70+
{
71+
UIPath = "/viewer",
72+
ApiEndpoint = "/viewer-api"
73+
};
74+
_viewer = ViewerUI.Configure(viewerConfig);
75+
```
76+
77+
### 5. Handle UI Requests
78+
Intercept GET requests for the Viewer UI:
79+
80+
```csharp
81+
protected void Application_BeginRequest(object sender, EventArgs e)
82+
{
83+
if (HttpContext.Current.Request.RequestType == "GET")
84+
{
85+
_viewer.HandleRequest(HttpContext.Current);
86+
}
87+
}
88+
```
89+
90+
## Licensing
91+
To remove trial limitations, set up a valid license by specifying the path to the license file or an environment variable.
92+
93+
```csharp
94+
viewConfig.SetLicensePath("c:\\licenses\\GroupDocs.Viewer.lic");
95+
```
96+
97+
Alternatively, request a temporary license from [GroupDocs Temporary License](https://purchase.groupdocs.com/temporary-license).
98+
99+
## Running the Application
100+
1. Open the project in Visual Studio.
101+
2. Build the solution to restore dependencies and compile the project.
102+
3. Run the application. The default Viewer API endpoint is `/viewer-api`, and the UI is accessible at `/viewer`.
103+
104+
## Example API Requests
105+
- **Render Document**: `GET /viewer-api/view?file={filePath}`
106+
- **Load Thumbnails**: `GET /viewer-api/thumbnail/{filePath}`
107+
108+
## Troubleshooting
109+
- Ensure the `App_Data/Files` and `App_Data/Cache` directories have proper read/write permissions.
110+
- Check the API endpoint configuration in `ViewerApiEndpointRouteBuilder` if the Viewer UI does not load.
111+
- Verify that the required NuGet packages are restored and referenced in the project.
112+
113+
## Resources
114+
- [GroupDocs.Viewer Documentation](https://docs.groupdocs.com/viewer/net/)
115+
- [GroupDocs.Viewer Examples](https://github.com/groupdocs-viewer/GroupDocs.Viewer-for-.NET)
116+
- [GroupDocs Support](https://forum.groupdocs.com/)
117+
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
using System.Net;
2+
using System.Net.Http;
3+
using System.Net.Http.Headers;
4+
using System.Threading;
5+
using System.Threading.Tasks;
6+
using System.Web.Http;
7+
8+
namespace GroupDocs.Viewer.UI.Api.NetFramework.Controllers;
9+
10+
public class FileResult : IHttpActionResult
11+
{
12+
private readonly byte[] _fileContents;
13+
private readonly string _contentType;
14+
private readonly string _fileName;
15+
16+
public FileResult(byte[] fileContents, string contentType, string fileName)
17+
{
18+
_fileContents = fileContents;
19+
_contentType = contentType;
20+
_fileName = fileName;
21+
}
22+
23+
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
24+
{
25+
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK)
26+
{
27+
Content = new ByteArrayContent(_fileContents)
28+
};
29+
30+
response.Content.Headers.ContentType = new MediaTypeHeaderValue(_contentType);
31+
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
32+
{
33+
FileName = _fileName
34+
};
35+
36+
return Task.FromResult(response);
37+
}
38+
}

src/GroupDocs.Viewer.UI.Api.NetFramework/Controllers/ViewerController.cs

Lines changed: 4 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,6 @@
66
using System;
77
using System.Collections.Generic;
88
using System.IO;
9-
using System.Net;
10-
using System.Net.Http;
11-
using System.Net.Http.Headers;
12-
using System.Threading;
139
using System.Threading.Tasks;
1410
using System.Web;
1511
using System.Web.Http;
@@ -143,7 +139,7 @@ public async Task<IHttpActionResult> GetPage([FromUri] GetPageRequest request)
143139
}
144140

145141
[HttpGet]
146-
public async Task<IHttpActionResult> GetThumb(GetThumbRequest request)
142+
public async Task<IHttpActionResult> GetThumb([FromUri] GetThumbRequest request)
147143
{
148144
try
149145
{
@@ -157,15 +153,15 @@ public async Task<IHttpActionResult> GetThumb(GetThumbRequest request)
157153
}
158154

159155
[HttpGet]
160-
public async Task<IHttpActionResult> GetPdf(GetPdfRequest request)
156+
public async Task<IHttpActionResult> GetPdf([FromUri] GetPdfRequest request)
161157
{
162158
if (!_config.EnableDownloadPdf && !_config.EnablePrint)
163159
return ErrorJsonResult("Creating PDF files is disabled.");
164160

165161
try
166162
{
167163
byte[] result = await _viewerService.GetPdfAsync(request);
168-
return new FileResult(result, "application/pdf", Path.GetFileName(request.File));
164+
return new FileResult(result, "application/pdf", $"{Path.GetFileNameWithoutExtension(request.File)}.pdf");
169165
}
170166
catch (Exception ex)
171167
{
@@ -174,7 +170,7 @@ public async Task<IHttpActionResult> GetPdf(GetPdfRequest request)
174170
}
175171

176172
[HttpGet]
177-
public async Task<IHttpActionResult> GetResource(GetResourceRequest request)
173+
public async Task<IHttpActionResult> GetResource([FromUri] GetResourceRequest request)
178174
{
179175
try
180176
{
@@ -193,34 +189,4 @@ private IHttpActionResult ErrorJsonResult(string message)
193189
return Json(new { error = message }, _jsonSerializerSettings);
194190
}
195191
}
196-
197-
public class FileResult : IHttpActionResult
198-
{
199-
private readonly byte[] _fileContents;
200-
private readonly string _contentType;
201-
private readonly string _fileName;
202-
203-
public FileResult(byte[] fileContents, string contentType, string fileName)
204-
{
205-
_fileContents = fileContents;
206-
_contentType = contentType;
207-
_fileName = fileName;
208-
}
209-
210-
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
211-
{
212-
HttpResponseMessage response = new HttpResponseMessage(HttpStatusCode.OK)
213-
{
214-
Content = new ByteArrayContent(_fileContents)
215-
};
216-
217-
response.Content.Headers.ContentType = new MediaTypeHeaderValue(_contentType);
218-
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
219-
{
220-
FileName = _fileName
221-
};
222-
223-
return Task.FromResult(response);
224-
}
225-
}
226192
}

src/GroupDocs.Viewer.UI.Api.NetFramework/Extensions/EndpointRouteBuilderExtensions.cs renamed to src/GroupDocs.Viewer.UI.Api.NetFramework/Extensions/ViewerApiEndpointRouteBuilder.cs

Lines changed: 1 addition & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
using GroupDocs.Viewer.UI.Api.Configuration;
22
using GroupDocs.Viewer.UI.Api.NetFramework.Endpoints;
3-
using Microsoft.Extensions.DependencyInjection;
43
using System;
5-
using System.Collections.Generic;
64
using System.Web.Http;
7-
using System.Web.Http.Dependencies;
85

96
namespace GroupDocs.Viewer.UI.Api.NetFramework.Extensions
107
{
@@ -45,7 +42,7 @@ private static void MapControllerRoutes(HttpRouteCollection routes, Options opti
4542
routes.MapHttpRoute(
4643
name: action,
4744
routeTemplate: $"{relativeApiPath}/{apiMethod}",
48-
defaults: new { controller = ApiNames.CONTROLLER_NAME, action }
45+
defaults: new { controller = ApiNames.CONTROLLER_NAME, action, optionalParam = RouteParameter.Optional }
4946
);
5047
}
5148
}
@@ -64,40 +61,4 @@ private static void EnsureValidApiOptions(Options options)
6461
ensureValidPath(options.ApiPath, nameof(Options.ApiPath));
6562
}
6663
}
67-
68-
public class ViewerDependencyResolver : IDependencyResolver
69-
{
70-
private readonly IServiceProvider _serviceProvider;
71-
72-
public ViewerDependencyResolver(IServiceProvider serviceProvider)
73-
{
74-
_serviceProvider = serviceProvider;
75-
}
76-
77-
public IDependencyScope BeginScope()
78-
{
79-
return this; // Web API does not natively support child scopes
80-
}
81-
82-
public object GetService(Type serviceType)
83-
{
84-
return _serviceProvider.GetService(serviceType);
85-
}
86-
87-
public IEnumerable<object> GetServices(Type serviceType)
88-
{
89-
return _serviceProvider.GetServices(serviceType);
90-
}
91-
92-
public void Dispose()
93-
{
94-
Dispose(true);
95-
GC.SuppressFinalize(this);
96-
}
97-
98-
protected virtual void Dispose(bool disposing)
99-
{
100-
// Cleanup
101-
}
102-
}
10364
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Web.Http.Dependencies;
4+
using Microsoft.Extensions.DependencyInjection;
5+
6+
namespace GroupDocs.Viewer.UI.Api.NetFramework.Extensions;
7+
8+
public class ViewerDependencyResolver : IDependencyResolver
9+
{
10+
private readonly IServiceProvider _serviceProvider;
11+
12+
public ViewerDependencyResolver(IServiceProvider serviceProvider)
13+
{
14+
_serviceProvider = serviceProvider;
15+
}
16+
17+
public IDependencyScope BeginScope()
18+
{
19+
return this; // Web API does not natively support child scopes
20+
}
21+
22+
public object GetService(Type serviceType)
23+
{
24+
return _serviceProvider.GetService(serviceType);
25+
}
26+
27+
public IEnumerable<object> GetServices(Type serviceType)
28+
{
29+
return _serviceProvider.GetServices(serviceType);
30+
}
31+
32+
public void Dispose()
33+
{
34+
Dispose(true);
35+
GC.SuppressFinalize(this);
36+
}
37+
38+
protected virtual void Dispose(bool disposing)
39+
{
40+
// Cleanup
41+
}
42+
}

src/GroupDocs.Viewer.UI.SelfHost.Api.NetFramework/Extensions/MvcBuilderExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace Microsoft.Extensions.DependencyInjection
99
{
1010
public static class MvcBuilderExtensions
1111
{
12-
public static GroupDocsViewerUIApiBuilder AddGroupDocsViewerSelfHostApi(IServiceCollection serviceCollection = null,
12+
public static GroupDocsViewerUIApiBuilder AddGroupDocsViewerSelfHostApi(this IServiceCollection serviceCollection,
1313
Action<Config> setupConfig = null)
1414
{
1515
serviceCollection ??= new ServiceCollection();

0 commit comments

Comments
 (0)