Маршрутизация ODATA не работает для конечных точек после обновления до .NET 8C#

Место общения программистов C#
Ответить
Anonymous
 Маршрутизация ODATA не работает для конечных точек после обновления до .NET 8

Сообщение Anonymous »

Я определил конфигурацию модели для регистрации EntitySet и EntityTypes для ODATA:

Код: Выделить всё

public class NotificationEntryModelConfiguration : IModelConfiguration
{
/// 
public void Apply(ODataModelBuilder builder, ApiVersion apiVersion, string routePrefix)
{
builder.Namespace = "NotificationService.Api";
builder.EntitySet("NotificationEntry")
.EntityType
.HasKey(p => p.Id);
ConfigureAlertDto(builder);
builder.EntityType()
.Collection
.Action("UpdateRead")
.Parameter("body");
builder.EntityType()
.Collection
.Action("DeleteBulk")
.Parameter("body");
}

private static void ConfigureAlertDto(ODataModelBuilder builder)
{
builder.AddEnumType(typeof(NotificationComponent));
builder.AddEnumType(typeof(NotificationSeverity));
builder.AddEnumType(typeof(UserNotificationState));

var entityType = builder.EntitySet("Alerts").EntityType;
entityType.HasKey(p => p.Id);
entityType.Property(p => p.Id).Name = "Id";
entityType.Property(p => p.NotificationName).Name = "NotificationName";
entityType.Property(p => p.Data).Name = "Data";
entityType.EnumProperty(p => p.Component).Name = "Component";
entityType.EnumProperty(p => p.Severity).Name = "Severity";
entityType.Property(p => p.CreationTime).Name = "CreationTime";
entityType.EnumProperty(p => p.State).Name = "State";
entityType.Property(p => p.UserNotificationId).Name = "UserNotificationId";
entityType.Property(p => p.DeepLinkRelativeUrl).Name = "DeepLinkRelativeUrl";
}
}
В моем файле Startup я регистрирую службу ODATA, создаю модели и добавляю компоненты маршрута. Предположим, что функция ConfigureCommonervices вызывается из запуска :

Код: Выделить всё

protected override void ConfigureCommonServices(IServiceCollection services) where TStartup : class
{
base.ConfigureCommonServices(services);
services.AddCustomHealthCheck(Configuration);
services.AddCustomCors(Configuration);

// Discover local OData model configurations if any
var startupAssembly = typeof(TStartup).Assembly;
var modelConfigTypes = startupAssembly
.GetTypes()
.Where(t => typeof(IModelConfiguration).IsAssignableFrom(t) && t.IsClass && !t.IsAbstract)
.ToArray();

var controllersBuilder = services.AddControllers(options => options.Filters.Add(typeof(ValidatorActionFilter)))
.AddNewtonsoftJson(options =>
{
options.SerializerSettings.Converters.Add(new StringEnumConverter());
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
});

// Always add API versioning (Swagger depends on IApiVersionDescriptionProvider)
services.AddCustomVersioning();

if (modelConfigTypes.Length > 0)
{
// Enable OData features
controllersBuilder.AddOData(opt =>
{
opt.Select().Expand().Filter().OrderBy().SetMaxTop(1000).Count();
opt.EnableQueryFeatures();
});

// Add OData integration to versioning now that controllersBuilder OData is registered
services.AddODataApiVersioning();

// Build versioned EDM models and register route components using discovered configurations
services.AddOptions()
.Configure((options, versionProvider) =>
{
var configs = new List(modelConfigTypes.Length);
foreach (var t in modelConfigTypes)
{
if (Activator.CreateInstance(t) is IModelConfiguration cfg)
{
configs.Add(cfg);
}
}
var builder = new VersionedODataModelBuilder(versionProvider, configs);
var models = builder.GetEdmModels();
foreach (var model in models)
{
options.AddRouteComponents("odata/v{version:apiVersion}", model);
}
});

// Keep case-insensitive enum resolver
services.AddSingleton(sp => new StringAsEnumResolver { EnableCaseInsensitive = true });
}

services.AddSwagger();
services.AddAppInsightsTelemetry(Configuration);
services.CisAuthentication(Configuration);
}
< /code>
Контроллер OData определяется так: < /p>
public class NotificationEntryController : ODataController
{
private readonly IMediator mediator;

public NotificationEntryController(IMediator mediator)
{
this.mediator = mediator;
}

/// 
/// Retrieves all inAppNotifications.
/// 
/// All available products.
/// Products successfully retrieved.
[UiPathAuthorize(Policy = Policies.UserContext)]
// [DormantEnableQuery]
[Produces("application/json")]
[ProducesResponseType(typeof(ODataValue), Status200OK)]
[ProducesResponseType((int)HttpStatusCode.BadRequest)]
[EndpointSeverity(EndpointSeverity.CRITICAL)]
public async Task Get(ODataQueryOptions  queryOptions)
{
if (!(queryOptions.Count == null || bool.TryParse(queryOptions.Count.RawValue, out _)))
{
return this.BuildErrorResponse(string.Format(NotificationServiceConstants.InvalidCountQueryOption, queryOptions.Count.RawValue), (int)HttpStatusCode.BadRequest);
}

var res = await mediator.Send(new NotificationQueryOption(queryOptions));

return this.BuildGetPaginatedApiResponse(res);
}

/// 
/// Marks the passed notifications as read/unread.
/// 
/// NotificationReadRequestDto object
/// NoContentResult
[HttpPost]
[ProducesDefaultResponseType]
[ProducesResponseType((int)HttpStatusCode.BadRequest)]
[ProducesResponseType((int)HttpStatusCode.OK)]
[UiPathAuthorize(Policy = Policies.UserContext)]
[EndpointSeverity(EndpointSeverity.HIGH)]
public async Task UpdateRead([FromBody] NotificationReadRequestDto body)
{
var res = await mediator.Send(body);
return this.BuildPostApiResponse(res);
}

/// 
/// Deletes the notification entry
/// 
/// Collection of notification ids
/// NoContentResult
[HttpPost]
[ProducesDefaultResponseType]
[ProducesResponseType((int)HttpStatusCode.BadRequest)]
[ProducesResponseType((int)HttpStatusCode.OK)]
[UiPathAuthorize(Policy = Policies.UserContext)]
[EndpointSeverity(EndpointSeverity.MEDIUM)]
public async Task DeleteBulkAsync([FromBody] NotificationBulkDeleteRequestDto body)
{
var ids = body.NotifcationIds;
if (!ids.Any() && !body.DeleteAll)
{
return this.BuildErrorResponse(NotificationServiceConstants.InvalidBulkdDeleteRequest, (int)HttpStatusCode.BadRequest);
}
var res = await mediator.Send(body);
return this.BuildPostApiResponse(res);
}
}
Несмотря на то, что odata/v1/$ metadata показывает updateread и deletebulk , зарегистрированные как действия, когда я нажимаю пост -URL .../odata/v1/natificationEntry/natificationservice.api.updateread или для deletebulk phrows. /> Это было ранее реализовано для .net6, и после обновления до .net8 я добавил множество изменений для обработки маршрутизации Odata, для которой я добавил код.>

Подробнее здесь: https://stackoverflow.com/questions/797 ... g-to-net-8
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»