using System; using JetBrains.Annotations; using Microsoft.AspNetCore.Html; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.AspNetCore.Mvc.Rendering; using Microsoft.AspNetCore.Routing; using Newtonsoft.Json; namespace StardewModdingAPI.Web.Framework { /// Provides extensions on ASP.NET Core types. public static class Extensions { /********* ** Public methods *********/ /**** ** View helpers ****/ /// Get a URL for an action method. Unlike , only the specified are added to the URL without merging values from the current HTTP request. /// The URL helper to extend. /// The name of the action method. /// The name of the controller. /// An object that contains route values. /// Get an absolute URL instead of a server-relative path/ /// The generated URL. public static string? PlainAction(this IUrlHelper helper, [AspMvcAction] string action, [AspMvcController] string controller, object? values = null, bool absoluteUrl = false) { // get route values RouteValueDictionary valuesDict = new(values); foreach (var value in helper.ActionContext.RouteData.Values) { if (!valuesDict.ContainsKey(value.Key)) valuesDict[value.Key] = null; // explicitly remove it from the URL } // get relative URL string? url = helper.Action(action, controller, valuesDict); if (url == null && action.EndsWith("Async")) url = helper.Action(action[..^"Async".Length], controller, valuesDict); // get absolute URL if (absoluteUrl) { HttpRequest request = helper.ActionContext.HttpContext.Request; Uri baseUri = new($"{request.Scheme}://{request.Host}"); url = new Uri(baseUri, url).ToString(); } return url; } /// Get a serialized JSON representation of the value. /// The page to extend. /// The value to serialize. /// The serialized JSON. /// This bypasses unnecessary validation (e.g. not allowing null values) in . public static IHtmlContent ForJson(this RazorPageBase page, object? value) { string json = JsonConvert.SerializeObject(value); return new HtmlString(json); } } }