mirror of
https://github.com/wiremock/WireMock.Net.git
synced 2026-03-28 11:51:48 +01:00
Update BodyParser logic (#212)
* Update BodyParser logic * update logic for byte[] * small update * MyGetKey * myget * dotnet nuget push * dotnet build * Release * . * StringContent * 1.0.4.18-preview-02 * Debug * 1.0.4.18-preview-02 * disable some proxy tests * myget * packagesToPack * fix * <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects> <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType> * Release * <VersionPrefix>1.0.4.18</VersionPrefix> * fix * BodyParserTests * ResponseBodyData (#216) * ResponseBodyData * refactor tests * LogEntryMapperTests
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
<PropertyGroup>
|
||||
<Description>Lightweight StandAlone Http Mocking Server for .Net.</Description>
|
||||
<AssemblyTitle>WireMock.Net.StandAlone</AssemblyTitle>
|
||||
<Version>1.0.4.18</Version>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>net451;net452;net46;netstandard1.3;netstandard2.0</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
@@ -21,6 +20,8 @@
|
||||
<IncludeSource>True</IncludeSource>
|
||||
<IncludeSymbols>True</IncludeSymbols>
|
||||
<ProjectGuid>{B6269AAC-170A-43D5-8B9A-579DED3D9A95}</ProjectGuid>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace WireMock.Admin.Requests
|
||||
public string Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The absolete URL.
|
||||
/// The absolute URL.
|
||||
/// </summary>
|
||||
public string AbsoluteUrl { get; set; }
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace WireMock.Admin.Requests
|
||||
public IDictionary<string, WireMockList<string>> Headers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Tthe Cookies.
|
||||
/// The Cookies.
|
||||
/// </summary>
|
||||
public IDictionary<string, string> Cookies { get; set; }
|
||||
|
||||
@@ -79,5 +79,25 @@ namespace WireMock.Admin.Requests
|
||||
/// The body encoding.
|
||||
/// </summary>
|
||||
public EncodingModel BodyEncoding { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The DetectedBodyType, valid values are:
|
||||
///
|
||||
/// - None
|
||||
/// - String
|
||||
/// - Json
|
||||
/// - Bytes
|
||||
/// </summary>
|
||||
public string DetectedBodyType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The DetectedBodyTypeFromContentType, valid values are:
|
||||
///
|
||||
/// - None
|
||||
/// - String
|
||||
/// - Json
|
||||
/// - Bytes
|
||||
/// </summary>
|
||||
public string DetectedBodyTypeFromContentType { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -58,5 +58,15 @@ namespace WireMock.Admin.Requests
|
||||
/// Gets or sets the body.
|
||||
/// </summary>
|
||||
public EncodingModel BodyEncoding { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The detected body type (detection based on body content).
|
||||
/// </summary>
|
||||
public BodyType DetectedBodyType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The detected body type (detection based on Content-Type).
|
||||
/// </summary>
|
||||
public BodyType DetectedBodyTypeFromContentType { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -2,16 +2,21 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using JetBrains.Annotations;
|
||||
using MimeKit;
|
||||
using Newtonsoft.Json;
|
||||
using WireMock.Util;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Http
|
||||
{
|
||||
internal static class HttpRequestMessageHelper
|
||||
{
|
||||
public static HttpRequestMessage Create(RequestMessage requestMessage, string url)
|
||||
internal static HttpRequestMessage Create([NotNull] RequestMessage requestMessage, [NotNull] string url)
|
||||
{
|
||||
Check.NotNull(requestMessage, nameof(requestMessage));
|
||||
Check.NotNullOrEmpty(url, nameof(url));
|
||||
|
||||
var httpRequestMessage = new HttpRequestMessage(new HttpMethod(requestMessage.Method), url);
|
||||
|
||||
ContentType contentType = null;
|
||||
@@ -21,40 +26,25 @@ namespace WireMock.Http
|
||||
ContentType.TryParse(value, out contentType);
|
||||
}
|
||||
|
||||
// Set Body if present
|
||||
if (requestMessage.BodyAsBytes != null)
|
||||
switch (requestMessage.BodyData?.DetectedBodyType)
|
||||
{
|
||||
httpRequestMessage.Content = new ByteArrayContent(requestMessage.BodyAsBytes);
|
||||
}
|
||||
else if (requestMessage.BodyAsJson != null)
|
||||
{
|
||||
if (contentType != null)
|
||||
{
|
||||
var encoding = requestMessage.BodyEncoding ?? Encoding.GetEncoding(contentType.Charset ?? "UTF-8");
|
||||
httpRequestMessage.Content = new StringContent(JsonConvert.SerializeObject(requestMessage.BodyAsJson), encoding, contentType.MimeType);
|
||||
}
|
||||
else
|
||||
{
|
||||
httpRequestMessage.Content = new StringContent(JsonConvert.SerializeObject(requestMessage.BodyAsJson), requestMessage.BodyEncoding);
|
||||
}
|
||||
}
|
||||
else if (requestMessage.Body != null)
|
||||
{
|
||||
if (contentType != null)
|
||||
{
|
||||
var encoding = requestMessage.BodyEncoding ?? Encoding.GetEncoding(contentType.Charset ?? "UTF-8");
|
||||
httpRequestMessage.Content = new StringContent(requestMessage.Body, encoding, contentType.MimeType);
|
||||
}
|
||||
else
|
||||
{
|
||||
httpRequestMessage.Content = new StringContent(requestMessage.Body, requestMessage.BodyEncoding);
|
||||
}
|
||||
case BodyType.Bytes:
|
||||
httpRequestMessage.Content = new ByteArrayContent(requestMessage.BodyData.BodyAsBytes);
|
||||
break;
|
||||
|
||||
case BodyType.Json:
|
||||
httpRequestMessage.Content = StringContentHelper.Create(JsonConvert.SerializeObject(requestMessage.BodyData.BodyAsJson), contentType);
|
||||
break;
|
||||
|
||||
case BodyType.String:
|
||||
httpRequestMessage.Content = StringContentHelper.Create(requestMessage.BodyData.BodyAsString, contentType);
|
||||
break;
|
||||
}
|
||||
|
||||
// Overwrite the host header
|
||||
httpRequestMessage.Headers.Host = new Uri(url).Authority;
|
||||
|
||||
// Set other headers if present and if not excluded
|
||||
// Set other headers if present
|
||||
if (requestMessage.Headers == null || requestMessage.Headers.Count == 0)
|
||||
{
|
||||
return httpRequestMessage;
|
||||
@@ -63,6 +53,7 @@ namespace WireMock.Http
|
||||
var excludeHeaders = new List<string> { HttpKnownHeaderNames.Host, HttpKnownHeaderNames.ContentLength };
|
||||
if (contentType != null)
|
||||
{
|
||||
// Content-Type should be set on the content
|
||||
excludeHeaders.Add(HttpKnownHeaderNames.ContentType);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,10 +24,7 @@ namespace WireMock.Http
|
||||
contentTypeHeader = headers.First(header => string.Equals(header.Key, HttpKnownHeaderNames.ContentType, StringComparison.OrdinalIgnoreCase)).Value;
|
||||
}
|
||||
|
||||
var body = await BodyParser.Parse(stream, contentTypeHeader?.FirstOrDefault());
|
||||
responseMessage.Body = body.BodyAsString;
|
||||
responseMessage.BodyAsJson = body.BodyAsJson;
|
||||
responseMessage.BodyAsBytes = body.BodyAsBytes;
|
||||
responseMessage.BodyData = await BodyParser.Parse(stream, contentTypeHeader?.FirstOrDefault());
|
||||
}
|
||||
|
||||
foreach (var header in headers)
|
||||
|
||||
38
src/WireMock.Net/Http/StringContentHelper.cs
Normal file
38
src/WireMock.Net/Http/StringContentHelper.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Text;
|
||||
using JetBrains.Annotations;
|
||||
using MimeKit;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Http
|
||||
{
|
||||
internal static class StringContentHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a StringContent object. Note that the Encoding is only set when it's also set on the original header.
|
||||
/// </summary>
|
||||
/// <param name="content">The string content (cannot be null)</param>
|
||||
/// <param name="contentType">The ContentType (can be null)</param>
|
||||
/// <returns>StringContent</returns>
|
||||
internal static StringContent Create([NotNull] string content, [CanBeNull] ContentType contentType)
|
||||
{
|
||||
Check.NotNull(content, nameof(content));
|
||||
|
||||
if (contentType == null)
|
||||
{
|
||||
return new StringContent(content);
|
||||
}
|
||||
|
||||
if (contentType.Charset == null)
|
||||
{
|
||||
var stringContent = new StringContent(content);
|
||||
stringContent.Headers.ContentType = new MediaTypeHeaderValue(contentType.MimeType);
|
||||
return stringContent;
|
||||
}
|
||||
|
||||
var encoding = Encoding.GetEncoding(contentType.Charset);
|
||||
return new StringContent(content, encoding, contentType.MimeType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,15 +24,12 @@ namespace WireMock
|
||||
public int Priority { get; }
|
||||
|
||||
/// <inheritdoc cref="IMapping.Scenario" />
|
||||
[CanBeNull]
|
||||
public string Scenario { get; }
|
||||
|
||||
/// <inheritdoc cref="IMapping.ExecutionConditionState" />
|
||||
[CanBeNull]
|
||||
public string ExecutionConditionState { get; }
|
||||
|
||||
/// <inheritdoc cref="IMapping.NextState" />
|
||||
[CanBeNull]
|
||||
public string NextState { get; }
|
||||
|
||||
/// <inheritdoc cref="IMapping.RequestMatcher" />
|
||||
@@ -79,7 +76,7 @@ namespace WireMock
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IMapping.GetRequestMatchResult" />
|
||||
public RequestMatchResult GetRequestMatchResult(RequestMessage requestMessage, [CanBeNull] string nextState)
|
||||
public RequestMatchResult GetRequestMatchResult(RequestMessage requestMessage, string nextState)
|
||||
{
|
||||
var result = new RequestMatchResult();
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
public interface IValueMatcher: IObjectMatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the value (can be a string or an obejct).
|
||||
/// Gets the value (can be a string or an object).
|
||||
/// </summary>
|
||||
/// <returns>Value</returns>
|
||||
object Value { get; }
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace WireMock.Matchers
|
||||
@@ -11,7 +12,7 @@ namespace WireMock.Matchers
|
||||
/// <summary>
|
||||
/// The tolerance
|
||||
/// </summary>
|
||||
public const double Tolerance = 0.0001;
|
||||
public const double Tolerance = 0.000001;
|
||||
|
||||
/// <summary>
|
||||
/// The default mismatch score
|
||||
@@ -28,6 +29,16 @@ namespace WireMock.Matchers
|
||||
/// </summary>
|
||||
public const double AlmostPerfect = 0.99;
|
||||
|
||||
/// <summary>
|
||||
/// Is the value a perfect match?
|
||||
/// </summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>true/false</returns>
|
||||
public static bool IsPerfect(double value)
|
||||
{
|
||||
return Math.Abs(value - Perfect) < Tolerance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a bool to the score.
|
||||
/// </summary>
|
||||
@@ -39,7 +50,7 @@ namespace WireMock.Matchers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the score from multiple funcs.
|
||||
/// Calculates the score from multiple values.
|
||||
/// </summary>
|
||||
/// <param name="values">The values.</param>
|
||||
/// <returns>average score</returns>
|
||||
@@ -49,7 +60,7 @@ namespace WireMock.Matchers
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the score from multiple funcs.
|
||||
/// Calculates the score from multiple values.
|
||||
/// </summary>
|
||||
/// <param name="values">The values.</param>
|
||||
/// <returns>average score</returns>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Util;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Matchers.Request
|
||||
@@ -93,6 +94,7 @@ namespace WireMock.Matchers.Request
|
||||
public RequestMessageBodyMatcher([NotNull] IMatcher matcher)
|
||||
{
|
||||
Check.NotNull(matcher, nameof(matcher));
|
||||
|
||||
Matcher = matcher;
|
||||
}
|
||||
|
||||
@@ -109,47 +111,41 @@ namespace WireMock.Matchers.Request
|
||||
if (Matcher is IObjectMatcher objectMatcher)
|
||||
{
|
||||
// If the body is a JSON object, try to match.
|
||||
if (requestMessage.BodyAsJson != null)
|
||||
if (requestMessage?.BodyData?.DetectedBodyType == BodyType.Json)
|
||||
{
|
||||
return objectMatcher.IsMatch(requestMessage.BodyAsJson);
|
||||
return objectMatcher.IsMatch(requestMessage.BodyData.BodyAsJson);
|
||||
}
|
||||
|
||||
// If the body is a byte array, try to match.
|
||||
if (requestMessage.BodyAsBytes != null)
|
||||
if (requestMessage?.BodyData?.DetectedBodyType == BodyType.Bytes)
|
||||
{
|
||||
return objectMatcher.IsMatch(requestMessage.BodyAsBytes);
|
||||
return objectMatcher.IsMatch(requestMessage.BodyData.BodyAsBytes);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the matcher is a IStringMatcher
|
||||
if (Matcher is IStringMatcher stringMatcher)
|
||||
{
|
||||
// If the body is a JSON object, try to use Body (string) to match.
|
||||
if (requestMessage.BodyAsJson != null && requestMessage.Body != null)
|
||||
// If the body is a Json or a String, use the BodyAsString to match on.
|
||||
if (requestMessage?.BodyData?.DetectedBodyType == BodyType.Json || requestMessage?.BodyData?.DetectedBodyType == BodyType.String)
|
||||
{
|
||||
return stringMatcher.IsMatch(requestMessage.Body);
|
||||
}
|
||||
|
||||
// If the string body is defined, try to match.
|
||||
if (requestMessage.Body != null)
|
||||
{
|
||||
return stringMatcher.IsMatch(requestMessage.Body);
|
||||
return stringMatcher.IsMatch(requestMessage.BodyData.BodyAsString);
|
||||
}
|
||||
}
|
||||
|
||||
if (Func != null)
|
||||
{
|
||||
return MatchScores.ToScore(requestMessage.Body != null && Func(requestMessage.Body));
|
||||
}
|
||||
|
||||
if (DataFunc != null)
|
||||
{
|
||||
return MatchScores.ToScore(requestMessage.BodyAsBytes != null && DataFunc(requestMessage.BodyAsBytes));
|
||||
return MatchScores.ToScore(requestMessage?.BodyData?.DetectedBodyType == BodyType.String && Func(requestMessage.BodyData.BodyAsString));
|
||||
}
|
||||
|
||||
if (JsonFunc != null)
|
||||
{
|
||||
return MatchScores.ToScore(requestMessage.BodyAsJson != null && JsonFunc(requestMessage.BodyAsJson));
|
||||
return MatchScores.ToScore(requestMessage?.BodyData?.DetectedBodyType == BodyType.Json && JsonFunc(requestMessage.BodyData.BodyAsJson));
|
||||
}
|
||||
|
||||
if (DataFunc != null)
|
||||
{
|
||||
return MatchScores.ToScore(requestMessage?.BodyData?.DetectedBodyType == BodyType.Bytes && DataFunc(requestMessage.BodyData.BodyAsBytes));
|
||||
}
|
||||
|
||||
return MatchScores.Mismatch;
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace WireMock.Owin.Mappers
|
||||
}
|
||||
|
||||
BodyData body = null;
|
||||
if (request.Body != null && ShouldParseBody(method))
|
||||
if (request.Body != null && BodyParser.ShouldParseBody(method))
|
||||
{
|
||||
body = await BodyParser.Parse(request.Body, request.ContentType);
|
||||
}
|
||||
@@ -69,21 +69,5 @@ namespace WireMock.Owin.Mappers
|
||||
#endif
|
||||
return (urldetails, clientIP);
|
||||
}
|
||||
|
||||
private bool ShouldParseBody(string method)
|
||||
{
|
||||
/*
|
||||
HEAD - No defined body semantics.
|
||||
GET - No defined body semantics.
|
||||
PUT - Body supported.
|
||||
POST - Body supported.
|
||||
DELETE - No defined body semantics.
|
||||
TRACE - Body not supported.
|
||||
OPTIONS - Body supported but no semantics on usage (maybe in the future).
|
||||
CONNECT - No defined body semantics
|
||||
PATCH - Body supported.
|
||||
*/
|
||||
return new[] { "PUT", "POST", "OPTIONS", "PATCH" }.Contains(method.ToUpper());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,23 +45,25 @@ namespace WireMock.Owin.Mappers
|
||||
response.StatusCode = responseMessage.StatusCode;
|
||||
|
||||
byte[] bytes = null;
|
||||
if (responseMessage.BodyAsBytes != null)
|
||||
switch (responseMessage.BodyData?.DetectedBodyType)
|
||||
{
|
||||
bytes = responseMessage.BodyAsBytes;
|
||||
}
|
||||
else if (responseMessage.BodyAsFile != null)
|
||||
{
|
||||
bytes = File.ReadAllBytes(responseMessage.BodyAsFile);
|
||||
}
|
||||
else if (responseMessage.BodyAsJson != null)
|
||||
{
|
||||
Formatting formatting = responseMessage.BodyAsJsonIndented == true ? Formatting.Indented : Formatting.None;
|
||||
string jsonBody = JsonConvert.SerializeObject(responseMessage.BodyAsJson, new JsonSerializerSettings { Formatting = formatting, NullValueHandling = NullValueHandling.Ignore });
|
||||
bytes = (responseMessage.BodyEncoding ?? _utf8NoBom).GetBytes(jsonBody);
|
||||
}
|
||||
else if (responseMessage.Body != null)
|
||||
{
|
||||
bytes = (responseMessage.BodyEncoding ?? _utf8NoBom).GetBytes(responseMessage.Body);
|
||||
case BodyType.String:
|
||||
bytes = (responseMessage.BodyData.Encoding ?? _utf8NoBom).GetBytes(responseMessage.BodyData.BodyAsString);
|
||||
break;
|
||||
|
||||
case BodyType.Json:
|
||||
Formatting formatting = responseMessage.BodyData.BodyAsJsonIndented == true ? Formatting.Indented : Formatting.None;
|
||||
string jsonBody = JsonConvert.SerializeObject(responseMessage.BodyData.BodyAsJson, new JsonSerializerSettings { Formatting = formatting, NullValueHandling = NullValueHandling.Ignore });
|
||||
bytes = (responseMessage.BodyData.Encoding ?? _utf8NoBom).GetBytes(jsonBody);
|
||||
break;
|
||||
|
||||
case BodyType.Bytes:
|
||||
bytes = responseMessage.BodyData.BodyAsBytes;
|
||||
break;
|
||||
|
||||
case BodyType.File:
|
||||
bytes = File.ReadAllBytes(responseMessage.BodyData.BodyAsFile);
|
||||
break;
|
||||
}
|
||||
|
||||
SetResponseHeaders(responseMessage, response);
|
||||
|
||||
@@ -94,7 +94,7 @@ namespace WireMock.Owin
|
||||
IsStarted = true;
|
||||
|
||||
// WaitHandle is signaled when the token is cancelled,
|
||||
// which will be more efficent than Thread.Sleep in while loop
|
||||
// which will be more efficient than Thread.Sleep in while loop
|
||||
_cts.Token.WaitHandle.WaitOne();
|
||||
}
|
||||
catch (Exception e)
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace WireMock.Owin
|
||||
|
||||
public ConcurrentDictionary<string, ScenarioState> Scenarios { get; } = new ConcurrentDictionary<string, ScenarioState>();
|
||||
|
||||
public ObservableCollection<LogEntry> LogEntries { get; } = new ConcurentObservableCollection<LogEntry>();
|
||||
public ObservableCollection<LogEntry> LogEntries { get; } = new ConcurrentObservableCollection<LogEntry>();
|
||||
|
||||
public int? RequestLogExpirationDuration { get; set; }
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Net;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Models;
|
||||
@@ -81,19 +80,34 @@ namespace WireMock
|
||||
public string RawQuery { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The original body as string, this is defined when Body or BodyAsJson are not null.
|
||||
/// The body.
|
||||
/// </summary>
|
||||
public BodyData BodyData { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The original body as string. Convenience getter for Handlebars.
|
||||
/// </summary>
|
||||
public string Body { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The body (as JSON object).
|
||||
/// The body (as JSON object). Convenience getter for Handlebars.
|
||||
/// </summary>
|
||||
public object BodyAsJson { get; set; }
|
||||
public object BodyAsJson { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The body (as bytearray).
|
||||
/// The body (as bytearray). Convenience getter for Handlebars.
|
||||
/// </summary>
|
||||
public byte[] BodyAsBytes { get; set; }
|
||||
public byte[] BodyAsBytes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The detected body type. Convenience getter for Handlebars.
|
||||
/// </summary>
|
||||
public string DetectedBodyType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The detected body type from the Content-Type header. Convenience getter for Handlebars.
|
||||
/// </summary>
|
||||
public string DetectedBodyTypeFromContentType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the Host
|
||||
@@ -115,21 +129,16 @@ namespace WireMock
|
||||
/// </summary>
|
||||
public string Origin { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The body encoding.
|
||||
/// </summary>
|
||||
public Encoding BodyEncoding { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="RequestMessage"/> class.
|
||||
/// </summary>
|
||||
/// <param name="urlDetails">The original url details.</param>
|
||||
/// <param name="method">The HTTP method.</param>
|
||||
/// <param name="clientIP">The client IP Address.</param>
|
||||
/// <param name="body">The body.</param>
|
||||
/// <param name="bodyData">The BodyData.</param>
|
||||
/// <param name="headers">The headers.</param>
|
||||
/// <param name="cookies">The cookies.</param>
|
||||
public RequestMessage([NotNull] UrlDetails urlDetails, [NotNull] string method, [NotNull] string clientIP, [CanBeNull] BodyData body = null, [CanBeNull] IDictionary<string, string[]> headers = null, [CanBeNull] IDictionary<string, string> cookies = null)
|
||||
public RequestMessage([NotNull] UrlDetails urlDetails, [NotNull] string method, [NotNull] string clientIP, [CanBeNull] BodyData bodyData = null, [CanBeNull] IDictionary<string, string[]> headers = null, [CanBeNull] IDictionary<string, string> cookies = null)
|
||||
{
|
||||
Check.NotNull(urlDetails, nameof(urlDetails));
|
||||
Check.NotNull(method, nameof(method));
|
||||
@@ -150,10 +159,14 @@ namespace WireMock
|
||||
Method = method;
|
||||
ClientIP = clientIP;
|
||||
|
||||
Body = body?.BodyAsString;
|
||||
BodyEncoding = body?.Encoding;
|
||||
BodyAsJson = body?.BodyAsJson;
|
||||
BodyAsBytes = body?.BodyAsBytes;
|
||||
BodyData = bodyData;
|
||||
|
||||
// Convenience getters for e.g. Handlebars
|
||||
Body = BodyData?.BodyAsString;
|
||||
BodyAsJson = BodyData?.BodyAsJson;
|
||||
BodyAsBytes = BodyData?.BodyAsBytes;
|
||||
DetectedBodyType = BodyData?.DetectedBodyType.ToString();
|
||||
DetectedBodyTypeFromContentType = BodyData?.DetectedBodyTypeFromContentType.ToString();
|
||||
|
||||
Headers = headers?.ToDictionary(header => header.Key, header => new WireMockList<string>(header.Value));
|
||||
Cookies = cookies;
|
||||
|
||||
@@ -56,17 +56,17 @@ namespace WireMock.ResponseBuilders
|
||||
/// <summary>
|
||||
/// WithBody : Create a string response based on a Base64 string (which will be decoded to a normal string).
|
||||
/// </summary>
|
||||
/// <param name="bodyAsbase64">The body.</param>
|
||||
/// <param name="bodyAsBase64">The body.</param>
|
||||
/// <param name="encoding">The Encoding.</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
[Obsolete("Should not be used, will be removed in future.")]
|
||||
IResponseBuilder WithBodyFromBase64([NotNull] string bodyAsbase64, [CanBeNull] Encoding encoding = null);
|
||||
IResponseBuilder WithBodyFromBase64([NotNull] string bodyAsBase64, [CanBeNull] Encoding encoding = null);
|
||||
|
||||
/// <summary>
|
||||
/// WithBodyFromFile : Create a ... response based on a File.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename.</param>
|
||||
/// <param name="cache">Defines if this file is cached in memory or retrieved from disk everytime the response is created.</param>
|
||||
/// <param name="cache">Defines if this file is cached in memory or retrieved from disk every time the response is created.</param>
|
||||
/// <returns>A <see cref="IResponseBuilder"/>.</returns>
|
||||
IResponseBuilder WithBodyFromFile([NotNull] string filename, bool cache = true);
|
||||
}
|
||||
|
||||
@@ -178,9 +178,12 @@ namespace WireMock.ResponseBuilders
|
||||
|
||||
return WithCallbackInternal(false, req => new ResponseMessage
|
||||
{
|
||||
Body = bodyFactory(req),
|
||||
BodyDestination = destination,
|
||||
BodyEncoding = encoding ?? Encoding.UTF8
|
||||
BodyData = new BodyData
|
||||
{
|
||||
DetectedBodyType = BodyType.String,
|
||||
BodyAsString = bodyFactory(req),
|
||||
Encoding = encoding ?? Encoding.UTF8
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -190,19 +193,20 @@ namespace WireMock.ResponseBuilders
|
||||
Check.NotNull(body, nameof(body));
|
||||
|
||||
ResponseMessage.BodyDestination = destination;
|
||||
ResponseMessage.BodyData = new BodyData();
|
||||
|
||||
switch (destination)
|
||||
{
|
||||
case BodyDestinationFormat.String:
|
||||
var enc = encoding ?? Encoding.UTF8;
|
||||
ResponseMessage.BodyAsBytes = null;
|
||||
ResponseMessage.Body = enc.GetString(body);
|
||||
ResponseMessage.BodyEncoding = enc;
|
||||
ResponseMessage.BodyData.DetectedBodyType = BodyType.String;
|
||||
ResponseMessage.BodyData.BodyAsString = enc.GetString(body);
|
||||
ResponseMessage.BodyData.Encoding = enc;
|
||||
break;
|
||||
|
||||
default:
|
||||
ResponseMessage.BodyAsBytes = body;
|
||||
ResponseMessage.BodyEncoding = null;
|
||||
ResponseMessage.BodyData.DetectedBodyType = BodyType.Bytes;
|
||||
ResponseMessage.BodyData.BodyAsBytes = body;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -214,20 +218,20 @@ namespace WireMock.ResponseBuilders
|
||||
{
|
||||
Check.NotNull(filename, nameof(filename));
|
||||
|
||||
ResponseMessage.BodyEncoding = null;
|
||||
ResponseMessage.BodyAsFileIsCached = cache;
|
||||
ResponseMessage.BodyData = new BodyData
|
||||
{
|
||||
BodyAsFileIsCached = cache
|
||||
};
|
||||
|
||||
if (cache)
|
||||
{
|
||||
ResponseMessage.Body = null;
|
||||
ResponseMessage.BodyAsBytes = File.ReadAllBytes(filename);
|
||||
ResponseMessage.BodyAsFile = null;
|
||||
ResponseMessage.BodyData.DetectedBodyType = BodyType.Bytes;
|
||||
ResponseMessage.BodyData.BodyAsBytes = File.ReadAllBytes(filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
ResponseMessage.Body = null;
|
||||
ResponseMessage.BodyAsBytes = null;
|
||||
ResponseMessage.BodyAsFile = filename;
|
||||
ResponseMessage.BodyData.DetectedBodyType = BodyType.File;
|
||||
ResponseMessage.BodyData.BodyAsFile = filename;
|
||||
}
|
||||
|
||||
return this;
|
||||
@@ -241,26 +245,27 @@ namespace WireMock.ResponseBuilders
|
||||
encoding = encoding ?? Encoding.UTF8;
|
||||
|
||||
ResponseMessage.BodyDestination = destination;
|
||||
ResponseMessage.BodyEncoding = encoding;
|
||||
|
||||
ResponseMessage.BodyData = new BodyData
|
||||
{
|
||||
Encoding = encoding
|
||||
};
|
||||
|
||||
switch (destination)
|
||||
{
|
||||
case BodyDestinationFormat.Bytes:
|
||||
ResponseMessage.Body = null;
|
||||
ResponseMessage.BodyAsJson = null;
|
||||
ResponseMessage.BodyAsBytes = encoding.GetBytes(body);
|
||||
ResponseMessage.BodyData.DetectedBodyType = BodyType.Bytes;
|
||||
ResponseMessage.BodyData.BodyAsBytes= encoding.GetBytes(body);
|
||||
break;
|
||||
|
||||
case BodyDestinationFormat.Json:
|
||||
ResponseMessage.Body = null;
|
||||
ResponseMessage.BodyAsJson = JsonConvert.DeserializeObject(body);
|
||||
ResponseMessage.BodyAsBytes = null;
|
||||
ResponseMessage.BodyData.DetectedBodyType = BodyType.Json;
|
||||
ResponseMessage.BodyData.BodyAsJson = JsonConvert.DeserializeObject(body);
|
||||
break;
|
||||
|
||||
default:
|
||||
ResponseMessage.Body = body;
|
||||
ResponseMessage.BodyAsJson = null;
|
||||
ResponseMessage.BodyAsBytes = null;
|
||||
ResponseMessage.BodyData.DetectedBodyType = BodyType.String;
|
||||
ResponseMessage.BodyData.BodyAsString = body;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -273,10 +278,14 @@ namespace WireMock.ResponseBuilders
|
||||
Check.NotNull(body, nameof(body));
|
||||
|
||||
ResponseMessage.BodyDestination = null;
|
||||
ResponseMessage.BodyAsJson = body;
|
||||
ResponseMessage.BodyEncoding = encoding;
|
||||
ResponseMessage.BodyAsJsonIndented = indented;
|
||||
|
||||
ResponseMessage.BodyData = new BodyData
|
||||
{
|
||||
Encoding = encoding,
|
||||
DetectedBodyType = BodyType.Json,
|
||||
BodyAsJson = body,
|
||||
BodyAsJsonIndented = indented
|
||||
};
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -287,15 +296,18 @@ namespace WireMock.ResponseBuilders
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="IBodyResponseBuilder.WithBodyFromBase64"/>
|
||||
public IResponseBuilder WithBodyFromBase64(string bodyAsbase64, Encoding encoding = null)
|
||||
public IResponseBuilder WithBodyFromBase64(string bodyAsBase64, Encoding encoding = null)
|
||||
{
|
||||
Check.NotNull(bodyAsbase64, nameof(bodyAsbase64));
|
||||
Check.NotNull(bodyAsBase64, nameof(bodyAsBase64));
|
||||
|
||||
encoding = encoding ?? Encoding.UTF8;
|
||||
|
||||
ResponseMessage.BodyDestination = null;
|
||||
ResponseMessage.Body = encoding.GetString(Convert.FromBase64String(bodyAsbase64));
|
||||
ResponseMessage.BodyEncoding = encoding;
|
||||
ResponseMessage.BodyData = new BodyData
|
||||
{
|
||||
Encoding = encoding,
|
||||
DetectedBodyType = BodyType.String,
|
||||
BodyAsString = encoding.GetString(Convert.FromBase64String(bodyAsBase64))
|
||||
};
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using WireMock.Util;
|
||||
using WireMock.Validation;
|
||||
|
||||
@@ -32,39 +31,9 @@ namespace WireMock
|
||||
public string BodyDestination { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the body as a string.
|
||||
/// The Body.
|
||||
/// </summary>
|
||||
public string Body { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the body as a json object.
|
||||
/// </summary>
|
||||
public object BodyAsJson { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether child objects to be indented according to the Newtonsoft.Json.JsonTextWriter.Indentation and Newtonsoft.Json.JsonTextWriter.IndentChar settings.
|
||||
/// </summary>
|
||||
public bool? BodyAsJsonIndented { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the body as bytes.
|
||||
/// </summary>
|
||||
public byte[] BodyAsBytes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the body as a file.
|
||||
/// </summary>
|
||||
public string BodyAsFile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Is the body as file cached?
|
||||
/// </summary>
|
||||
public bool? BodyAsFileIsCached { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the body encoding.
|
||||
/// </summary>
|
||||
public Encoding BodyEncoding { get; set; } = new UTF8Encoding(false);
|
||||
public BodyData BodyData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Adds the header.
|
||||
|
||||
@@ -16,10 +16,18 @@ namespace WireMock
|
||||
var response = new ResponseMessage
|
||||
{
|
||||
StatusCode = statusCode,
|
||||
Headers = ContentTypeJsonHeaders,
|
||||
BodyAsJson = message != null ? new StatusModel { Status = message, Guid = guid } : null
|
||||
Headers = ContentTypeJsonHeaders
|
||||
};
|
||||
|
||||
if (message != null)
|
||||
{
|
||||
response.BodyData = new BodyData
|
||||
{
|
||||
DetectedBodyType = BodyType.Json,
|
||||
BodyAsJson = new StatusModel { Status = message, Guid = guid }
|
||||
};
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
using WireMock.Admin.Mappings;
|
||||
using WireMock.Admin.Requests;
|
||||
using WireMock.Logging;
|
||||
using WireMock.Util;
|
||||
|
||||
namespace WireMock.Serialization
|
||||
{
|
||||
@@ -9,51 +10,102 @@ namespace WireMock.Serialization
|
||||
{
|
||||
public static LogEntryModel Map(LogEntry logEntry)
|
||||
{
|
||||
var logRequestModel = new LogRequestModel
|
||||
{
|
||||
DateTime = logEntry.RequestMessage.DateTime,
|
||||
ClientIP = logEntry.RequestMessage.ClientIP,
|
||||
Path = logEntry.RequestMessage.Path,
|
||||
AbsolutePath = logEntry.RequestMessage.AbsolutePath,
|
||||
Url = logEntry.RequestMessage.Url,
|
||||
AbsoluteUrl = logEntry.RequestMessage.AbsoluteUrl,
|
||||
Query = logEntry.RequestMessage.Query,
|
||||
Method = logEntry.RequestMessage.Method,
|
||||
Headers = logEntry.RequestMessage.Headers,
|
||||
Cookies = logEntry.RequestMessage.Cookies
|
||||
};
|
||||
|
||||
if (logEntry.RequestMessage.BodyData != null)
|
||||
{
|
||||
logRequestModel.DetectedBodyType = logEntry.RequestMessage.BodyData.DetectedBodyType.ToString();
|
||||
logRequestModel.DetectedBodyTypeFromContentType = logEntry.RequestMessage.BodyData.DetectedBodyTypeFromContentType.ToString();
|
||||
|
||||
switch (logEntry.RequestMessage.BodyData.DetectedBodyType)
|
||||
{
|
||||
case BodyType.String:
|
||||
logRequestModel.Body = logEntry.RequestMessage.BodyData.BodyAsString;
|
||||
break;
|
||||
|
||||
case BodyType.Json:
|
||||
logRequestModel.Body = logEntry.RequestMessage.BodyData.BodyAsString; // In case of Json, do also save the Body as string (backwards compatible)
|
||||
logRequestModel.BodyAsJson = logEntry.RequestMessage.BodyData.BodyAsJson;
|
||||
break;
|
||||
|
||||
case BodyType.Bytes:
|
||||
logRequestModel.BodyAsBytes = logEntry.RequestMessage.BodyData.BodyAsBytes;
|
||||
break;
|
||||
}
|
||||
|
||||
logRequestModel.BodyEncoding = logEntry.RequestMessage.BodyData.Encoding != null
|
||||
? new EncodingModel
|
||||
{
|
||||
EncodingName = logEntry.RequestMessage.BodyData.Encoding.EncodingName,
|
||||
CodePage = logEntry.RequestMessage.BodyData.Encoding.CodePage,
|
||||
WebName = logEntry.RequestMessage.BodyData.Encoding.WebName
|
||||
}
|
||||
: null;
|
||||
}
|
||||
|
||||
var logResponseModel = new LogResponseModel
|
||||
{
|
||||
StatusCode = logEntry.ResponseMessage.StatusCode,
|
||||
Headers = logEntry.ResponseMessage.Headers
|
||||
};
|
||||
|
||||
if (logEntry.ResponseMessage.BodyData != null)
|
||||
{
|
||||
logResponseModel.BodyOriginal = logEntry.ResponseMessage.BodyOriginal;
|
||||
logResponseModel.BodyDestination = logEntry.ResponseMessage.BodyDestination;
|
||||
|
||||
logResponseModel.DetectedBodyType = logEntry.ResponseMessage.BodyData.DetectedBodyType;
|
||||
logResponseModel.DetectedBodyTypeFromContentType = logEntry.ResponseMessage.BodyData.DetectedBodyTypeFromContentType;
|
||||
|
||||
switch (logEntry.ResponseMessage.BodyData.DetectedBodyType)
|
||||
{
|
||||
case BodyType.String:
|
||||
logResponseModel.Body = logEntry.ResponseMessage.BodyData.BodyAsString;
|
||||
break;
|
||||
|
||||
case BodyType.Json:
|
||||
logResponseModel.BodyAsJson = logEntry.ResponseMessage.BodyData.BodyAsJson;
|
||||
break;
|
||||
|
||||
case BodyType.Bytes:
|
||||
logResponseModel.BodyAsBytes = logEntry.ResponseMessage.BodyData.BodyAsBytes;
|
||||
break;
|
||||
|
||||
case BodyType.File:
|
||||
logResponseModel.BodyAsFile = logEntry.ResponseMessage.BodyData.BodyAsFile;
|
||||
logResponseModel.BodyAsFileIsCached = logEntry.ResponseMessage.BodyData.BodyAsFileIsCached;
|
||||
break;
|
||||
}
|
||||
|
||||
logResponseModel.BodyEncoding = logEntry.ResponseMessage.BodyData.Encoding != null
|
||||
? new EncodingModel
|
||||
{
|
||||
EncodingName = logEntry.ResponseMessage.BodyData.Encoding.EncodingName,
|
||||
CodePage = logEntry.ResponseMessage.BodyData.Encoding.CodePage,
|
||||
WebName = logEntry.ResponseMessage.BodyData.Encoding.WebName
|
||||
}
|
||||
: null;
|
||||
}
|
||||
|
||||
return new LogEntryModel
|
||||
{
|
||||
Guid = logEntry.Guid,
|
||||
Request = new LogRequestModel
|
||||
{
|
||||
DateTime = logEntry.RequestMessage.DateTime,
|
||||
ClientIP = logEntry.RequestMessage.ClientIP,
|
||||
Path = logEntry.RequestMessage.Path,
|
||||
AbsolutePath = logEntry.RequestMessage.AbsolutePath,
|
||||
Url = logEntry.RequestMessage.Url,
|
||||
AbsoluteUrl = logEntry.RequestMessage.AbsoluteUrl,
|
||||
Query = logEntry.RequestMessage.Query,
|
||||
Method = logEntry.RequestMessage.Method,
|
||||
Body = logEntry.RequestMessage.Body,
|
||||
BodyAsJson = logEntry.RequestMessage.BodyAsJson,
|
||||
BodyAsBytes = logEntry.RequestMessage.BodyAsBytes,
|
||||
Headers = logEntry.RequestMessage.Headers,
|
||||
Cookies = logEntry.RequestMessage.Cookies,
|
||||
BodyEncoding = logEntry.RequestMessage.BodyEncoding != null ? new EncodingModel
|
||||
{
|
||||
EncodingName = logEntry.RequestMessage.BodyEncoding.EncodingName,
|
||||
CodePage = logEntry.RequestMessage.BodyEncoding.CodePage,
|
||||
WebName = logEntry.RequestMessage.BodyEncoding.WebName
|
||||
} : null
|
||||
},
|
||||
Response = new LogResponseModel
|
||||
{
|
||||
StatusCode = logEntry.ResponseMessage.StatusCode,
|
||||
BodyDestination = logEntry.ResponseMessage.BodyDestination,
|
||||
Body = logEntry.ResponseMessage.Body,
|
||||
BodyAsJson = logEntry.ResponseMessage.BodyAsJson,
|
||||
BodyAsBytes = logEntry.ResponseMessage.BodyAsBytes,
|
||||
BodyOriginal = logEntry.ResponseMessage.BodyOriginal,
|
||||
BodyAsFile = logEntry.ResponseMessage.BodyAsFile,
|
||||
BodyAsFileIsCached = logEntry.ResponseMessage.BodyAsFileIsCached,
|
||||
Headers = logEntry.ResponseMessage.Headers,
|
||||
BodyEncoding = logEntry.ResponseMessage.BodyEncoding != null ? new EncodingModel
|
||||
{
|
||||
EncodingName = logEntry.ResponseMessage.BodyEncoding.EncodingName,
|
||||
CodePage = logEntry.ResponseMessage.BodyEncoding.CodePage,
|
||||
WebName = logEntry.ResponseMessage.BodyEncoding.WebName
|
||||
} : null
|
||||
},
|
||||
MappingGuid = logEntry.MappingGuid,
|
||||
MappingTitle = logEntry.MappingTitle,
|
||||
Request = logRequestModel,
|
||||
Response = logResponseModel,
|
||||
RequestMatchResult = logEntry.RequestMatchResult != null ? new LogRequestMatchModel
|
||||
{
|
||||
TotalScore = logEntry.RequestMatchResult.TotalScore,
|
||||
|
||||
@@ -100,22 +100,40 @@ namespace WireMock.Serialization
|
||||
mappingModel.Response.BodyDestination = response.ResponseMessage.BodyDestination;
|
||||
mappingModel.Response.StatusCode = response.ResponseMessage.StatusCode;
|
||||
mappingModel.Response.Headers = Map(response.ResponseMessage.Headers);
|
||||
mappingModel.Response.BodyAsJson = response.ResponseMessage.BodyAsJson;
|
||||
mappingModel.Response.BodyAsJsonIndented = response.ResponseMessage.BodyAsJsonIndented;
|
||||
mappingModel.Response.Body = response.ResponseMessage.Body;
|
||||
mappingModel.Response.BodyAsBytes = response.ResponseMessage.BodyAsBytes;
|
||||
mappingModel.Response.BodyAsFile = response.ResponseMessage.BodyAsFile;
|
||||
mappingModel.Response.BodyAsFileIsCached = response.ResponseMessage.BodyAsFileIsCached;
|
||||
mappingModel.Response.UseTransformer = response.UseTransformer;
|
||||
|
||||
if (response.ResponseMessage.BodyEncoding != null && response.ResponseMessage.BodyEncoding.WebName != "utf-8")
|
||||
if (response.ResponseMessage.BodyData != null)
|
||||
{
|
||||
mappingModel.Response.BodyEncoding = new EncodingModel
|
||||
switch (response.ResponseMessage.BodyData?.DetectedBodyType)
|
||||
{
|
||||
EncodingName = response.ResponseMessage.BodyEncoding.EncodingName,
|
||||
CodePage = response.ResponseMessage.BodyEncoding.CodePage,
|
||||
WebName = response.ResponseMessage.BodyEncoding.WebName
|
||||
};
|
||||
case BodyType.String:
|
||||
mappingModel.Response.Body = response.ResponseMessage.BodyData.BodyAsString;
|
||||
break;
|
||||
|
||||
case BodyType.Json:
|
||||
mappingModel.Response.BodyAsJson = response.ResponseMessage.BodyData.BodyAsJson;
|
||||
mappingModel.Response.BodyAsJsonIndented = response.ResponseMessage.BodyData.BodyAsJsonIndented;
|
||||
break;
|
||||
|
||||
case BodyType.Bytes:
|
||||
mappingModel.Response.BodyAsBytes = response.ResponseMessage.BodyData.BodyAsBytes;
|
||||
break;
|
||||
|
||||
case BodyType.File:
|
||||
mappingModel.Response.BodyAsFile = response.ResponseMessage.BodyData.BodyAsFile;
|
||||
mappingModel.Response.BodyAsFileIsCached = response.ResponseMessage.BodyData.BodyAsFileIsCached;
|
||||
break;
|
||||
}
|
||||
|
||||
if (response.ResponseMessage.BodyData.Encoding != null && response.ResponseMessage.BodyData.Encoding.WebName != "utf-8")
|
||||
{
|
||||
mappingModel.Response.BodyEncoding = new EncodingModel
|
||||
{
|
||||
EncodingName = response.ResponseMessage.BodyData.Encoding.EncodingName,
|
||||
CodePage = response.ResponseMessage.BodyData.Encoding.CodePage,
|
||||
WebName = response.ResponseMessage.BodyData.Encoding.WebName
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -274,13 +274,13 @@ namespace WireMock.Server
|
||||
}
|
||||
});
|
||||
|
||||
if (requestMessage.BodyAsJson != null)
|
||||
if (requestMessage.BodyData?.DetectedBodyType == BodyType.Json)
|
||||
{
|
||||
request.WithBody(new JsonMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyAsJson));
|
||||
request.WithBody(new JsonMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsJson));
|
||||
}
|
||||
else if (requestMessage.Body != null)
|
||||
else if (requestMessage.BodyData?.DetectedBodyType == BodyType.String)
|
||||
{
|
||||
request.WithBody(new ExactMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.Body));
|
||||
request.WithBody(new ExactMatcher(MatchBehaviour.AcceptOnMatch, requestMessage.BodyData.BodyAsString));
|
||||
}
|
||||
|
||||
var response = Response.Create(responseMessage);
|
||||
@@ -764,9 +764,13 @@ namespace WireMock.Server
|
||||
{
|
||||
return new ResponseMessage
|
||||
{
|
||||
Body = JsonConvert.SerializeObject(result, keepNullValues ? _settingsIncludeNullValues : _settings),
|
||||
BodyData = new BodyData
|
||||
{
|
||||
DetectedBodyType = BodyType.String,
|
||||
BodyAsString = JsonConvert.SerializeObject(result, keepNullValues ? _settingsIncludeNullValues : _settings)
|
||||
},
|
||||
StatusCode = 200,
|
||||
Headers = new Dictionary<string, WireMockList<string>> { { HttpKnownHeaderNames.ContentType, new WireMockList<string>("application/json") } }
|
||||
Headers = new Dictionary<string, WireMockList<string>> { { HttpKnownHeaderNames.ContentType, new WireMockList<string>(ContentTypeJson) } }
|
||||
};
|
||||
}
|
||||
|
||||
@@ -777,9 +781,17 @@ namespace WireMock.Server
|
||||
|
||||
private T DeserializeObject<T>(RequestMessage requestMessage)
|
||||
{
|
||||
return requestMessage.Body != null ?
|
||||
JsonConvert.DeserializeObject<T>(requestMessage.Body) :
|
||||
((JObject)requestMessage.BodyAsJson).ToObject<T>();
|
||||
if (requestMessage?.BodyData?.DetectedBodyType == BodyType.String)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<T>(requestMessage.BodyData.BodyAsString);
|
||||
}
|
||||
|
||||
if (requestMessage?.BodyData?.DetectedBodyType == BodyType.Json)
|
||||
{
|
||||
return ((JObject)requestMessage.BodyData.BodyAsJson).ToObject<T>();
|
||||
}
|
||||
|
||||
return default(T);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using WireMock.Handlers;
|
||||
using WireMock.Logging;
|
||||
|
||||
@@ -50,14 +50,12 @@ namespace WireMock.Transformers
|
||||
|
||||
string ParseAsString(object arg)
|
||||
{
|
||||
if (arg is string)
|
||||
if (arg is string argAsString)
|
||||
{
|
||||
return (string) arg;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotSupportedException($"The value '{arg}' with type '{arg?.GetType()}' cannot be used in Handlebars Regex.");
|
||||
return argAsString;
|
||||
}
|
||||
|
||||
throw new NotSupportedException($"The value '{arg}' with type '{arg?.GetType()}' cannot be used in Handlebars Regex.");
|
||||
}
|
||||
|
||||
return (ParseAsString(arguments[0]), ParseAsString(arguments[1]), arguments.Length == 3 ? arguments[2] : null);
|
||||
|
||||
@@ -17,12 +17,12 @@ namespace WireMock.Transformers
|
||||
|
||||
public static ResponseMessage Transform(RequestMessage requestMessage, ResponseMessage original)
|
||||
{
|
||||
bool bodyIsJson = original.BodyAsJson != null;
|
||||
bool bodyIsJson = original.BodyData.DetectedBodyType == BodyType.Json;
|
||||
var responseMessage = new ResponseMessage { StatusCode = original.StatusCode };
|
||||
|
||||
if (!bodyIsJson)
|
||||
{
|
||||
responseMessage.BodyOriginal = original.Body;
|
||||
responseMessage.BodyOriginal = original.BodyData.BodyAsString;
|
||||
}
|
||||
|
||||
var template = new { request = requestMessage };
|
||||
@@ -57,7 +57,7 @@ namespace WireMock.Transformers
|
||||
private static void TransformBodyAsJson(object template, ResponseMessage original, ResponseMessage responseMessage)
|
||||
{
|
||||
JToken jToken;
|
||||
switch (original.BodyAsJson)
|
||||
switch (original.BodyData.BodyAsJson)
|
||||
{
|
||||
case JObject bodyAsJObject:
|
||||
jToken = bodyAsJObject;
|
||||
@@ -68,13 +68,18 @@ namespace WireMock.Transformers
|
||||
break;
|
||||
|
||||
default:
|
||||
jToken = JObject.FromObject(original.BodyAsJson);
|
||||
jToken = JObject.FromObject(original.BodyData.BodyAsJson);
|
||||
break;
|
||||
}
|
||||
|
||||
WalkNode(jToken, template);
|
||||
|
||||
responseMessage.BodyAsJson = jToken;
|
||||
responseMessage.BodyData = new BodyData
|
||||
{
|
||||
DetectedBodyType = original.BodyData.DetectedBodyType,
|
||||
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
|
||||
BodyAsJson = jToken
|
||||
};
|
||||
}
|
||||
|
||||
private static void WalkNode(JToken node, object template)
|
||||
@@ -127,9 +132,14 @@ namespace WireMock.Transformers
|
||||
|
||||
private static void TransformBodyAsString(object template, ResponseMessage original, ResponseMessage responseMessage)
|
||||
{
|
||||
var templateBody = Handlebars.Compile(original.Body);
|
||||
var templateBody = Handlebars.Compile(original.BodyData.BodyAsString);
|
||||
|
||||
responseMessage.Body = templateBody(template);
|
||||
responseMessage.BodyData = new BodyData
|
||||
{
|
||||
DetectedBodyType = original.BodyData.DetectedBodyType,
|
||||
DetectedBodyTypeFromContentType = original.BodyData.DetectedBodyTypeFromContentType,
|
||||
BodyAsString = templateBody(template)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,5 +26,30 @@ namespace WireMock.Util
|
||||
/// The body (as bytearray).
|
||||
/// </summary>
|
||||
public byte[] BodyAsBytes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether child objects to be indented according to the Newtonsoft.Json.JsonTextWriter.Indentation and Newtonsoft.Json.JsonTextWriter.IndentChar settings.
|
||||
/// </summary>
|
||||
public bool? BodyAsJsonIndented { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the body as a file.
|
||||
/// </summary>
|
||||
public string BodyAsFile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Is the body as file cached?
|
||||
/// </summary>
|
||||
public bool? BodyAsFileIsCached { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The detected body type (detection based on body content).
|
||||
/// </summary>
|
||||
public BodyType DetectedBodyType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The detected body type (detection based on Content-Type).
|
||||
/// </summary>
|
||||
public BodyType DetectedBodyTypeFromContentType { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -4,36 +4,112 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using JetBrains.Annotations;
|
||||
using MimeKit;
|
||||
using Newtonsoft.Json;
|
||||
using WireMock.Matchers;
|
||||
using WireMock.Validation;
|
||||
|
||||
namespace WireMock.Util
|
||||
{
|
||||
internal static class BodyParser
|
||||
{
|
||||
private static readonly string[] JsonContentTypes =
|
||||
{
|
||||
"application/json",
|
||||
"application/vnd.api+json"
|
||||
private static readonly Encoding DefaultEncoding = Encoding.UTF8;
|
||||
|
||||
/*
|
||||
HEAD - No defined body semantics.
|
||||
GET - No defined body semantics.
|
||||
PUT - Body supported.
|
||||
POST - Body supported.
|
||||
DELETE - No defined body semantics.
|
||||
TRACE - Body not supported.
|
||||
OPTIONS - Body supported but no semantics on usage (maybe in the future).
|
||||
CONNECT - No defined body semantics
|
||||
PATCH - Body supported.
|
||||
*/
|
||||
private static readonly string[] AllowedBodyParseMethods = { "PUT", "POST", "OPTIONS", "PATCH" };
|
||||
|
||||
private static readonly IStringMatcher[] JsonContentTypesMatchers = {
|
||||
new WildcardMatcher("application/json", true),
|
||||
new WildcardMatcher("application/vnd.*+json", true)
|
||||
};
|
||||
|
||||
private static readonly string[] TextContentTypes =
|
||||
private static readonly IStringMatcher[] TextContentTypeMatchers =
|
||||
{
|
||||
"text/",
|
||||
"application/javascript", "application/typescript",
|
||||
"application/xml", "application/xhtml+xml",
|
||||
"application/x-www-form-urlencoded"
|
||||
new WildcardMatcher("text/*", true),
|
||||
new RegexMatcher("^application\\/(java|type)script$", true),
|
||||
new WildcardMatcher("application/*xml", true),
|
||||
new WildcardMatcher("application/x-www-form-urlencoded", true)
|
||||
};
|
||||
|
||||
private static async Task<Tuple<string, Encoding>> ReadStringAsync(Stream stream)
|
||||
public static bool ParseBodyAsIsValid([CanBeNull] string parseBodyAs)
|
||||
{
|
||||
using (var streamReader = new StreamReader(stream))
|
||||
{
|
||||
string content = await streamReader.ReadToEndAsync();
|
||||
|
||||
return new Tuple<string, Encoding>(content, streamReader.CurrentEncoding);
|
||||
}
|
||||
return Enum.TryParse(parseBodyAs, out BodyType _);
|
||||
}
|
||||
|
||||
public static bool ShouldParseBody([CanBeNull] string method)
|
||||
{
|
||||
return AllowedBodyParseMethods.Contains(method, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
public static BodyType DetectBodyTypeFromContentType([CanBeNull] string contentTypeValue)
|
||||
{
|
||||
if (string.IsNullOrEmpty(contentTypeValue) || !ContentType.TryParse(contentTypeValue, out ContentType contentType))
|
||||
{
|
||||
return BodyType.Bytes;
|
||||
}
|
||||
|
||||
if (TextContentTypeMatchers.Any(matcher => MatchScores.IsPerfect(matcher.IsMatch(contentType.MimeType))))
|
||||
{
|
||||
return BodyType.String;
|
||||
}
|
||||
|
||||
if (JsonContentTypesMatchers.Any(matcher => MatchScores.IsPerfect(matcher.IsMatch(contentType.MimeType))))
|
||||
{
|
||||
return BodyType.Json;
|
||||
}
|
||||
|
||||
return BodyType.Bytes;
|
||||
}
|
||||
|
||||
public static async Task<BodyData> Parse([NotNull] Stream stream, [CanBeNull] string contentType)
|
||||
{
|
||||
Check.NotNull(stream, nameof(stream));
|
||||
|
||||
var data = new BodyData
|
||||
{
|
||||
BodyAsBytes = await ReadBytesAsync(stream),
|
||||
DetectedBodyType = BodyType.Bytes,
|
||||
DetectedBodyTypeFromContentType = DetectBodyTypeFromContentType(contentType)
|
||||
};
|
||||
|
||||
// Try to get the body as String
|
||||
try
|
||||
{
|
||||
data.BodyAsString = DefaultEncoding.GetString(data.BodyAsBytes);
|
||||
data.Encoding = DefaultEncoding;
|
||||
data.DetectedBodyType = BodyType.String;
|
||||
|
||||
// If string is not null or empty, try to get as Json
|
||||
if (!string.IsNullOrEmpty(data.BodyAsString))
|
||||
{
|
||||
try
|
||||
{
|
||||
data.BodyAsJson = JsonConvert.DeserializeObject(data.BodyAsString, new JsonSerializerSettings { Formatting = Formatting.Indented });
|
||||
data.DetectedBodyType = BodyType.Json;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// JsonConvert failed, just ignore.
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Reading as string failed, just ignore
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
private static async Task<byte[]> ReadBytesAsync(Stream stream)
|
||||
{
|
||||
using (var memoryStream = new MemoryStream())
|
||||
@@ -42,47 +118,5 @@ namespace WireMock.Util
|
||||
return memoryStream.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<BodyData> Parse([NotNull] Stream stream, [CanBeNull] string contentTypeHeaderValue)
|
||||
{
|
||||
var data = new BodyData();
|
||||
|
||||
if (contentTypeHeaderValue != null && TextContentTypes.Any(text => contentTypeHeaderValue.StartsWith(text, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
try
|
||||
{
|
||||
var stringData = await ReadStringAsync(stream);
|
||||
data.BodyAsString = stringData.Item1;
|
||||
data.Encoding = stringData.Item2;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Reading as string failed, just get the ByteArray.
|
||||
data.BodyAsBytes = await ReadBytesAsync(stream);
|
||||
}
|
||||
}
|
||||
else if (contentTypeHeaderValue != null && JsonContentTypes.Any(json => contentTypeHeaderValue.StartsWith(json, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
var stringData = await ReadStringAsync(stream);
|
||||
data.BodyAsString = stringData.Item1;
|
||||
data.Encoding = stringData.Item2;
|
||||
|
||||
try
|
||||
{
|
||||
data.BodyAsJson = JsonConvert.DeserializeObject(stringData.Item1, new JsonSerializerSettings { Formatting = Formatting.Indented });
|
||||
}
|
||||
catch
|
||||
{
|
||||
// JsonConvert failed, just set the Body as string.
|
||||
data.BodyAsString = stringData.Item1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
data.BodyAsBytes = await ReadBytesAsync(stream);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
33
src/WireMock.Net/Util/BodyType.cs
Normal file
33
src/WireMock.Net/Util/BodyType.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
namespace WireMock.Util
|
||||
{
|
||||
/// <summary>
|
||||
/// The BodyType
|
||||
/// </summary>
|
||||
public enum BodyType
|
||||
{
|
||||
/// <summary>
|
||||
/// No body present
|
||||
/// </summary>
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// Body is a String
|
||||
/// </summary>
|
||||
String,
|
||||
|
||||
/// <summary>
|
||||
/// Body is a Json object
|
||||
/// </summary>
|
||||
Json,
|
||||
|
||||
/// <summary>
|
||||
/// Body is a Byte array
|
||||
/// </summary>
|
||||
Bytes,
|
||||
|
||||
/// <summary>
|
||||
/// Body is a File
|
||||
/// </summary>
|
||||
File
|
||||
}
|
||||
}
|
||||
@@ -8,26 +8,26 @@ namespace WireMock.Util
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of elements in the collection.</typeparam>
|
||||
/// <inheritdoc cref="ObservableCollection{T}" />
|
||||
public class ConcurentObservableCollection<T> : ObservableCollection<T>
|
||||
public class ConcurrentObservableCollection<T> : ObservableCollection<T>
|
||||
{
|
||||
private readonly object _lockObject = new object();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:WireMock.Util.ConcurentObservableCollection`1" /> class.
|
||||
/// Initializes a new instance of the <see cref="T:WireMock.Util.ConcurrentObservableCollection`1" /> class.
|
||||
/// </summary>
|
||||
public ConcurentObservableCollection() { }
|
||||
public ConcurrentObservableCollection() { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ConcurentObservableCollection{T}"/> class that contains elements copied from the specified list.
|
||||
/// Initializes a new instance of the <see cref="ConcurrentObservableCollection{T}"/> class that contains elements copied from the specified list.
|
||||
/// </summary>
|
||||
/// <param name="list">The list from which the elements are copied.</param>
|
||||
public ConcurentObservableCollection(List<T> list) : base(list) { }
|
||||
public ConcurrentObservableCollection(List<T> list) : base(list) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ConcurentObservableCollection{T}"/> class that contains elements copied from the specified collection.
|
||||
/// Initializes a new instance of the <see cref="ConcurrentObservableCollection{T}"/> class that contains elements copied from the specified collection.
|
||||
/// </summary>
|
||||
/// <param name="collection">The collection from which the elements are copied.</param>
|
||||
public ConcurentObservableCollection(IEnumerable<T> collection) : base(collection) { }
|
||||
public ConcurrentObservableCollection(IEnumerable<T> collection) : base(collection) { }
|
||||
|
||||
/// <inheritdoc cref="ObservableCollection{T}.ClearItems"/>
|
||||
protected override void ClearItems()
|
||||
@@ -11,16 +11,16 @@ namespace WireMock.Util
|
||||
private const int NumberOfRetries = 3;
|
||||
private const int DelayOnRetry = 500;
|
||||
|
||||
public static string ReadAllTextWithRetryAndDelay([NotNull] IFileSystemHandler filehandler, [NotNull] string path)
|
||||
public static string ReadAllTextWithRetryAndDelay([NotNull] IFileSystemHandler handler, [NotNull] string path)
|
||||
{
|
||||
Check.NotNull(filehandler, nameof(filehandler));
|
||||
Check.NotNull(handler, nameof(handler));
|
||||
Check.NotNullOrEmpty(path, nameof(path));
|
||||
|
||||
for (int i = 1; i <= NumberOfRetries; ++i)
|
||||
{
|
||||
try
|
||||
{
|
||||
return filehandler.ReadMappingFile(path);
|
||||
return handler.ReadMappingFile(path);
|
||||
}
|
||||
catch
|
||||
{
|
||||
|
||||
@@ -92,7 +92,7 @@ namespace WireMock.Util
|
||||
|
||||
private static void ProcessItem(JToken node, string path, string propertyName, List<string> lines)
|
||||
{
|
||||
string castText = string.Empty;
|
||||
string castText;
|
||||
switch (node.Type)
|
||||
{
|
||||
case JTokenType.Boolean:
|
||||
@@ -132,8 +132,7 @@ namespace WireMock.Util
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new NotSupportedException(
|
||||
$"JTokenType '{node.Type}' cannot be converted to a Dynamic Linq cast operator.");
|
||||
throw new NotSupportedException($"JTokenType '{node.Type}' cannot be converted to a Dynamic Linq cast operator.");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(propertyName))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using JetBrains.Annotations;
|
||||
using WireMock.Models;
|
||||
using WireMock.Validation;
|
||||
#if !USE_ASPNETCORE
|
||||
using Microsoft.Owin;
|
||||
#else
|
||||
@@ -13,6 +14,8 @@ namespace WireMock.Util
|
||||
{
|
||||
public static UrlDetails Parse([NotNull] Uri uri, PathString pathBase)
|
||||
{
|
||||
Check.NotNull(uri, nameof(uri));
|
||||
|
||||
if (!pathBase.HasValue)
|
||||
{
|
||||
return new UrlDetails(uri, uri);
|
||||
@@ -26,7 +29,7 @@ namespace WireMock.Util
|
||||
|
||||
private static string RemoveFirst(string text, string search)
|
||||
{
|
||||
int pos = text.IndexOf(search);
|
||||
int pos = text.IndexOf(search, StringComparison.Ordinal);
|
||||
if (pos < 0)
|
||||
{
|
||||
return text;
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
<PropertyGroup>
|
||||
<Description>Lightweight Http Mocking Server for .Net, inspired by WireMock from the Java landscape.</Description>
|
||||
<AssemblyTitle>WireMock.Net</AssemblyTitle>
|
||||
<Version>1.0.4.18</Version>
|
||||
<Authors>Stef Heyenrath</Authors>
|
||||
<TargetFrameworks>net451;net452;net46;net461;netstandard1.3;netstandard2.0</TargetFrameworks>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
@@ -21,6 +20,8 @@
|
||||
<IncludeSource>True</IncludeSource>
|
||||
<IncludeSymbols>True</IncludeSymbols>
|
||||
<ProjectGuid>{D3804228-91F4-4502-9595-39584E5A01AD}</ProjectGuid>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
@@ -47,57 +48,66 @@
|
||||
</PackageReference>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
|
||||
<PackageReference Include="SimMetrics.Net" Version="1.0.4" />
|
||||
<PackageReference Include="System.Net.Http" Version="4.3.3" />
|
||||
<PackageReference Include="RestEase" Version="1.4.4" />
|
||||
<PackageReference Include="MimeKitLite" Version="2.0.1" />
|
||||
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.0.8.18" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net451' ">
|
||||
<PackageReference Include="Handlebars.Net" Version="1.9.0" />
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.OwinSelfHost" Version="5.2.6" />
|
||||
<PackageReference Include="XPath2" Version="1.0.5.1" />
|
||||
<!-- Required for WebRequestHandler -->
|
||||
<Reference Include="System.Net.Http.WebRequest" />
|
||||
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.OwinSelfHost" Version="5.2.6" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||
|
||||
<PackageReference Include="Handlebars.Net" Version="1.9.0" />
|
||||
<PackageReference Include="XPath2" Version="1.0.5.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net452' ">
|
||||
<PackageReference Include="Handlebars.Net" Version="1.9.5" />
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.OwinSelfHost" Version="5.2.6" />
|
||||
<PackageReference Include="XPath2" Version="1.0.5.1" />
|
||||
<!-- Required for WebRequestHandler -->
|
||||
<Reference Include="System.Net.Http.WebRequest" />
|
||||
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.OwinSelfHost" Version="5.2.6" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||
|
||||
<PackageReference Include="Handlebars.Net" Version="1.9.5" />
|
||||
<PackageReference Include="XPath2" Version="1.0.5.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net46' ">
|
||||
<PackageReference Include="Handlebars.Net" Version="1.9.5" />
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.OwinSelfHost" Version="5.2.6" />
|
||||
<PackageReference Include="Microsoft.Owin" Version="4.0.0" />
|
||||
<PackageReference Include="Microsoft.Owin.Host.HttpListener" Version="4.0.0" />
|
||||
<PackageReference Include="Microsoft.Owin.Hosting" Version="4.0.0" />
|
||||
<PackageReference Include="System.Net.Http" Version="4.3.3" />
|
||||
<PackageReference Include="XPath2" Version="1.0.5.1" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||
|
||||
<PackageReference Include="Handlebars.Net" Version="1.9.5" />
|
||||
<PackageReference Include="XPath2" Version="1.0.5.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'net461' ">
|
||||
<PackageReference Include="Handlebars.Net" Version="1.9.5" />
|
||||
<PackageReference Include="Microsoft.AspNetCore" Version="2.1.2" />
|
||||
|
||||
<PackageReference Include="Handlebars.Net" Version="1.9.5" />
|
||||
<PackageReference Include="XPath2" Version="1.0.5.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard1.3' ">
|
||||
<PackageReference Include="Handlebars.Net" Version="1.9.5" />
|
||||
<PackageReference Include="Microsoft.AspNetCore" Version="1.1.7" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel.Https" Version="1.1.3" />
|
||||
<PackageReference Include="System.Xml.XmlDocument" Version="4.3.0" />
|
||||
<PackageReference Include="System.Xml.XPath.XmlDocument" Version="4.3.0" />
|
||||
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
|
||||
|
||||
<PackageReference Include="Handlebars.Net" Version="1.9.5" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
|
||||
<PackageReference Include="Handlebars.Net" Version="1.9.5" />
|
||||
<PackageReference Include="Microsoft.AspNetCore" Version="2.1.2" />
|
||||
|
||||
<PackageReference Include="Handlebars.Net" Version="1.9.5" />
|
||||
<PackageReference Include="XPath2" Version="1.0.5.1" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user