feat: support Matrix42 26.1 sandboxed web api

This commit is contained in:
Meik
2026-06-26 11:44:34 +02:00
parent 690ad4f615
commit 6c6ac272cd
8 changed files with 267 additions and 305 deletions

View File

@@ -13,9 +13,9 @@ using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
using Matrix42.Common;
using Matrix42.WebApi.Contracts;
using update4u.SPS.DataLayer;
using update4u.SPS.DataLayer.Transaction;
@@ -80,7 +80,7 @@ namespace C4IT.F4SD
{
LogEntry($"Generating F4SD URI for type: '{type}', GUID: '{EOID}'", LogLevels.Debug);
var builder = new UriBuilder(c4itf4sdmonLinkBase);
var queryString = HttpUtility.ParseQueryString(builder.Query);
var queryString = UrlQueryBuilder.Parse(builder.Query);
switch (type.ToLowerInvariant().Split('.').Last())
{
@@ -1663,7 +1663,7 @@ namespace C4IT.F4SD
presetParamsDyn.SPSActivityClassIncident.Asset = asset.Id;
}
var type = TicketAndServiceRequestEnabled ? "SPSActivityTypeTicket" : "SPSActivityTypeIncident";
var presetParams = HttpUtility.UrlEncode(JsonConvert.SerializeObject(presetParamsDyn));
var presetParams = WebUtility.UrlEncode(JsonConvert.SerializeObject(presetParamsDyn));
var directLink = string.Format(TicketDirectLinkCreateTemplate, F4SDM42WebApiController.defaultInstance.BaseUrl, type, presetParams);
return new DirectLink()
{
@@ -1848,7 +1848,7 @@ namespace C4IT.F4SD
viewOptionsDyn.type = CIName;
viewOptionsDyn.viewType = "action";
viewOptionsDyn.actionId = TicketCloseActionId;
var viewOptions = HttpUtility.UrlEncode(JsonConvert.SerializeObject(viewOptionsDyn));
var viewOptions = WebUtility.UrlEncode(JsonConvert.SerializeObject(viewOptionsDyn));
var ticketDirectLinkPreview = string.Format(TicketDirectLinkPreviewTemplate, F4SDM42WebApiController.defaultInstance.BaseUrl, CIName, ActivityEOID);
var ticketDirectLinkEdit = string.Format(TicketDirectLinkEditTemplate, F4SDM42WebApiController.defaultInstance.BaseUrl, CIName, ActivityEOID);
@@ -2305,7 +2305,7 @@ namespace C4IT.F4SD
}
zipArchive.Dispose();
memoryStream.Position = 0L;
HttpResponseMessage httpResponseMessage = request.CreateResponse(HttpStatusCode.OK);
HttpResponseMessage httpResponseMessage = HttpResponseExtensions.CreateResponse(request, HttpStatusCode.OK);
httpResponseMessage.Content = new StreamContent(memoryStream);
httpResponseMessage.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
@@ -2727,4 +2727,41 @@ namespace C4IT.F4SD
Roles = new List<M42Role>();
}
}
internal sealed class UrlQueryBuilder
{
private readonly List<KeyValuePair<string, string>> _values = new List<KeyValuePair<string, string>>();
private UrlQueryBuilder()
{
}
public static UrlQueryBuilder Parse(string query)
{
var builder = new UrlQueryBuilder();
var normalizedQuery = (query ?? string.Empty).TrimStart('?');
foreach (var pair in normalizedQuery.Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries))
{
var separatorIndex = pair.IndexOf('=');
var key = separatorIndex >= 0 ? pair.Substring(0, separatorIndex) : pair;
var value = separatorIndex >= 0 ? pair.Substring(separatorIndex + 1) : string.Empty;
builder.Add(WebUtility.UrlDecode(key), WebUtility.UrlDecode(value));
}
return builder;
}
public void Add(string key, string value)
{
if (!string.IsNullOrEmpty(key))
_values.Add(new KeyValuePair<string, string>(key, value ?? string.Empty));
}
public override string ToString()
{
return string.Join("&", _values.Select(pair => $"{WebUtility.UrlEncode(pair.Key)}={WebUtility.UrlEncode(pair.Value)}"));
}
}
}