Estoy escribiendo un poco sucia método de extensión para HtmlHelper para que yo pueda decir algo como HtmlHelper.WysiwygFor(lambda) y mostrar el CKEditor.

Tengo esta trabajando actualmente, pero parece un poco más complicado de lo que yo prefiero. Tengo la esperanza de que hay una forma más sencilla de hacer esto.

Aquí es lo que tengo hasta ahora.

public static MvcHtmlString WysiwygFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
{
    return MvcHtmlString.Create(string.Concat("<textarea class=\"ckeditor\" cols=\"80\" id=\"",
                                        expression.MemberName(), "\" name=\"editor1\" rows=\"10\">", 
                                        GetValue(helper, expression),
                                        "</textarea>"));
}

private static string GetValue<TModel, TProperty>(HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression)
{
    MemberExpression body = (MemberExpression)expression.Body;
    string propertyName = body.Member.Name;
    TModel model = helper.ViewData.Model;
    string value = typeof(TModel).GetProperty(propertyName).GetValue(model, null).ToString();
    return value;
}

private static string MemberName<T, V>(this Expression<Func<T, V>> expression)
{
    var memberExpression = expression.Body as MemberExpression;
    if (memberExpression == null)
            throw new InvalidOperationException("Expression must be a member expression");

    return memberExpression.Member.Name;
}

Gracias!

  • He probado el método Getvalue y tengo una buena resuts cuando el ayudante es un selectlist. Los otros métodos aquí fallado en este caso.

6 Comentarios

  1. 83

    Tratar como este:

    public static MvcHtmlString Try<TModel, TProperty>(
        this HtmlHelper<TModel> htmlHelper, 
        Expression<Func<TModel, TProperty>> expression
    )
    {
        var builder = new TagBuilder("textarea");
        builder.AddCssClass("ckeditor");
        builder.MergeAttribute("cols", "80");
        builder.MergeAttribute("name", "editor1");
        builder.MergeAttribute("id", expression.Name); //not sure about the id - verify
        var value = ModelMetadata.FromLambdaExpression(
            expression, htmlHelper.ViewData
        ).Model;
        builder.SetInnerText(value.ToString());
        return MvcHtmlString.Create(builder.ToString());
    }
    • Yo estaba más interesado en esta línea de la anterior – var valor = ModelMetadata.FromLambdaExpression( expresión, htmlHelper.ViewData ).Modelo; que funcionó muy bien! Me di cuenta que su expresión.Nombre devuelve null. Cambié de que a punto a mi nombre de usuario método para conseguir que el trabajo para la IDENTIFICACIÓN. También, he encontrado que hay una TagBuilder.GenerateId() para añadir el atributo ID. Gracias. Voy asegúrese de mencionar que en mi próximo libro (ASP.NET MVC libro de cocina – groups.google.com/group/aspnet-mvc-2-cookbook-review)
    • Hola darin, puede usted por favor me explique esta línea? var value = ModelMetadata.FromLambdaExpression( expression, htmlHelper.ViewData ).Model;
  2. 25
    ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
    Object value = metadata.Model;
    String name = metadata.PropertyName;
    • Esto me está funcionando correctamente y recibe el nombre de la propiedad a través de PropertyName, donde la expresión.Nombre devuelve null. Editar para agregar – me estoy quedando MVC5 en caso de que los asuntos
  3. 10

    Sé que este es un hilo viejo, pero en caso de que si alguien está buscando, la manera de generar el id /nombre de atributo es también:

    System.Web.Mvc.ExpressionHelper.GetExpressionText(expression);

    Estoy usando esto en mis extensiones y nunca tuvo problemas con él. También funciona muy bien con las propiedades anidadas.

    • De esta manera se consigue el nombre de la Propiedad, pero no su Valor
  4. 5

    Forma más sencilla es meterlo todo en un método de extensión:

    public static class ExtensionMethods
    {   
    
        public static object Value<TModel, TProperty>(this Expression<Func<TModel, TProperty>> expression, ViewDataDictionary<TModel> viewData)
        {
            return ModelMetadata.FromLambdaExpression(expression, viewData).Model;
        }  
    
    }

    Por lo que la sintaxis de llamada es:

    expression.Value(htmlHelper.ViewData)
  5. 1

    Esto no se trata por tanto de Pedro o BigMomma la respuesta, pero combina ambos. Si usted está llamando a este de un método de controlador, donde no se tiene acceso a un HtmlHelper ejemplo, acaba de crear un controlador de base de método como este:

    public ModelMetadata GetModelMetadata<TModel, TProperty>( TModel model, Expression<Func<TModel, TProperty>> expression )
    {
        ViewData.Model = model; //model is null in Controller; you must set it here (or earlier) in order to extract values from the returned ModelMetadata.
        return ModelMetadata.FromLambdaExpression( expression, new ViewDataDictionary<TModel>( ViewData ) );
    }

    A continuación, se puede leer lo que usted necesita desde el modelo de metadatos como de costumbre;

    var mm = GetModelMetaData( model, m => m.SomeProperty );
    string name = mm.PropertyName;
    object value = mm.Model;

Dejar respuesta

Please enter your comment!
Please enter your name here