jeudi 23 juillet 2015

HtmlHelper on type parameter of generic view-model

I'm trying to create an HtmlHelper method on a strongly-typed view, where the view-model is a generic. But there's a complication. I want to simplify my syntax so I can specify a member expression of a property on my view-model. Consider the following.

public interface ViewModel<T>
{
    T Model { get; set; }
}

public class DocViewModel : ViewModel<Document> 
{
    public IEnumerable<string> Options { get; set; }
    public Document Model { get; set; }
}

public class Document
{
    public string Name { get; set; }
    public string Value { get; set; }
}

Now, I can easily create a helper that references the view-model itself, and use it like so:

@model DocViewModel
<div>
    @Html.DoSomething(vm => vm.Options);
    @Html.DoSomethingElse(vm => vm.Model.Name);
    @Html.DoSomethingYetAgain(vm => vm.Model.Value);
</div>

But I'd like to be able to pass simply an expression on the Model, like so:

@model DocViewModel
<div>
    @Html.DoSomething(vm => vm.Options);
    @Html.DoSomethingElse(vm => vm.Name);
    @Html.DoSomethingYetAgain(vm => vm.Value);
</div>

Now, I can write the helper in such a way that I can do this if I explicitly reference the type parameters in my calls:

@model DocViewModel
<div>
     @Html.DoSomething<Document>(vm => vm.Name);
</div>

But that sort of defeats the purpose of what I'm going after. It seems like I should be able to write an HtmlHelper that can exploit the fact that the view is strongly-typed on DocViewModel, which itself is a KoViewModel, and that @Html() returns

HtmlHelper<DocViewModel> //HtmlHelper<KoViewModel<Document>>

so that the type-param that Document represents is known implicitly, and so that I can write

public static string DoSomethingElse<TModel, TProperty>(this HtmlHelper<KoViewModel<TModel>> helper, Expression<Func<TModel, TProperty>> expression) 
{
    return "Whatever";
}

but that conversion can't be done. So is there any way I can do this? Or am I just going to have to live with the ugly syntax?

Aucun commentaire:

Enregistrer un commentaire