Diferenciar Guid y los Parámetros de la cadena en MVC 3

El uso de la fuera-de-la-método del cuadro de localizadores en ASP.NET MVC (3 o 4DP), hay una manera de tener el marco de MVC diferenciar entre una cuerda y el Guid sin necesidad de analizar el parámetro en el controlador de acción?

Ejemplos de uso sería para la dirección URL

http://[dominio]/cliente/detalles/F325A917-04F4-4562-B104-AF193C41FA78

para ejecutar el

public ActionResult Details(Guid guid)

método, y

http://[dominio]/cliente/detalles/bill-gates

para ejecutar el

public ActionResult Details(string id)

método.

Sin cambios, obviamente, los métodos son ambiguos, como sigue:

public ActionResult Details(Guid id)
{
    var model = Context.GetData(id);
    return View(model);
}

public ActionResult Details(string id)
{
    var model = Context.GetData(id);
    return View(model);
}

lo que produce el error:

The current request for action 'Details' on controller type 'DataController' is ambiguous between the following action methods:
System.Web.Mvc.ActionResult Details(System.Guid) on type Example.Web.Controllers.DataController
System.Web.Mvc.ActionResult Details(System.String) on type Example.Web.Controllers.DataController 

He intentado usar un custom restricción (basado en ¿Cómo puedo crear una ruta de restricción de tipo de Sistema.Guid?) para intentar empujar a través través de de enrutamiento:

routes.MapRoute(
    "Guid",
    "{controller}/{action}/{guid}",
    new { controller = "Home", action = "Index" }, 
    new { guid = new GuidConstraint() }
);

routes.MapRoute(
    "Default", //Route name
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);

Y conmutación de la acción de firmas para:

public ActionResult Details(Guid guid)
{
    var model = Context.GetData(guid);
    return View(model);
}

public ActionResult Details(string id)
{
    var model = Context.GetData(id);
    return View(model);
}

La restricción se ejecuta y pasa, por lo tanto el argumento es enviado a una acción, pero aparentemente todavía como una cadena, y por lo tanto ambiguo a las dos firmas de método. Creo que hay algo en cómo los métodos de acción se encuentra que las causas de la ambigüedad, y por lo tanto podría ser anulado mediante la conexión de un módulo personalizado para localizar métodos.

El mismo resultado puede lograrse mediante el análisis de la cadena de parámetro, pero sería muy bueno que la brevedad para evitar que la lógica de la acción (por no hablar de que con suerte reutilizar algún día más tarde).

Tienes razón, el método de acción del localizador es ajeno a la ruta de la restricción. Si se quita la cadena de método de acción, no el guid método de acción obtener elegido?
MVC no soporta la sobrecarga de método basado exclusivamente en la firma – la solución más fácil para que usted probablemente sería simplemente tener las dos con nombre único en los métodos de acción, uno de los detalles por GUID (Detalles) y otro para obtener detalles por nombre (o Búsqueda de Información, tal vez?).
Correcto, la eliminación de la cadena de acción seleccione el Guid (suponiendo que pasa la restricción O puede ser analizado en un Guid).

OriginalEl autor falquan | 2011-09-27

3 Kommentare

  1. 11

    Primer lugar, usted debe disambigute sus métodos dándoles dos nombres diferentes:

    public ActionResult DetailsGuid(Guid guid)
    {
        var model = Context.GetData(guid);
        return View(model); 
    }
    
    public ActionResult DetailsString(string id)
    {
        var model = Context.GetData(id);
        return View(model);
    } 

    Después, usted necesita una ruta personalizada de controlador para inspeccionar la solicitud, y cambiar el nombre del método en consecuencia:

    using System.Web.Mvc; 
    using System.Web.Routing; 
    
    public class MyRouteHandler : IRouteHandler 
    { 
        public IHttpHandler GetHttpHandler(RequestContext requestContext) 
        { 
            var routeData = requestContext.RouteData; 
            var stringValue = routeData.Values["id"].ToString();
            Guid guidValue; 
            var action = routeData.Values["action"]; 
            if (Guid.TryParse(stringValue, out guidValue) && (guidValue != Guid.Empty);
                routeData.Values["action"] = action + "Guid"; 
    
            else
                routeData.Values["action"] = action + "String"; 
    
            var handler = new MvcHandler(requestContext); 
            return handler; 
        } 
    } 

    Por último, añadir un Details ruta en la parte superior de las rutas, de la siguiente manera:

    routes.Add("Details", 
        new Route("{controller}/Details/{id}", 
            new RouteValueDictionary( 
                new { controller = "Home", action = "Details" }), 
                new MyRouteHandler()
            )
        ); 
    );

    Cuando llega una solicitud para obtener más detalles, el Details la ruta de usar su propio controlador de ruta para inspeccionar el id token. La ruta del controlador añade al nombre de la acción basado en la forma de la id de token, por lo que la solicitud será dirigida a la acción apropiada.

    OriginalEl autor counsellorben

  2. 8

    Mi opinión es que el uso de la acción selector de método es más útil y menos de codificación.

    public class GuidMethodSelectorAttribute : ActionMethodSelectorAttribute
    {
        public override bool IsValidForRequest(ControllerContext controllerContext, System.Reflection.MethodInfo methodInfo)
        {
            var idStr = controllerContext.RouteData.Values["id"];
            if (idStr == null)
                return false;
            Guid a;
            var result = Guid.TryParse(idStr.ToString(), out a);
            return result;
        }
    }

    Este selector inspecciona solicitud de parámetro ID. Si es guid, devuelve true. Así, para usarlo:

    public class HomeController : Controller
    {
        [GuidMethodSelector]
        public ActionResult Index(Guid id)
        {
            return View();
        }
        public ActionResult Index(string id)
        {
            return View();
        }
    }
    Usted puede utilizar el incorporado GuidRouteConstraint clase en lugar de tener que agregar código personalizado. Agradezco que esto no puede haber sido el caso en el momento de la escritura.

    OriginalEl autor Nickmaovich

  3. 7

    Si usted todavía está el registro de las rutas en este modo, la GuidRouteConstraint() de la clase fue añadido en la versión más reciente de MVC y debe ser utilizado en lugar de una implementación personalizada:

    public override void RegisterArea(AreaRegistrationContext context)
    {
        context.MapRoute(
            "Guid",
            "{controller}/{action}/{guid}",
            new { controller = "Home", action = "Index" }, 
            new { guid = new GuidRouteConstraint() }
        );
    }

    Entonces usted puede simplemente crear su acción como resultado:

    public class HomeController : Controller {
        public ActionResult Index(Guid guid) {
        }
    }
    Trabajó un tratamiento, sólo asegúrese de usar el tipo correcto de using declaración – usted probablemente querrá using System.Web.Mvc.Routing.Constraints; y no del Sistema.Web.Http.De enrutamiento.Restricciones

    OriginalEl autor Laurence C

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Recent Articles

Python «set» con duplicados/elementos repetidos

Hay una forma estándar de representar un "conjunto" que puede contener elementos duplicados. Como yo lo entiendo, un conjunto tiene exactamente un cero o...

Python: generador de expresión vs rendimiento

En Python, ¿hay alguna diferencia entre la creación de un generador de objetos a través de un generador de expresión versus el uso de...

Cómo exportar/importar la Masilla lista de sesiones?

Hay una manera de hacer esto? O tengo que tomar manualmente cada archivo de Registro? InformationsquelleAutor s.webbandit | 2012-10-23

no distingue mayúsculas de minúsculas coincidentes en xpath?

Por ejemplo, para el xml a continuación <CATALOG> <CD title="Empire Burlesque"/> <CD title="empire burlesque"/> <CD...