简体   繁体   中英

How to avoid duplication when using custom route tokens and attribute routing?

Right now, I have the following code in my asp.net core mvc app:

using System.Threading.Tasks;
using jean.nl.Extensions;
using jean.services.Constants;
using jean.services.Extensions;
using jean.services.Repositories;
using jean.services.Services;
using Microsoft.AspNetCore.Mvc;

namespace jean.nl.Areas.Employer.Controllers
{
    [Area(AreaConstants.Employer)]
    [Route("[area]/Employee/Notify")]
    public class EmployeeNotificationController : BaseController
    {
        private readonly UserRepository _userRepository;
        private readonly EmployeeRegistrationService _employeeRegistrationService;
        public EmployeeNotificationController(UserRepository userRepository,
            EmployeeRegistrationService employeeRegistrationService)
        {
            _userRepository = userRepository;
            _employeeRegistrationService = employeeRegistrationService;
        }

        [Route("{employeeId}/[action]")]
        public async Task<bool> RegistrationPending(string employeeId)
        {
            return await _employeeRegistrationService
                .NotifyRegistrationPendingAsync(User.UserId(), employeeId);
        }

        [Route("{employeeId}/[action]")]
        public async Task<bool> IdUploadPending(string employeeId)
        {
            return await _employeeRegistrationService
                .NotifyIdUploadPendingAsync(User.UserId(), employeeId);
        }

        [Route("{employeeId}/[action]")]
        public async Task<bool> ContractSignaturePending(string employeeId)
        {
            return await _employeeRegistrationService
                .NotifyContractSignaturePendingAsync(User.UserId(), employeeId);
        }

        [Route("{employeeId}/[action]")]
        public async Task<bool> DocumentSignaturePending(string employeeId)
        {
            return await _employeeRegistrationService
                .NotifyDocumentSignaturePendingAsync(User.UserId(), employeeId);
        }
    }
}

What I'm achieving with this is to match urls of the kind ~/Employer/Employee/Notify/{employeeId}/{action} . While this approach succeeds, I cannot help but feel there's a lot of unneccessary duplication. For one thing, each and every action is marked with the same Route attribute, which makes me question whether I could achieve the same goal differently. I tried defining a global route of the form with the following snippet of code,

routes.MapRoute(
    name: "notify_employee",
    template: "{area:exists}/Employee/Notify/{employeeId}/{action}",
    defaults: new { controller = "EmployeeNotificationController" });

but to no avail. Is there any way to get what I'm looking for which would prevent me from having to decorate every action of my controller?

After a bit of thinking, I found a solution by defining the route attribute and the action methods the following way:

[Route("[area]/Employee/{id:guid}/Notify/[action]")]
public class EmployeeNotificationController : BaseController
{
    // some code...

    public async Task<bool> RegistrationPending(string id)
    {
        return await _employeeRegistrationService
            .NotifyRegistrationPendingAsync(User.UserId(), id);
    }

    // some more code...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM