Skip to content

Commit

Permalink
Issue276 items (#277)
Browse files Browse the repository at this point in the history
* Add properties

* Minor changes
  • Loading branch information
geoperez authored Apr 23, 2019
1 parent cd92e84 commit b611869
Show file tree
Hide file tree
Showing 13 changed files with 216 additions and 81 deletions.
10 changes: 5 additions & 5 deletions src/Unosquare.Labs.EmbedIO.Samples/PeopleController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,19 @@ public async Task<bool> GetPeople(string id = null)
{
// if it ends with a / means we need to list people
if (string.IsNullOrWhiteSpace(id))
return await this.JsonResponseAsync(_dbContext.People.SelectAll());
return await JsonResponseAsync(_dbContext.People.SelectAll());

// if it ends with "first" means we need to show first record of people
if (id == "first")
return await this.JsonResponseAsync(_dbContext.People.SelectAll().First());
return await JsonResponseAsync(_dbContext.People.SelectAll().First());

// otherwise, we need to parse the key and respond with the entity accordingly
if (int.TryParse(id, out var key))
{
var single = await _dbContext.People.SingleAsync(key);

if (single != null)
return await this.JsonResponseAsync(single);
return await JsonResponseAsync(single);
}

throw new KeyNotFoundException($"Key Not Found: {id}");
Expand All @@ -62,7 +62,7 @@ public async Task<bool> GetPeople(string id = null)
/// <returns></returns>
[WebApiHandler(HttpVerbs.Post, RelativePath + "people/")]
public Task<bool> PostPeople() =>
this.TransformJson<GridDataRequest, GridDataResponse>(async (model, ct) =>
TransformJson<GridDataRequest, GridDataResponse>(async (model, ct) =>
model.CreateGridDataResponse((await _dbContext.People.SelectAllAsync()).AsQueryable()));

/// <summary>
Expand All @@ -74,7 +74,7 @@ public async Task<bool> Echo()
{
var content = await this.RequestFormDataDictionaryAsync();

return await this.JsonResponseAsync(content);
return await JsonResponseAsync(content);
}
}
}
9 changes: 9 additions & 0 deletions src/Unosquare.Labs.EmbedIO/Abstractions/IHttpContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
{
using System.Threading.Tasks;
using System.Security.Principal;
using System.Collections.Generic;

/// <summary>
/// Interface to create a HTTP Context.
Expand Down Expand Up @@ -40,6 +41,14 @@ public interface IHttpContext
/// </value>
IWebServer WebServer { get; set; }

/// <summary>
/// Gets or sets the dictionary of data to pass trough the EmbedIO pipeline.
/// </summary>
/// <value>
/// The items.
/// </value>
IDictionary<object,object> Items { get; set; }

/// <summary>
/// Accepts the web socket asynchronous.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@
// Sorts strings in reverse order to obtain the evaluation order of virtual paths
internal sealed class ReverseOrdinalStringComparer : IComparer<string>
{
private static readonly IComparer<string> _directComparer = StringComparer.Ordinal;
private static readonly IComparer<string> DirectComparer = StringComparer.Ordinal;

private ReverseOrdinalStringComparer()
{
}

public static IComparer<string> Instance { get; } = new ReverseOrdinalStringComparer();

public int Compare(string x, string y) => _directComparer.Compare(y, x);
public int Compare(string x, string y) => DirectComparer.Compare(y, x);
}
}
14 changes: 12 additions & 2 deletions src/Unosquare.Labs.EmbedIO/HttpContext.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#if !NETSTANDARD1_3
namespace Unosquare.Labs.EmbedIO
{
using System.Security.Principal;
using System.Net;
using System;
using System.Collections.Generic;
using System.Net;
using System.Security.Principal;
using System.Threading.Tasks;

/// <summary>
Expand All @@ -13,6 +14,8 @@ namespace Unosquare.Labs.EmbedIO
public class HttpContext : IHttpContext
{
private readonly HttpListenerContext _context;
private Lazy<IDictionary<object, object>> _items =
new Lazy<IDictionary<object, object>>(() => new Dictionary<object, object>(), true);

/// <summary>
/// Initializes a new instance of the <see cref="HttpContext" /> class.
Expand All @@ -38,6 +41,13 @@ public HttpContext(HttpListenerContext context)
/// <inheritdoc />
public IWebServer WebServer { get; set; }

/// <inheritdoc />
public IDictionary<object, object> Items
{
get => _items.Value;
set => _items = new Lazy<IDictionary<object, object>>(() => value, true);
}

/// <inheritdoc />
public async Task<IWebSocketContext> AcceptWebSocketAsync(int receiveBufferSize)
=> new WebSocketContext(await _context.AcceptWebSocketAsync(subProtocol: null,
Expand Down
4 changes: 2 additions & 2 deletions src/Unosquare.Labs.EmbedIO/Modules/ResourceFilesModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
{
using Constants;
using EmbedIO;
using Swan;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Swan;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Reflection;

/// <summary>
/// Represents a simple module to server resource files from the .NET assembly.
Expand Down
11 changes: 6 additions & 5 deletions src/Unosquare.Labs.EmbedIO/Modules/StaticFilesModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ public StaticFilesModule(
#endif

headers?.ForEach(DefaultHeaders.Add);
additionalPaths?.ForEach((virtualPath, physicalPath) => {
additionalPaths?.ForEach((virtualPath, physicalPath) =>
{
if (virtualPath != "/")
RegisterVirtualPath(virtualPath, physicalPath);
});
Expand Down Expand Up @@ -196,7 +197,7 @@ public string DefaultExtension
public ReadOnlyDictionary<string, string> VirtualPaths => _virtualPathManager.VirtualPaths;

/// <inheritdoc />
public override string Name => nameof(StaticFilesModule);
public override string Name { get; } = nameof(StaticFilesModule);

/// <summary>
/// Private collection holding the contents of the RAM Cache.
Expand Down Expand Up @@ -358,9 +359,9 @@ private async Task<bool> HandleFile(
}

await WriteFileAsync(
partialHeader,
context.Response,
buffer,
partialHeader,
context.Response,
buffer,
context.AcceptGzip(buffer.Length),
ct)
.ConfigureAwait(false);
Expand Down
141 changes: 119 additions & 22 deletions src/Unosquare.Labs.EmbedIO/Modules/WebApiController.cs
Original file line number Diff line number Diff line change
@@ -1,45 +1,60 @@
namespace Unosquare.Labs.EmbedIO.Modules
{
using System;
using System.Security.Principal;
using System.Text;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using System.Security.Principal;

/// <inheritdoc />
/// <summary>
/// Inherit from this class and define your own Web API methods
/// You must RegisterController in the Web API Module to make it active.
/// </summary>
public abstract class WebApiController : IHttpContext
public abstract class WebApiController
{
private readonly IHttpContext _context;

/// <summary>
/// Initializes a new instance of the <see cref="WebApiController"/> class.
/// </summary>
/// <param name="context">The context.</param>
protected WebApiController(IHttpContext context)
{
Request = context.Request;
Response = context.Response;
User = context.User;
WebServer = context.WebServer;
_context = context;
}

/// <inheritdoc />
public IHttpRequest Request { get; internal set; }

/// <inheritdoc />
public IHttpResponse Response { get; internal set; }
/// <summary>
/// Gets the HTTP Request.
/// </summary>
/// <value>
/// The request.
/// </value>
public IHttpRequest Request => _context.Request;

/// <inheritdoc />
public IPrincipal User { get; }
/// <summary>
/// Gets the HTTP Response.
/// </summary>
/// <value>
/// The response.
/// </value>
public IHttpResponse Response => _context.Response;

/// <inheritdoc />
public IWebServer WebServer { get; set; }
/// <summary>
/// Gets the user.
/// </summary>
/// <value>
/// The user.
/// </value>
public IPrincipal User => _context.User;

/// <inheritdoc />
public Task<IWebSocketContext> AcceptWebSocketAsync(int receiveBufferSize)
{
throw new NotImplementedException();
}
/// <summary>
/// Gets or sets the web server.
/// </summary>
/// <value>
/// The web server.
/// </value>
public IWebServer WebServer => _context.WebServer;

/// <summary>
/// Sets the default headers to the Web API response.
Expand All @@ -52,6 +67,88 @@ public Task<IWebSocketContext> AcceptWebSocketAsync(int receiveBufferSize)
///
/// Previous values are defined to avoid caching from client.
/// </summary>
public virtual void SetDefaultHeaders() => this.NoCache();
public virtual void SetDefaultHeaders() => _context.NoCache();

/// <summary>
/// Outputs async a Json Response given a data object.
/// </summary>
/// <param name="data">The data.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>
/// A <c>true</c> value if the response output was set.
/// </returns>
public virtual Task<bool> JsonResponseAsync(object data, CancellationToken cancellationToken = default) =>
_context.JsonResponseAsync(data, cancellationToken);

/// <summary>
/// Transforms the response body as JSON and write a new JSON to the request.
/// </summary>
/// <typeparam name="TIn">The type of the input.</typeparam>
/// <typeparam name="TOut">The type of the output.</typeparam>
/// <param name="transformFunc">The transform function.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>
/// A task for writing the output stream.
/// </returns>
public virtual Task<bool> TransformJson<TIn, TOut>(Func<TIn, CancellationToken, Task<TOut>> transformFunc,
CancellationToken cancellationToken = default)
where TIn : class
=> _context.TransformJson(transformFunc, cancellationToken);

/// <summary>
/// Outputs a JSON Response given an exception.
/// </summary>
/// <param name="ex">The ex.</param>
/// <param name="statusCode">The status code.</param>
/// <param name="useGzip">if set to <c>true</c> [use gzip].</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>
/// A task for writing the output stream.
/// </returns>
public virtual Task<bool> JsonExceptionResponseAsync(
Exception ex,
System.Net.HttpStatusCode statusCode = System.Net.HttpStatusCode.InternalServerError,
bool useGzip = true,
CancellationToken cancellationToken = default)
=> _context.JsonExceptionResponseAsync(ex, statusCode, useGzip, cancellationToken);

/// <summary>
/// Outputs async a string response given a string.
/// </summary>
/// <param name="content">The content.</param>
/// <param name="contentType">Type of the content.</param>
/// <param name="encoding">The encoding.</param>
/// <param name="useGzip">if set to <c>true</c> [use gzip].</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>
/// A task for writing the output stream.
/// </returns>
public virtual Task<bool> StringResponseAsync(
string content,
string contentType = "application/json",
Encoding encoding = null,
bool useGzip = true,
CancellationToken cancellationToken = default) =>
_context.StringResponseAsync(content, contentType, encoding, useGzip, cancellationToken);

/// <summary>
/// Returns dictionary from Request POST data
/// Please note the underlying input stream is not rewindable.
/// </summary>
/// <returns>A task with a collection that represents KVPs from request data.</returns>
public virtual Task<Dictionary<string, object>> RequestFormDataDictionaryAsync() =>
_context.RequestFormDataDictionaryAsync();

/// <summary>
/// Deletes the session object associated to the current context.
/// </summary>
public virtual void DeleteSession() => _context.DeleteSession();

/// <summary>
/// Gets the session object associated to the current context.
/// Returns null if the LocalSessionWebModule has not been loaded.
/// </summary>
/// <returns>A session object for the given server context.</returns>
public virtual SessionInfo GetSession() => _context.GetSession();
}
}
6 changes: 3 additions & 3 deletions src/Unosquare.Labs.EmbedIO/Modules/WebApiModule.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
namespace Unosquare.Labs.EmbedIO.Modules
{
using Constants;
using EmbedIO;
using Swan;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Constants;
using EmbedIO;
using Swan;

/// <summary>
/// A very simple module to register class methods as handlers.
Expand Down
10 changes: 10 additions & 0 deletions src/Unosquare.Labs.EmbedIO/System.Net/HttpListenerContext.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
namespace Unosquare.Net
{
using System;
using System.Collections.Generic;
using System.Security.Principal;
using System.Threading.Tasks;
using Labs.EmbedIO;
Expand All @@ -12,6 +13,8 @@
public sealed class HttpListenerContext : IHttpContext
{
private WebSocketContext _websocketContext;
private Lazy<IDictionary<object, object>> _items =
new Lazy<IDictionary<object, object>>(() => new Dictionary<object, object>(), true);

internal HttpListenerContext(HttpConnection cnc)
{
Expand All @@ -33,6 +36,13 @@ internal HttpListenerContext(HttpConnection cnc)

/// <inheritdoc />
public IWebServer WebServer { get; set; }

/// <inheritdoc />
public IDictionary<object, object> Items
{
get => _items.Value;
set => _items = new Lazy<IDictionary<object, object>>(() => value, true);
}

internal HttpListenerRequest HttpListenerRequest => Request as HttpListenerRequest;

Expand Down
Loading

0 comments on commit b611869

Please sign in to comment.