Make all optional strings nullable

This commit is contained in:
crobibero 2020-06-27 10:50:44 -06:00
parent 90c01327aa
commit 73bcda7eac
33 changed files with 143 additions and 145 deletions

View File

@ -53,7 +53,7 @@ namespace Jellyfin.Api.Controllers
public ActionResult<QueryResult<BaseItemDto>> GetSimilarAlbums( public ActionResult<QueryResult<BaseItemDto>> GetSimilarAlbums(
[FromRoute] string albumId, [FromRoute] string albumId,
[FromQuery] Guid userId, [FromQuery] Guid userId,
[FromQuery] string excludeArtistIds, [FromQuery] string? excludeArtistIds,
[FromQuery] int? limit) [FromQuery] int? limit)
{ {
var dtoOptions = new DtoOptions().AddClientFields(Request); var dtoOptions = new DtoOptions().AddClientFields(Request);
@ -85,7 +85,7 @@ namespace Jellyfin.Api.Controllers
public ActionResult<QueryResult<BaseItemDto>> GetSimilarArtists( public ActionResult<QueryResult<BaseItemDto>> GetSimilarArtists(
[FromRoute] string artistId, [FromRoute] string artistId,
[FromQuery] Guid userId, [FromQuery] Guid userId,
[FromQuery] string excludeArtistIds, [FromQuery] string? excludeArtistIds,
[FromQuery] int? limit) [FromQuery] int? limit)
{ {
var dtoOptions = new DtoOptions().AddClientFields(Request); var dtoOptions = new DtoOptions().AddClientFields(Request);

View File

@ -65,7 +65,7 @@ namespace Jellyfin.Api.Controllers
[HttpPost("Keys")] [HttpPost("Keys")]
[Authorize(Policy = Policies.RequiresElevation)] [Authorize(Policy = Policies.RequiresElevation)]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult CreateKey([FromQuery, Required] string app) public ActionResult CreateKey([FromQuery, Required] string? app)
{ {
_authRepo.Create(new AuthenticationInfo _authRepo.Create(new AuthenticationInfo
{ {
@ -88,7 +88,7 @@ namespace Jellyfin.Api.Controllers
[HttpDelete("Keys/{key}")] [HttpDelete("Keys/{key}")]
[Authorize(Policy = Policies.RequiresElevation)] [Authorize(Policy = Policies.RequiresElevation)]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult RevokeKey([FromRoute] string key) public ActionResult RevokeKey([FromRoute] string? key)
{ {
_sessionManager.RevokeToken(key); _sessionManager.RevokeToken(key);
return NoContent(); return NoContent();

View File

@ -51,8 +51,8 @@ namespace Jellyfin.Api.Controllers
[HttpPost] [HttpPost]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult<CollectionCreationResult> CreateCollection( public ActionResult<CollectionCreationResult> CreateCollection(
[FromQuery] string name, [FromQuery] string? name,
[FromQuery] string ids, [FromQuery] string? ids,
[FromQuery] bool isLocked, [FromQuery] bool isLocked,
[FromQuery] Guid? parentId) [FromQuery] Guid? parentId)
{ {
@ -86,7 +86,7 @@ namespace Jellyfin.Api.Controllers
/// <returns>A <see cref="NoContentResult"/> indicating success.</returns> /// <returns>A <see cref="NoContentResult"/> indicating success.</returns>
[HttpPost("{collectionId}/Items")] [HttpPost("{collectionId}/Items")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult AddToCollection([FromRoute] Guid collectionId, [FromQuery] string itemIds) public ActionResult AddToCollection([FromRoute] Guid collectionId, [FromQuery] string? itemIds)
{ {
_collectionManager.AddToCollection(collectionId, RequestHelpers.Split(itemIds, ',', true)); _collectionManager.AddToCollection(collectionId, RequestHelpers.Split(itemIds, ',', true));
return NoContent(); return NoContent();
@ -101,7 +101,7 @@ namespace Jellyfin.Api.Controllers
/// <returns>A <see cref="NoContentResult"/> indicating success.</returns> /// <returns>A <see cref="NoContentResult"/> indicating success.</returns>
[HttpDelete("{collectionId}/Items")] [HttpDelete("{collectionId}/Items")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult RemoveFromCollection([FromRoute] Guid collectionId, [FromQuery] string itemIds) public ActionResult RemoveFromCollection([FromRoute] Guid collectionId, [FromQuery] string? itemIds)
{ {
_collectionManager.RemoveFromCollection(collectionId, RequestHelpers.Split(itemIds, ',', true)); _collectionManager.RemoveFromCollection(collectionId, RequestHelpers.Split(itemIds, ',', true));
return NoContent(); return NoContent();

View File

@ -70,7 +70,7 @@ namespace Jellyfin.Api.Controllers
/// <returns>Configuration.</returns> /// <returns>Configuration.</returns>
[HttpGet("Configuration/{key}")] [HttpGet("Configuration/{key}")]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult<object> GetNamedConfiguration([FromRoute] string key) public ActionResult<object> GetNamedConfiguration([FromRoute] string? key)
{ {
return _configurationManager.GetConfiguration(key); return _configurationManager.GetConfiguration(key);
} }
@ -84,7 +84,7 @@ namespace Jellyfin.Api.Controllers
[HttpPost("Configuration/{key}")] [HttpPost("Configuration/{key}")]
[Authorize(Policy = Policies.RequiresElevation)] [Authorize(Policy = Policies.RequiresElevation)]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<ActionResult> UpdateNamedConfiguration([FromRoute] string key) public async Task<ActionResult> UpdateNamedConfiguration([FromRoute] string? key)
{ {
var configurationType = _configurationManager.GetConfigurationType(key); var configurationType = _configurationManager.GetConfigurationType(key);
var configuration = await JsonSerializer.DeserializeAsync(Request.Body, configurationType).ConfigureAwait(false); var configuration = await JsonSerializer.DeserializeAsync(Request.Body, configurationType).ConfigureAwait(false);

View File

@ -122,7 +122,7 @@ namespace Jellyfin.Api.Controllers
[HttpGet("/web/ConfigurationPage")] [HttpGet("/web/ConfigurationPage")]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult GetDashboardConfigurationPage([FromQuery] string name) public ActionResult GetDashboardConfigurationPage([FromQuery] string? name)
{ {
IPlugin? plugin = null; IPlugin? plugin = null;
Stream? stream = null; Stream? stream = null;

View File

@ -65,7 +65,7 @@ namespace Jellyfin.Api.Controllers
[Authorize(Policy = Policies.RequiresElevation)] [Authorize(Policy = Policies.RequiresElevation)]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<DeviceInfo> GetDeviceInfo([FromQuery, BindRequired] string id) public ActionResult<DeviceInfo> GetDeviceInfo([FromQuery, BindRequired] string? id)
{ {
var deviceInfo = _deviceManager.GetDevice(id); var deviceInfo = _deviceManager.GetDevice(id);
if (deviceInfo == null) if (deviceInfo == null)
@ -87,7 +87,7 @@ namespace Jellyfin.Api.Controllers
[Authorize(Policy = Policies.RequiresElevation)] [Authorize(Policy = Policies.RequiresElevation)]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<DeviceOptions> GetDeviceOptions([FromQuery, BindRequired] string id) public ActionResult<DeviceOptions> GetDeviceOptions([FromQuery, BindRequired] string? id)
{ {
var deviceInfo = _deviceManager.GetDeviceOptions(id); var deviceInfo = _deviceManager.GetDeviceOptions(id);
if (deviceInfo == null) if (deviceInfo == null)
@ -111,7 +111,7 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult UpdateDeviceOptions( public ActionResult UpdateDeviceOptions(
[FromQuery, BindRequired] string id, [FromQuery, BindRequired] string? id,
[FromBody, BindRequired] DeviceOptions deviceOptions) [FromBody, BindRequired] DeviceOptions deviceOptions)
{ {
var existingDeviceOptions = _deviceManager.GetDeviceOptions(id); var existingDeviceOptions = _deviceManager.GetDeviceOptions(id);
@ -134,7 +134,7 @@ namespace Jellyfin.Api.Controllers
[HttpDelete] [HttpDelete]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult DeleteDevice([FromQuery, BindRequired] string id) public ActionResult DeleteDevice([FromQuery, BindRequired] string? id)
{ {
var existingDevice = _deviceManager.GetDevice(id); var existingDevice = _deviceManager.GetDevice(id);
if (existingDevice == null) if (existingDevice == null)

View File

@ -39,9 +39,9 @@ namespace Jellyfin.Api.Controllers
[HttpGet("{displayPreferencesId}")] [HttpGet("{displayPreferencesId}")]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult<DisplayPreferences> GetDisplayPreferences( public ActionResult<DisplayPreferences> GetDisplayPreferences(
[FromRoute] string displayPreferencesId, [FromRoute] string? displayPreferencesId,
[FromQuery] [Required] string userId, [FromQuery] [Required] string? userId,
[FromQuery] [Required] string client) [FromQuery] [Required] string? client)
{ {
return _displayPreferencesRepository.GetDisplayPreferences(displayPreferencesId, userId, client); return _displayPreferencesRepository.GetDisplayPreferences(displayPreferencesId, userId, client);
} }
@ -59,9 +59,9 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
[SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "displayPreferencesId", Justification = "Imported from ServiceStack")] [SuppressMessage("Microsoft.Performance", "CA1801:ReviewUnusedParameters", MessageId = "displayPreferencesId", Justification = "Imported from ServiceStack")]
public ActionResult UpdateDisplayPreferences( public ActionResult UpdateDisplayPreferences(
[FromRoute] string displayPreferencesId, [FromRoute] string? displayPreferencesId,
[FromQuery, BindRequired] string userId, [FromQuery, BindRequired] string? userId,
[FromQuery, BindRequired] string client, [FromQuery, BindRequired] string? client,
[FromBody, BindRequired] DisplayPreferences displayPreferences) [FromBody, BindRequired] DisplayPreferences displayPreferences)
{ {
_displayPreferencesRepository.SaveDisplayPreferences( _displayPreferencesRepository.SaveDisplayPreferences(

View File

@ -64,7 +64,7 @@ namespace Jellyfin.Api.Controllers
[Produces(MediaTypeNames.Application.Octet)] [Produces(MediaTypeNames.Application.Octet)]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<FileStreamResult> GetGeneralImage([FromRoute] string name, [FromRoute] string type) public ActionResult<FileStreamResult> GetGeneralImage([FromRoute] string? name, [FromRoute] string? type)
{ {
var filename = string.Equals(type, "primary", StringComparison.OrdinalIgnoreCase) var filename = string.Equals(type, "primary", StringComparison.OrdinalIgnoreCase)
? "folder" ? "folder"
@ -110,8 +110,8 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<FileStreamResult> GetRatingImage( public ActionResult<FileStreamResult> GetRatingImage(
[FromRoute] string theme, [FromRoute] string? theme,
[FromRoute] string name) [FromRoute] string? name)
{ {
return GetImageFile(_applicationPaths.RatingsPath, theme, name); return GetImageFile(_applicationPaths.RatingsPath, theme, name);
} }
@ -143,8 +143,8 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<FileStreamResult> GetMediaInfoImage( public ActionResult<FileStreamResult> GetMediaInfoImage(
[FromRoute] string theme, [FromRoute] string? theme,
[FromRoute] string name) [FromRoute] string? name)
{ {
return GetImageFile(_applicationPaths.MediaInfoImagesPath, theme, name); return GetImageFile(_applicationPaths.MediaInfoImagesPath, theme, name);
} }
@ -156,7 +156,7 @@ namespace Jellyfin.Api.Controllers
/// <param name="theme">Theme to search.</param> /// <param name="theme">Theme to search.</param>
/// <param name="name">File name to search for.</param> /// <param name="name">File name to search for.</param>
/// <returns>A <see cref="FileStreamResult"/> containing the image contents on success, or a <see cref="NotFoundResult"/> if the image could not be found.</returns> /// <returns>A <see cref="FileStreamResult"/> containing the image contents on success, or a <see cref="NotFoundResult"/> if the image could not be found.</returns>
private ActionResult<FileStreamResult> GetImageFile(string basePath, string theme, string name) private ActionResult<FileStreamResult> GetImageFile(string basePath, string? theme, string? name)
{ {
var themeFolder = Path.Combine(basePath, theme); var themeFolder = Path.Combine(basePath, theme);
if (Directory.Exists(themeFolder)) if (Directory.Exists(themeFolder))

View File

@ -65,7 +65,7 @@ namespace Jellyfin.Api.Controllers
[FromRoute] Guid id, [FromRoute] Guid id,
[FromQuery] Guid userId, [FromQuery] Guid userId,
[FromQuery] int? limit, [FromQuery] int? limit,
[FromQuery] string fields, [FromQuery] string? fields,
[FromQuery] bool? enableImages, [FromQuery] bool? enableImages,
[FromQuery] bool? enableUserData, [FromQuery] bool? enableUserData,
[FromQuery] int? imageTypeLimit, [FromQuery] int? imageTypeLimit,
@ -100,7 +100,7 @@ namespace Jellyfin.Api.Controllers
[FromRoute] Guid id, [FromRoute] Guid id,
[FromQuery] Guid userId, [FromQuery] Guid userId,
[FromQuery] int? limit, [FromQuery] int? limit,
[FromQuery] string fields, [FromQuery] string? fields,
[FromQuery] bool? enableImages, [FromQuery] bool? enableImages,
[FromQuery] bool? enableUserData, [FromQuery] bool? enableUserData,
[FromQuery] int? imageTypeLimit, [FromQuery] int? imageTypeLimit,
@ -135,7 +135,7 @@ namespace Jellyfin.Api.Controllers
[FromRoute] Guid id, [FromRoute] Guid id,
[FromQuery] Guid userId, [FromQuery] Guid userId,
[FromQuery] int? limit, [FromQuery] int? limit,
[FromQuery] string fields, [FromQuery] string? fields,
[FromQuery] bool? enableImages, [FromQuery] bool? enableImages,
[FromQuery] bool? enableUserData, [FromQuery] bool? enableUserData,
[FromQuery] int? imageTypeLimit, [FromQuery] int? imageTypeLimit,
@ -167,10 +167,10 @@ namespace Jellyfin.Api.Controllers
[HttpGet("/MusicGenres/{name}/InstantMix")] [HttpGet("/MusicGenres/{name}/InstantMix")]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult<QueryResult<BaseItemDto>> GetInstantMixFromMusicGenre( public ActionResult<QueryResult<BaseItemDto>> GetInstantMixFromMusicGenre(
[FromRoute] string name, [FromRoute] string? name,
[FromQuery] Guid userId, [FromQuery] Guid userId,
[FromQuery] int? limit, [FromQuery] int? limit,
[FromQuery] string fields, [FromQuery] string? fields,
[FromQuery] bool? enableImages, [FromQuery] bool? enableImages,
[FromQuery] bool? enableUserData, [FromQuery] bool? enableUserData,
[FromQuery] int? imageTypeLimit, [FromQuery] int? imageTypeLimit,
@ -204,7 +204,7 @@ namespace Jellyfin.Api.Controllers
[FromRoute] Guid id, [FromRoute] Guid id,
[FromQuery] Guid userId, [FromQuery] Guid userId,
[FromQuery] int? limit, [FromQuery] int? limit,
[FromQuery] string fields, [FromQuery] string? fields,
[FromQuery] bool? enableImages, [FromQuery] bool? enableImages,
[FromQuery] bool? enableUserData, [FromQuery] bool? enableUserData,
[FromQuery] int? imageTypeLimit, [FromQuery] int? imageTypeLimit,
@ -239,7 +239,7 @@ namespace Jellyfin.Api.Controllers
[FromRoute] Guid id, [FromRoute] Guid id,
[FromQuery] Guid userId, [FromQuery] Guid userId,
[FromQuery] int? limit, [FromQuery] int? limit,
[FromQuery] string fields, [FromQuery] string? fields,
[FromQuery] bool? enableImages, [FromQuery] bool? enableImages,
[FromQuery] bool? enableUserData, [FromQuery] bool? enableUserData,
[FromQuery] int? imageTypeLimit, [FromQuery] int? imageTypeLimit,
@ -274,7 +274,7 @@ namespace Jellyfin.Api.Controllers
[FromRoute] Guid id, [FromRoute] Guid id,
[FromQuery] Guid userId, [FromQuery] Guid userId,
[FromQuery] int? limit, [FromQuery] int? limit,
[FromQuery] string fields, [FromQuery] string? fields,
[FromQuery] bool? enableImages, [FromQuery] bool? enableImages,
[FromQuery] bool? enableUserData, [FromQuery] bool? enableUserData,
[FromQuery] int? imageTypeLimit, [FromQuery] int? imageTypeLimit,

View File

@ -193,7 +193,7 @@ namespace Jellyfin.Api.Controllers
[HttpPost("/Items/{itemId}/ContentType")] [HttpPost("/Items/{itemId}/ContentType")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult UpdateItemContentType([FromRoute] Guid itemId, [FromQuery, BindRequired] string contentType) public ActionResult UpdateItemContentType([FromRoute] Guid itemId, [FromQuery, BindRequired] string? contentType)
{ {
var item = _libraryManager.GetItemById(itemId); var item = _libraryManager.GetItemById(itemId);
if (item == null) if (item == null)

View File

@ -524,7 +524,7 @@ namespace Jellyfin.Api.Controllers
[HttpPost("/Library/Series/Updated")] [HttpPost("/Library/Series/Updated")]
[Authorize(Policy = Policies.DefaultAuthorization)] [Authorize(Policy = Policies.DefaultAuthorization)]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult PostUpdatedSeries([FromQuery] string tvdbId) public ActionResult PostUpdatedSeries([FromQuery] string? tvdbId)
{ {
var series = _libraryManager.GetItemList(new InternalItemsQuery var series = _libraryManager.GetItemList(new InternalItemsQuery
{ {
@ -554,7 +554,7 @@ namespace Jellyfin.Api.Controllers
[HttpPost("/Library/Movies/Updated")] [HttpPost("/Library/Movies/Updated")]
[Authorize(Policy = Policies.DefaultAuthorization)] [Authorize(Policy = Policies.DefaultAuthorization)]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult PostUpdatedMovies([FromRoute] string tmdbId, [FromRoute] string imdbId) public ActionResult PostUpdatedMovies([FromRoute] string? tmdbId, [FromRoute] string? imdbId)
{ {
var movies = _libraryManager.GetItemList(new InternalItemsQuery var movies = _libraryManager.GetItemList(new InternalItemsQuery
{ {
@ -687,10 +687,10 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult<QueryResult<BaseItemDto>> GetSimilarItems( public ActionResult<QueryResult<BaseItemDto>> GetSimilarItems(
[FromRoute] Guid itemId, [FromRoute] Guid itemId,
[FromQuery] string excludeArtistIds, [FromQuery] string? excludeArtistIds,
[FromQuery] Guid userId, [FromQuery] Guid userId,
[FromQuery] int? limit, [FromQuery] int? limit,
[FromQuery] string fields) [FromQuery] string? fields)
{ {
var item = itemId.Equals(Guid.Empty) var item = itemId.Equals(Guid.Empty)
? (!userId.Equals(Guid.Empty) ? (!userId.Equals(Guid.Empty)
@ -737,7 +737,7 @@ namespace Jellyfin.Api.Controllers
[HttpGet("/Libraries/AvailableOptions")] [HttpGet("/Libraries/AvailableOptions")]
[Authorize(Policy = Policies.FirstTimeSetupOrElevated)] [Authorize(Policy = Policies.FirstTimeSetupOrElevated)]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult<LibraryOptionsResultDto> GetLibraryOptionsInfo([FromQuery] string libraryContentType, [FromQuery] bool isNewLibrary) public ActionResult<LibraryOptionsResultDto> GetLibraryOptionsInfo([FromQuery] string? libraryContentType, [FromQuery] bool isNewLibrary)
{ {
var result = new LibraryOptionsResultDto(); var result = new LibraryOptionsResultDto();
@ -877,10 +877,10 @@ namespace Jellyfin.Api.Controllers
private QueryResult<BaseItemDto> GetSimilarItemsResult( private QueryResult<BaseItemDto> GetSimilarItemsResult(
BaseItem item, BaseItem item,
string excludeArtistIds, string? excludeArtistIds,
Guid userId, Guid userId,
int? limit, int? limit,
string fields, string? fields,
string[] includeItemTypes, string[] includeItemTypes,
bool isMovie) bool isMovie)
{ {
@ -942,7 +942,7 @@ namespace Jellyfin.Api.Controllers
return result; return result;
} }
private static string[] GetRepresentativeItemTypes(string contentType) private static string[] GetRepresentativeItemTypes(string? contentType)
{ {
return contentType switch return contentType switch
{ {

View File

@ -72,8 +72,8 @@ namespace Jellyfin.Api.Controllers
[HttpPost] [HttpPost]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<ActionResult> AddVirtualFolder( public async Task<ActionResult> AddVirtualFolder(
[FromQuery] string name, [FromQuery] string? name,
[FromQuery] string collectionType, [FromQuery] string? collectionType,
[FromQuery] bool refreshLibrary, [FromQuery] bool refreshLibrary,
[FromQuery] string[] paths, [FromQuery] string[] paths,
[FromQuery] LibraryOptions libraryOptions) [FromQuery] LibraryOptions libraryOptions)
@ -100,7 +100,7 @@ namespace Jellyfin.Api.Controllers
[HttpDelete] [HttpDelete]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<ActionResult> RemoveVirtualFolder( public async Task<ActionResult> RemoveVirtualFolder(
[FromQuery] string name, [FromQuery] string? name,
[FromQuery] bool refreshLibrary) [FromQuery] bool refreshLibrary)
{ {
await _libraryManager.RemoveVirtualFolder(name, refreshLibrary).ConfigureAwait(false); await _libraryManager.RemoveVirtualFolder(name, refreshLibrary).ConfigureAwait(false);
@ -123,8 +123,8 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
[ProducesResponseType(StatusCodes.Status409Conflict)] [ProducesResponseType(StatusCodes.Status409Conflict)]
public ActionResult RenameVirtualFolder( public ActionResult RenameVirtualFolder(
[FromQuery] string name, [FromQuery] string? name,
[FromQuery] string newName, [FromQuery] string? newName,
[FromQuery] bool refreshLibrary) [FromQuery] bool refreshLibrary)
{ {
if (string.IsNullOrWhiteSpace(name)) if (string.IsNullOrWhiteSpace(name))
@ -205,8 +205,8 @@ namespace Jellyfin.Api.Controllers
[HttpPost("Paths")] [HttpPost("Paths")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult AddMediaPath( public ActionResult AddMediaPath(
[FromQuery] string name, [FromQuery] string? name,
[FromQuery] string path, [FromQuery] string? path,
[FromQuery] MediaPathInfo pathInfo, [FromQuery] MediaPathInfo pathInfo,
[FromQuery] bool refreshLibrary) [FromQuery] bool refreshLibrary)
{ {
@ -256,7 +256,7 @@ namespace Jellyfin.Api.Controllers
[HttpPost("Paths/Update")] [HttpPost("Paths/Update")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult UpdateMediaPath( public ActionResult UpdateMediaPath(
[FromQuery] string name, [FromQuery] string? name,
[FromQuery] MediaPathInfo pathInfo) [FromQuery] MediaPathInfo pathInfo)
{ {
if (string.IsNullOrWhiteSpace(name)) if (string.IsNullOrWhiteSpace(name))
@ -280,8 +280,8 @@ namespace Jellyfin.Api.Controllers
[HttpDelete("Paths")] [HttpDelete("Paths")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult RemoveMediaPath( public ActionResult RemoveMediaPath(
[FromQuery] string name, [FromQuery] string? name,
[FromQuery] string path, [FromQuery] string? path,
[FromQuery] bool refreshLibrary) [FromQuery] bool refreshLibrary)
{ {
if (string.IsNullOrWhiteSpace(name)) if (string.IsNullOrWhiteSpace(name))
@ -327,7 +327,7 @@ namespace Jellyfin.Api.Controllers
[HttpPost("LibraryOptions")] [HttpPost("LibraryOptions")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult UpdateLibraryOptions( public ActionResult UpdateLibraryOptions(
[FromQuery] string id, [FromQuery] string? id,
[FromQuery] LibraryOptions libraryOptions) [FromQuery] LibraryOptions libraryOptions)
{ {
var collectionFolder = (CollectionFolder)_libraryManager.GetItemById(id); var collectionFolder = (CollectionFolder)_libraryManager.GetItemById(id);

View File

@ -93,8 +93,8 @@ namespace Jellyfin.Api.Controllers
[HttpPost("Admin")] [HttpPost("Admin")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult CreateAdminNotification( public ActionResult CreateAdminNotification(
[FromQuery] string name, [FromQuery] string? name,
[FromQuery] string description, [FromQuery] string? description,
[FromQuery] string? url, [FromQuery] string? url,
[FromQuery] NotificationLevel? level) [FromQuery] NotificationLevel? level)
{ {

View File

@ -40,7 +40,7 @@ namespace Jellyfin.Api.Controllers
[HttpGet("/{name}")] [HttpGet("/{name}")]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<PackageInfo>> GetPackageInfo( public async Task<ActionResult<PackageInfo>> GetPackageInfo(
[FromRoute] [Required] string name, [FromRoute] [Required] string? name,
[FromQuery] string? assemblyGuid) [FromQuery] string? assemblyGuid)
{ {
var packages = await _installationManager.GetAvailablePackages().ConfigureAwait(false); var packages = await _installationManager.GetAvailablePackages().ConfigureAwait(false);
@ -80,9 +80,9 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
[Authorize(Policy = Policies.RequiresElevation)] [Authorize(Policy = Policies.RequiresElevation)]
public async Task<ActionResult> InstallPackage( public async Task<ActionResult> InstallPackage(
[FromRoute] [Required] string name, [FromRoute] [Required] string? name,
[FromQuery] string assemblyGuid, [FromQuery] string? assemblyGuid,
[FromQuery] string version) [FromQuery] string? version)
{ {
var packages = await _installationManager.GetAvailablePackages().ConfigureAwait(false); var packages = await _installationManager.GetAvailablePackages().ConfigureAwait(false);
var package = _installationManager.GetCompatibleVersions( var package = _installationManager.GetCompatibleVersions(

View File

@ -84,8 +84,8 @@ namespace Jellyfin.Api.Controllers
[HttpPost("{playlistId}/Items")] [HttpPost("{playlistId}/Items")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult AddToPlaylist( public ActionResult AddToPlaylist(
[FromRoute] string playlistId, [FromRoute] string? playlistId,
[FromQuery] string ids, [FromQuery] string? ids,
[FromQuery] Guid userId) [FromQuery] Guid userId)
{ {
_playlistManager.AddToPlaylist(playlistId, RequestHelpers.GetGuids(ids), userId); _playlistManager.AddToPlaylist(playlistId, RequestHelpers.GetGuids(ids), userId);
@ -103,8 +103,8 @@ namespace Jellyfin.Api.Controllers
[HttpPost("{playlistId}/Items/{itemId}/Move/{newIndex}")] [HttpPost("{playlistId}/Items/{itemId}/Move/{newIndex}")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult MoveItem( public ActionResult MoveItem(
[FromRoute] string playlistId, [FromRoute] string? playlistId,
[FromRoute] string itemId, [FromRoute] string? itemId,
[FromRoute] int newIndex) [FromRoute] int newIndex)
{ {
_playlistManager.MoveItem(playlistId, itemId, newIndex); _playlistManager.MoveItem(playlistId, itemId, newIndex);
@ -120,7 +120,7 @@ namespace Jellyfin.Api.Controllers
/// <returns>An <see cref="NoContentResult"/> on success.</returns> /// <returns>An <see cref="NoContentResult"/> on success.</returns>
[HttpDelete("{playlistId}/Items")] [HttpDelete("{playlistId}/Items")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult RemoveFromPlaylist([FromRoute] string playlistId, [FromQuery] string entryIds) public ActionResult RemoveFromPlaylist([FromRoute] string? playlistId, [FromQuery] string? entryIds)
{ {
_playlistManager.RemoveFromPlaylist(playlistId, RequestHelpers.Split(entryIds, ',', true)); _playlistManager.RemoveFromPlaylist(playlistId, RequestHelpers.Split(entryIds, ',', true));
return NoContent(); return NoContent();
@ -147,11 +147,11 @@ namespace Jellyfin.Api.Controllers
[FromRoute] Guid userId, [FromRoute] Guid userId,
[FromRoute] int? startIndex, [FromRoute] int? startIndex,
[FromRoute] int? limit, [FromRoute] int? limit,
[FromRoute] string fields, [FromRoute] string? fields,
[FromRoute] bool? enableImages, [FromRoute] bool? enableImages,
[FromRoute] bool? enableUserData, [FromRoute] bool? enableUserData,
[FromRoute] int? imageTypeLimit, [FromRoute] int? imageTypeLimit,
[FromRoute] string enableImageTypes) [FromRoute] string? enableImageTypes)
{ {
var playlist = (Playlist)_libraryManager.GetItemById(playlistId); var playlist = (Playlist)_libraryManager.GetItemById(playlistId);
if (playlist == null) if (playlist == null)

View File

@ -166,7 +166,7 @@ namespace Jellyfin.Api.Controllers
[Obsolete("This endpoint should not be used.")] [Obsolete("This endpoint should not be used.")]
[HttpPost("RegistrationRecords/{name}")] [HttpPost("RegistrationRecords/{name}")]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult<MBRegistrationRecord> GetRegistrationStatus([FromRoute] string name) public ActionResult<MBRegistrationRecord> GetRegistrationStatus([FromRoute] string? name)
{ {
return new MBRegistrationRecord return new MBRegistrationRecord
{ {
@ -188,7 +188,7 @@ namespace Jellyfin.Api.Controllers
[Obsolete("Paid plugins are not supported")] [Obsolete("Paid plugins are not supported")]
[HttpGet("/Registrations/{name}")] [HttpGet("/Registrations/{name}")]
[ProducesResponseType(StatusCodes.Status501NotImplemented)] [ProducesResponseType(StatusCodes.Status501NotImplemented)]
public ActionResult GetRegistration([FromRoute] string name) public ActionResult GetRegistration([FromRoute] string? name)
{ {
// TODO Once we have proper apps and plugins and decide to break compatibility with paid plugins, // TODO Once we have proper apps and plugins and decide to break compatibility with paid plugins,
// delete all these registration endpoints. They are only kept for compatibility. // delete all these registration endpoints. They are only kept for compatibility.

View File

@ -208,7 +208,7 @@ namespace Jellyfin.Api.Controllers
public async Task<ActionResult> DownloadRemoteImage( public async Task<ActionResult> DownloadRemoteImage(
[FromRoute] Guid itemId, [FromRoute] Guid itemId,
[FromQuery, BindRequired] ImageType type, [FromQuery, BindRequired] ImageType type,
[FromQuery] string imageUrl) [FromQuery] string? imageUrl)
{ {
var item = _libraryManager.GetItemById(itemId); var item = _libraryManager.GetItemById(itemId);
if (item == null) if (item == null)

View File

@ -71,7 +71,7 @@ namespace Jellyfin.Api.Controllers
[HttpGet("{taskId}")] [HttpGet("{taskId}")]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<TaskInfo> GetTask([FromRoute] string taskId) public ActionResult<TaskInfo> GetTask([FromRoute] string? taskId)
{ {
var task = _taskManager.ScheduledTasks.FirstOrDefault(i => var task = _taskManager.ScheduledTasks.FirstOrDefault(i =>
string.Equals(i.Id, taskId, StringComparison.OrdinalIgnoreCase)); string.Equals(i.Id, taskId, StringComparison.OrdinalIgnoreCase));
@ -94,7 +94,7 @@ namespace Jellyfin.Api.Controllers
[HttpPost("Running/{taskId}")] [HttpPost("Running/{taskId}")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult StartTask([FromRoute] string taskId) public ActionResult StartTask([FromRoute] string? taskId)
{ {
var task = _taskManager.ScheduledTasks.FirstOrDefault(o => var task = _taskManager.ScheduledTasks.FirstOrDefault(o =>
o.Id.Equals(taskId, StringComparison.OrdinalIgnoreCase)); o.Id.Equals(taskId, StringComparison.OrdinalIgnoreCase));
@ -118,7 +118,7 @@ namespace Jellyfin.Api.Controllers
[HttpDelete("Running/{taskId}")] [HttpDelete("Running/{taskId}")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult StopTask([FromRoute] string taskId) public ActionResult StopTask([FromRoute] string? taskId)
{ {
var task = _taskManager.ScheduledTasks.FirstOrDefault(o => var task = _taskManager.ScheduledTasks.FirstOrDefault(o =>
o.Id.Equals(taskId, StringComparison.OrdinalIgnoreCase)); o.Id.Equals(taskId, StringComparison.OrdinalIgnoreCase));
@ -144,7 +144,7 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult UpdateTask( public ActionResult UpdateTask(
[FromRoute] string taskId, [FromRoute] string? taskId,
[FromBody, BindRequired] TaskTriggerInfo[] triggerInfos) [FromBody, BindRequired] TaskTriggerInfo[] triggerInfos)
{ {
var task = _taskManager.ScheduledTasks.FirstOrDefault(o => var task = _taskManager.ScheduledTasks.FirstOrDefault(o =>

View File

@ -81,11 +81,11 @@ namespace Jellyfin.Api.Controllers
[FromQuery] int? startIndex, [FromQuery] int? startIndex,
[FromQuery] int? limit, [FromQuery] int? limit,
[FromQuery] Guid userId, [FromQuery] Guid userId,
[FromQuery, Required] string searchTerm, [FromQuery, Required] string? searchTerm,
[FromQuery] string includeItemTypes, [FromQuery] string? includeItemTypes,
[FromQuery] string excludeItemTypes, [FromQuery] string? excludeItemTypes,
[FromQuery] string mediaTypes, [FromQuery] string? mediaTypes,
[FromQuery] string parentId, [FromQuery] string? parentId,
[FromQuery] bool? isMovie, [FromQuery] bool? isMovie,
[FromQuery] bool? isSeries, [FromQuery] bool? isSeries,
[FromQuery] bool? isNews, [FromQuery] bool? isNews,

View File

@ -62,7 +62,7 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult<IEnumerable<SessionInfo>> GetSessions( public ActionResult<IEnumerable<SessionInfo>> GetSessions(
[FromQuery] Guid controllableByUserId, [FromQuery] Guid controllableByUserId,
[FromQuery] string deviceId, [FromQuery] string? deviceId,
[FromQuery] int? activeWithinSeconds) [FromQuery] int? activeWithinSeconds)
{ {
var result = _sessionManager.Sessions; var result = _sessionManager.Sessions;
@ -123,10 +123,10 @@ namespace Jellyfin.Api.Controllers
[HttpPost("/Sessions/{sessionId}/Viewing")] [HttpPost("/Sessions/{sessionId}/Viewing")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult DisplayContent( public ActionResult DisplayContent(
[FromRoute] string sessionId, [FromRoute] string? sessionId,
[FromQuery] string itemType, [FromQuery] string? itemType,
[FromQuery] string itemId, [FromQuery] string? itemId,
[FromQuery] string itemName) [FromQuery] string? itemName)
{ {
var command = new BrowseRequest var command = new BrowseRequest
{ {
@ -157,7 +157,7 @@ namespace Jellyfin.Api.Controllers
[HttpPost("/Sessions/{sessionId}/Playing")] [HttpPost("/Sessions/{sessionId}/Playing")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult Play( public ActionResult Play(
[FromRoute] string sessionId, [FromRoute] string? sessionId,
[FromQuery] Guid[] itemIds, [FromQuery] Guid[] itemIds,
[FromQuery] long? startPositionTicks, [FromQuery] long? startPositionTicks,
[FromQuery] PlayCommand playCommand, [FromQuery] PlayCommand playCommand,
@ -191,7 +191,7 @@ namespace Jellyfin.Api.Controllers
[HttpPost("/Sessions/{sessionId}/Playing/{command}")] [HttpPost("/Sessions/{sessionId}/Playing/{command}")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult SendPlaystateCommand( public ActionResult SendPlaystateCommand(
[FromRoute] string sessionId, [FromRoute] string? sessionId,
[FromBody] PlaystateRequest playstateRequest) [FromBody] PlaystateRequest playstateRequest)
{ {
_sessionManager.SendPlaystateCommand( _sessionManager.SendPlaystateCommand(
@ -213,8 +213,8 @@ namespace Jellyfin.Api.Controllers
[HttpPost("/Sessions/{sessionId}/System/{command}")] [HttpPost("/Sessions/{sessionId}/System/{command}")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult SendSystemCommand( public ActionResult SendSystemCommand(
[FromRoute] string sessionId, [FromRoute] string? sessionId,
[FromRoute] string command) [FromRoute] string? command)
{ {
var name = command; var name = command;
if (Enum.TryParse(name, true, out GeneralCommandType commandType)) if (Enum.TryParse(name, true, out GeneralCommandType commandType))
@ -244,8 +244,8 @@ namespace Jellyfin.Api.Controllers
[HttpPost("/Sessions/{sessionId}/Command/{Command}")] [HttpPost("/Sessions/{sessionId}/Command/{Command}")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult SendGeneralCommand( public ActionResult SendGeneralCommand(
[FromRoute] string sessionId, [FromRoute] string? sessionId,
[FromRoute] string command) [FromRoute] string? command)
{ {
var currentSession = RequestHelpers.GetSession(_sessionManager, _authContext, Request); var currentSession = RequestHelpers.GetSession(_sessionManager, _authContext, Request);
@ -270,7 +270,7 @@ namespace Jellyfin.Api.Controllers
[HttpPost("/Sessions/{sessionId}/Command")] [HttpPost("/Sessions/{sessionId}/Command")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult SendFullGeneralCommand( public ActionResult SendFullGeneralCommand(
[FromRoute] string sessionId, [FromRoute] string? sessionId,
[FromBody, Required] GeneralCommand command) [FromBody, Required] GeneralCommand command)
{ {
var currentSession = RequestHelpers.GetSession(_sessionManager, _authContext, Request); var currentSession = RequestHelpers.GetSession(_sessionManager, _authContext, Request);
@ -303,9 +303,9 @@ namespace Jellyfin.Api.Controllers
[HttpPost("/Sessions/{sessionId}/Message")] [HttpPost("/Sessions/{sessionId}/Message")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult SendMessageCommand( public ActionResult SendMessageCommand(
[FromRoute] string sessionId, [FromRoute] string? sessionId,
[FromQuery] string text, [FromQuery] string? text,
[FromQuery] string header, [FromQuery] string? header,
[FromQuery] long? timeoutMs) [FromQuery] long? timeoutMs)
{ {
var command = new MessageCommand var command = new MessageCommand
@ -330,7 +330,7 @@ namespace Jellyfin.Api.Controllers
[HttpPost("/Sessions/{sessionId}/User/{userId}")] [HttpPost("/Sessions/{sessionId}/User/{userId}")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult AddUserToSession( public ActionResult AddUserToSession(
[FromRoute] string sessionId, [FromRoute] string? sessionId,
[FromRoute] Guid userId) [FromRoute] Guid userId)
{ {
_sessionManager.AddAdditionalUser(sessionId, userId); _sessionManager.AddAdditionalUser(sessionId, userId);
@ -347,7 +347,7 @@ namespace Jellyfin.Api.Controllers
[HttpDelete("/Sessions/{sessionId}/User/{userId}")] [HttpDelete("/Sessions/{sessionId}/User/{userId}")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult RemoveUserFromSession( public ActionResult RemoveUserFromSession(
[FromRoute] string sessionId, [FromRoute] string? sessionId,
[FromRoute] Guid userId) [FromRoute] Guid userId)
{ {
_sessionManager.RemoveAdditionalUser(sessionId, userId); _sessionManager.RemoveAdditionalUser(sessionId, userId);
@ -368,9 +368,9 @@ namespace Jellyfin.Api.Controllers
[HttpPost("/Sessions/Capabilities")] [HttpPost("/Sessions/Capabilities")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult PostCapabilities( public ActionResult PostCapabilities(
[FromQuery] string id, [FromQuery] string? id,
[FromQuery] string playableMediaTypes, [FromQuery] string? playableMediaTypes,
[FromQuery] string supportedCommands, [FromQuery] string? supportedCommands,
[FromQuery] bool supportsMediaControl, [FromQuery] bool supportsMediaControl,
[FromQuery] bool supportsSync, [FromQuery] bool supportsSync,
[FromQuery] bool supportsPersistentIdentifier = true) [FromQuery] bool supportsPersistentIdentifier = true)
@ -401,7 +401,7 @@ namespace Jellyfin.Api.Controllers
[HttpPost("/Sessions/Capabilities/Full")] [HttpPost("/Sessions/Capabilities/Full")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult PostFullCapabilities( public ActionResult PostFullCapabilities(
[FromQuery] string id, [FromQuery] string? id,
[FromBody, Required] ClientCapabilities capabilities) [FromBody, Required] ClientCapabilities capabilities)
{ {
if (string.IsNullOrWhiteSpace(id)) if (string.IsNullOrWhiteSpace(id))
@ -424,8 +424,8 @@ namespace Jellyfin.Api.Controllers
[HttpPost("/Sessions/Viewing")] [HttpPost("/Sessions/Viewing")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult ReportViewing( public ActionResult ReportViewing(
[FromQuery] string sessionId, [FromQuery] string? sessionId,
[FromQuery] string itemId) [FromQuery] string? itemId)
{ {
string session = RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id; string session = RequestHelpers.GetSession(_sessionManager, _authContext, Request).Id;

View File

@ -75,9 +75,9 @@ namespace Jellyfin.Api.Controllers
[HttpPost("Configuration")] [HttpPost("Configuration")]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public ActionResult UpdateInitialConfiguration( public ActionResult UpdateInitialConfiguration(
[FromForm] string uiCulture, [FromForm] string? uiCulture,
[FromForm] string metadataCountryCode, [FromForm] string? metadataCountryCode,
[FromForm] string preferredMetadataLanguage) [FromForm] string? preferredMetadataLanguage)
{ {
_config.Configuration.UICulture = uiCulture; _config.Configuration.UICulture = uiCulture;
_config.Configuration.MetadataCountryCode = metadataCountryCode; _config.Configuration.MetadataCountryCode = metadataCountryCode;

View File

@ -112,7 +112,7 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<IEnumerable<RemoteSubtitleInfo>>> SearchRemoteSubtitles( public async Task<ActionResult<IEnumerable<RemoteSubtitleInfo>>> SearchRemoteSubtitles(
[FromRoute] Guid itemId, [FromRoute] Guid itemId,
[FromRoute] string language, [FromRoute] string? language,
[FromQuery] bool? isPerfectMatch) [FromQuery] bool? isPerfectMatch)
{ {
var video = (Video)_libraryManager.GetItemById(itemId); var video = (Video)_libraryManager.GetItemById(itemId);
@ -132,7 +132,7 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
public async Task<ActionResult> DownloadRemoteSubtitles( public async Task<ActionResult> DownloadRemoteSubtitles(
[FromRoute] Guid itemId, [FromRoute] Guid itemId,
[FromRoute] string subtitleId) [FromRoute] string? subtitleId)
{ {
var video = (Video)_libraryManager.GetItemById(itemId); var video = (Video)_libraryManager.GetItemById(itemId);
@ -161,7 +161,7 @@ namespace Jellyfin.Api.Controllers
[Authorize(Policy = Policies.DefaultAuthorization)] [Authorize(Policy = Policies.DefaultAuthorization)]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
[Produces(MediaTypeNames.Application.Octet)] [Produces(MediaTypeNames.Application.Octet)]
public async Task<ActionResult> GetRemoteSubtitles([FromRoute] string id) public async Task<ActionResult> GetRemoteSubtitles([FromRoute] string? id)
{ {
var result = await _subtitleManager.GetRemoteSubtitles(id, CancellationToken.None).ConfigureAwait(false); var result = await _subtitleManager.GetRemoteSubtitles(id, CancellationToken.None).ConfigureAwait(false);
@ -186,9 +186,9 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult> GetSubtitle( public async Task<ActionResult> GetSubtitle(
[FromRoute, Required] Guid itemId, [FromRoute, Required] Guid itemId,
[FromRoute, Required] string mediaSourceId, [FromRoute, Required] string? mediaSourceId,
[FromRoute, Required] int index, [FromRoute, Required] int index,
[FromRoute, Required] string format, [FromRoute, Required] string? format,
[FromQuery] long? endPositionTicks, [FromQuery] long? endPositionTicks,
[FromQuery] bool copyTimestamps, [FromQuery] bool copyTimestamps,
[FromQuery] bool addVttTimeMap, [FromQuery] bool addVttTimeMap,
@ -254,7 +254,7 @@ namespace Jellyfin.Api.Controllers
public async Task<ActionResult> GetSubtitlePlaylist( public async Task<ActionResult> GetSubtitlePlaylist(
[FromRoute] Guid itemId, [FromRoute] Guid itemId,
[FromRoute] int index, [FromRoute] int index,
[FromRoute] string mediaSourceId, [FromRoute] string? mediaSourceId,
[FromQuery, Required] int segmentLength) [FromQuery, Required] int segmentLength)
{ {
var item = (Video)_libraryManager.GetItemById(itemId); var item = (Video)_libraryManager.GetItemById(itemId);
@ -324,7 +324,7 @@ namespace Jellyfin.Api.Controllers
/// <returns>A <see cref="Task{Stream}"/> with the new subtitle file.</returns> /// <returns>A <see cref="Task{Stream}"/> with the new subtitle file.</returns>
private Task<Stream> EncodeSubtitles( private Task<Stream> EncodeSubtitles(
Guid id, Guid id,
string mediaSourceId, string? mediaSourceId,
int index, int index,
string format, string format,
long startPositionTicks, long startPositionTicks,

View File

@ -193,7 +193,7 @@ namespace Jellyfin.Api.Controllers
[HttpGet("Logs/Log")] [HttpGet("Logs/Log")]
[Authorize(Policy = Policies.RequiresElevation)] [Authorize(Policy = Policies.RequiresElevation)]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
public ActionResult GetLogFile([FromQuery, Required] string name) public ActionResult GetLogFile([FromQuery, Required] string? name)
{ {
var file = _fileSystem.GetFiles(_appPaths.LogDirectoryPath) var file = _fileSystem.GetFiles(_appPaths.LogDirectoryPath)
.First(i => string.Equals(i.Name, name, StringComparison.OrdinalIgnoreCase)); .First(i => string.Equals(i.Name, name, StringComparison.OrdinalIgnoreCase));

View File

@ -190,7 +190,7 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<QueryResult<BaseItemDto>> GetEpisodes( public ActionResult<QueryResult<BaseItemDto>> GetEpisodes(
[FromRoute] string seriesId, [FromRoute] string? seriesId,
[FromQuery] Guid userId, [FromQuery] Guid userId,
[FromQuery] string? fields, [FromQuery] string? fields,
[FromQuery] int? season, [FromQuery] int? season,
@ -311,12 +311,12 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public ActionResult<QueryResult<BaseItemDto>> GetSeasons( public ActionResult<QueryResult<BaseItemDto>> GetSeasons(
[FromRoute] string seriesId, [FromRoute] string? seriesId,
[FromQuery] Guid userId, [FromQuery] Guid userId,
[FromQuery] string fields, [FromQuery] string? fields,
[FromQuery] bool? isSpecialSeason, [FromQuery] bool? isSpecialSeason,
[FromQuery] bool? isMissing, [FromQuery] bool? isMissing,
[FromQuery] string adjacentTo, [FromQuery] string? adjacentTo,
[FromQuery] bool? enableImages, [FromQuery] bool? enableImages,
[FromQuery] int? imageTypeLimit, [FromQuery] int? imageTypeLimit,
[FromQuery] string? enableImageTypes, [FromQuery] string? enableImageTypes,

View File

@ -164,8 +164,8 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<AuthenticationResult>> AuthenticateUser( public async Task<ActionResult<AuthenticationResult>> AuthenticateUser(
[FromRoute, Required] Guid userId, [FromRoute, Required] Guid userId,
[FromQuery, BindRequired] string pw, [FromQuery, BindRequired] string? pw,
[FromQuery, BindRequired] string password) [FromQuery, BindRequired] string? password)
{ {
var user = _userManager.GetUserById(userId); var user = _userManager.GetUserById(userId);
@ -483,7 +483,7 @@ namespace Jellyfin.Api.Controllers
/// <returns>A <see cref="Task"/> containing a <see cref="ForgotPasswordResult"/>.</returns> /// <returns>A <see cref="Task"/> containing a <see cref="ForgotPasswordResult"/>.</returns>
[HttpPost("ForgotPassword")] [HttpPost("ForgotPassword")]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<ForgotPasswordResult>> ForgotPassword([FromBody] string enteredUsername) public async Task<ActionResult<ForgotPasswordResult>> ForgotPassword([FromBody] string? enteredUsername)
{ {
var isLocal = HttpContext.Connection.RemoteIpAddress.Equals(HttpContext.Connection.LocalIpAddress) var isLocal = HttpContext.Connection.RemoteIpAddress.Equals(HttpContext.Connection.LocalIpAddress)
|| _networkManager.IsInLocalNetwork(HttpContext.Connection.RemoteIpAddress.ToString()); || _networkManager.IsInLocalNetwork(HttpContext.Connection.RemoteIpAddress.ToString());
@ -501,7 +501,7 @@ namespace Jellyfin.Api.Controllers
/// <returns>A <see cref="Task"/> containing a <see cref="PinRedeemResult"/>.</returns> /// <returns>A <see cref="Task"/> containing a <see cref="PinRedeemResult"/>.</returns>
[HttpPost("ForgotPassword/Pin")] [HttpPost("ForgotPassword/Pin")]
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status200OK)]
public async Task<ActionResult<PinRedeemResult>> ForgotPasswordPin([FromBody] string pin) public async Task<ActionResult<PinRedeemResult>> ForgotPasswordPin([FromBody] string? pin)
{ {
var result = await _userManager.RedeemPasswordResetPin(pin).ConfigureAwait(false); var result = await _userManager.RedeemPasswordResetPin(pin).ConfigureAwait(false);
return result; return result;

View File

@ -265,12 +265,12 @@ namespace Jellyfin.Api.Controllers
public ActionResult<IEnumerable<BaseItemDto>> GetLatestMedia( public ActionResult<IEnumerable<BaseItemDto>> GetLatestMedia(
[FromRoute] Guid userId, [FromRoute] Guid userId,
[FromQuery] Guid parentId, [FromQuery] Guid parentId,
[FromQuery] string fields, [FromQuery] string? fields,
[FromQuery] string includeItemTypes, [FromQuery] string? includeItemTypes,
[FromQuery] bool? isPlayed, [FromQuery] bool? isPlayed,
[FromQuery] bool? enableImages, [FromQuery] bool? enableImages,
[FromQuery] int? imageTypeLimit, [FromQuery] int? imageTypeLimit,
[FromQuery] string enableImageTypes, [FromQuery] string? enableImageTypes,
[FromQuery] bool? enableUserData, [FromQuery] bool? enableUserData,
[FromQuery] int limit = 20, [FromQuery] int limit = 20,
[FromQuery] bool groupItems = true) [FromQuery] bool groupItems = true)

View File

@ -66,7 +66,7 @@ namespace Jellyfin.Api.Controllers
[FromRoute] Guid userId, [FromRoute] Guid userId,
[FromQuery] bool? includeExternalContent, [FromQuery] bool? includeExternalContent,
[FromQuery] bool includeHidden, [FromQuery] bool includeHidden,
[FromQuery] string presetViews) [FromQuery] string? presetViews)
{ {
var query = new UserViewQuery var query = new UserViewQuery
{ {

View File

@ -50,7 +50,7 @@ namespace Jellyfin.Api.Controllers
[ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status404NotFound)]
public async Task<ActionResult<FileStreamResult>> GetAttachment( public async Task<ActionResult<FileStreamResult>> GetAttachment(
[FromRoute] Guid videoId, [FromRoute] Guid videoId,
[FromRoute] string mediaSourceId, [FromRoute] string? mediaSourceId,
[FromRoute] int index) [FromRoute] int index)
{ {
try try

View File

@ -133,7 +133,7 @@ namespace Jellyfin.Api.Controllers
[Authorize(Policy = Policies.RequiresElevation)] [Authorize(Policy = Policies.RequiresElevation)]
[ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status400BadRequest)] [ProducesResponseType(StatusCodes.Status400BadRequest)]
public ActionResult MergeVersions([FromQuery] string itemIds) public ActionResult MergeVersions([FromQuery] string? itemIds)
{ {
var items = RequestHelpers.Split(itemIds, ',', true) var items = RequestHelpers.Split(itemIds, ',', true)
.Select(i => _libraryManager.GetItemById(i)) .Select(i => _libraryManager.GetItemById(i))

View File

@ -64,16 +64,16 @@ namespace Jellyfin.Api.Controllers
public ActionResult<QueryResult<BaseItemDto>> GetYears( public ActionResult<QueryResult<BaseItemDto>> GetYears(
[FromQuery] int? startIndex, [FromQuery] int? startIndex,
[FromQuery] int? limit, [FromQuery] int? limit,
[FromQuery] string sortOrder, [FromQuery] string? sortOrder,
[FromQuery] string parentId, [FromQuery] string? parentId,
[FromQuery] string fields, [FromQuery] string? fields,
[FromQuery] string excludeItemTypes, [FromQuery] string? excludeItemTypes,
[FromQuery] string includeItemTypes, [FromQuery] string? includeItemTypes,
[FromQuery] string mediaTypes, [FromQuery] string? mediaTypes,
[FromQuery] string sortBy, [FromQuery] string? sortBy,
[FromQuery] bool? enableUserData, [FromQuery] bool? enableUserData,
[FromQuery] int? imageTypeLimit, [FromQuery] int? imageTypeLimit,
[FromQuery] string enableImageTypes, [FromQuery] string? enableImageTypes,
[FromQuery] Guid userId, [FromQuery] Guid userId,
[FromQuery] bool recursive = true, [FromQuery] bool recursive = true,
[FromQuery] bool? enableImages = true) [FromQuery] bool? enableImages = true)

View File

@ -23,7 +23,7 @@ namespace Jellyfin.Api.Extensions
/// <param name="dtoOptions">DtoOptions object.</param> /// <param name="dtoOptions">DtoOptions object.</param>
/// <param name="fields">Comma delimited string of fields.</param> /// <param name="fields">Comma delimited string of fields.</param>
/// <returns>Modified DtoOptions object.</returns> /// <returns>Modified DtoOptions object.</returns>
internal static DtoOptions AddItemFields(this DtoOptions dtoOptions, string fields) internal static DtoOptions AddItemFields(this DtoOptions dtoOptions, string? fields)
{ {
if (string.IsNullOrEmpty(fields)) if (string.IsNullOrEmpty(fields))
{ {
@ -126,7 +126,7 @@ namespace Jellyfin.Api.Extensions
bool? enableImages, bool? enableImages,
bool? enableUserData, bool? enableUserData,
int? imageTypeLimit, int? imageTypeLimit,
string enableImageTypes) string? enableImageTypes)
{ {
dtoOptions.EnableImages = enableImages ?? true; dtoOptions.EnableImages = enableImages ?? true;

View File

@ -20,7 +20,7 @@ namespace Jellyfin.Api.Helpers
/// <param name="separator">The char that separates the substrings.</param> /// <param name="separator">The char that separates the substrings.</param>
/// <param name="removeEmpty">Option to remove empty substrings from the array.</param> /// <param name="removeEmpty">Option to remove empty substrings from the array.</param>
/// <returns>An array of the substrings.</returns> /// <returns>An array of the substrings.</returns>
internal static string[] Split(string value, char separator, bool removeEmpty) internal static string[] Split(string? value, char separator, bool removeEmpty)
{ {
if (string.IsNullOrWhiteSpace(value)) if (string.IsNullOrWhiteSpace(value))
{ {
@ -99,16 +99,14 @@ namespace Jellyfin.Api.Helpers
/// <param name="sortBy">Sort by.</param> /// <param name="sortBy">Sort by.</param>
/// <param name="requestedSortOrder">Sort order.</param> /// <param name="requestedSortOrder">Sort order.</param>
/// <returns>Resulting order by.</returns> /// <returns>Resulting order by.</returns>
internal static ValueTuple<string, SortOrder>[] GetOrderBy(string sortBy, string requestedSortOrder) internal static ValueTuple<string, SortOrder>[] GetOrderBy(string? sortBy, string? requestedSortOrder)
{ {
var val = sortBy; if (string.IsNullOrEmpty(sortBy))
if (string.IsNullOrEmpty(val))
{ {
return Array.Empty<ValueTuple<string, SortOrder>>(); return Array.Empty<ValueTuple<string, SortOrder>>();
} }
var vals = val.Split(','); var vals = sortBy.Split(',');
if (string.IsNullOrWhiteSpace(requestedSortOrder)) if (string.IsNullOrWhiteSpace(requestedSortOrder))
{ {
requestedSortOrder = "Ascending"; requestedSortOrder = "Ascending";

View File

@ -23,7 +23,7 @@ namespace Jellyfin.Api.Helpers
IDtoService dtoService, IDtoService dtoService,
Guid userId, Guid userId,
string id, string id,
string excludeArtistIds, string? excludeArtistIds,
int? limit, int? limit,
Type[] includeTypes, Type[] includeTypes,
Func<BaseItem, List<PersonInfo>, List<PersonInfo>, BaseItem, int> getSimilarityScore) Func<BaseItem, List<PersonInfo>, List<PersonInfo>, BaseItem, int> getSimilarityScore)