Tengo un controlador que está hecho con ASP.NET y realmente quiero simplificar eso con una vista rápida:

// REST representation of Storage
// There is always at least two options to view them
// Data as is or Quick view at metrics averages
[Route("metrics")]
public class MetricsController : Controller
{
    // Get raw Storage object
    [HttpGet]
    public IActionResult GetStorageView()
    {   
        // TODO: do not use in production
        WSManModule.HyperVMetric.test(false);
        //

        var response = MetricsService.Instance.GetRawMetrics();

        if (response == null)
        {
            return NotFound();
        }

        if (Request.QueryString.Value == "?q=quick")
        {
            return Ok(new StorageQuickView(response));
        }

        return Ok(response);
    }

    // Get metrics for specific device
    [HttpGet("{deviceName}")]
    public IActionResult GetDeviceView(string deviceName)
    {
        var response = MetricsService.Instance.GetDeviceMetrics(deviceName);

        if (response == null)
        {
            return NotFound();
        }

        if (Request.QueryString.Value == "?q=quick")
        {
            return Ok(new DeviceQuickView(response));
        }

        return Ok(response);
    }

    // Get metrics for specific component within the device
    [HttpGet("{deviceName}/{componentName}")]
    public IActionResult GetComponentView(string deviceName, string componentName)
    {
        var response = MetricsService.Instance.GetComponentMetrics(deviceName, componentName);

        if (response == null)
        {
            return NotFound();
        }

        if (Request.QueryString.Value == "?q=quick")
        {
            return Ok(new ComponentQuickView(response));
        }

        return Ok(response);
    }
}

Ahora tiene mucha repetición y no me gusta. ¿Hay alguna forma de hacerlo bien con parámetros opcionales como {quick?} o algo similar?

Simplemente: quiero realizar diferentes operaciones si tenemos /quick al final de la ruta o no.

0
Roman 22 feb. 2018 a las 19:59

2 respuestas

La mejor respuesta

Simplemente acepte el parámetro q con sus acciones:

// Get raw Storage object
[HttpGet]
public IActionResult GetStorageView(string q)
{   
    // TODO: do not use in production
    WSManModule.HyperVMetric.test(false);
    //

    var response = MetricsService.Instance.GetRawMetrics();

    if (response == null)
    {
        return NotFound();
    }

    if (q == "quick")
    {
        return Ok(new StorageQuickView(response));
    }

    return Ok(response);
}

// Get metrics for specific device
[HttpGet("{deviceName}")]
public IActionResult GetDeviceView(string deviceName, string q)
{
    var response = MetricsService.Instance.GetDeviceMetrics(deviceName);

    if (response == null)
    {
        return NotFound();
    }

    if (q == "quick")
    {
        return Ok(new DeviceQuickView(response));
    }

    return Ok(response);
}

Los parámetros del método de acción no son solo derivados de rutas. Los valores provienen de Proveedores de valor y uno de los proveedores predeterminados analiza la cadena de consulta. Por lo tanto, solo necesita agregar el valor de la cadena de consulta a los parámetros de su método de acción en lugar de analizar o comparar la cadena de consulta manualmente.

1
NightOwl888 22 feb. 2018 a las 17:07

Puedes crear un método privado como este:

private IAction ProcessResponse<T>(IMyResponseType response)
{
    if(response == null)
    {
        return NotFound();
    }

    if (Request.QueryString.Value == "?q=quick")
    {
        var okInstance = (T) Activator.CreateInstance(typeof (T), response);
        return Ok(okInstance);
    }

    return Ok(response);
}

Y usarlo así:

// Get metrics for specific component within the device
[HttpGet("{deviceName}/{componentName}")]
public IActionResult GetComponentView(string deviceName, string componentName)
{
    var response = MetricsService.Instance.GetComponentMetrics(deviceName, componentName);

    return ProcessResponse<ComponentQuickView>(response);
}

// Get raw Storage object
[HttpGet]
public IActionResult GetStorageView()
{   
    // TODO: do not use in production
    WSManModule.HyperVMetric.test(false);
    //

    var response = MetricsService.Instance.GetRawMetrics();

    return ProcessResponse<StorageQuickView>(response);
}
0
DotNet Fan 22 feb. 2018 a las 17:54