0

Currently I'm using a base class for some Customer model classes. As defined as follows

public abstract class BaseCustomerModel<T>
   where T : IUserEntity

For further clarification, the IUserEntity contains:

public interface IUserEntity
{
   string ErrorMessage { get; }
}

That property among some other things will be exposed in an ErrorTextControl.ascx:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<(...).Models.BaseCustomerModel<(...).IUserEntity>>" %>

<tr>
   <td colspan="2"><%: Html.DisplayFor(model => model.ErrorMessage) %></td>
</tr>

I'll call the user control like so:

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<(...).Models.MyUserModel>" %>
<% if (Model.HasErrors)
   {
      Html.RenderPartial("ErrorTextControl", Model);
   } %>

Last piece of code (MyUserEntity implements IUserEntity):

public class MyUserModel : BaseCustomerModel<MyUserEntity>

Unfortunately this obviously doesn't work, because the generic type can't be implicitly casted to an IUserEntity. Therefore resulting in the following error message in the browser:

Exception Details: System.InvalidOperationException: The model item passed into the dictionary is of type '(...).Models.MyUserModel', but this dictionary requires a model item of type '(...).Models.BaseCustomerModel`1[(...).IUserEntity]'.

So questions:

  • Is there any way to define a user control with a generic base class from which the type is not yet known? If yes, how to accomplish such thing?
  • If not, any workaround, common solution or ideas to be able to have a generic user control?

Many thanks.

3
  • monty - you'll need some sort of common interface (apart from IUserEntity ) that will be bound. have you identified this??. i say this because you'll be strongly typing sets of properties, therefore these properties will need to be part of a contract. if it's just the IUserEntity part that needs to be exposed to the ErrorTextControl.ascx, then why not: <%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IUserEntity>" %> - or am i completely missing the point here :) Commented Dec 9, 2010 at 10:10
  • Jep, just found out myself too... see the answer I posted. Commented Dec 9, 2010 at 10:13
  • good - you know it makes sense!! ;) Commented Dec 9, 2010 at 10:18

2 Answers 2

1

Well, just came up with a solution myself.

Just an extra interface to BaseCustomerModel:

public abstract class BaseCustomerModel<T> : IContainErrorMessage
   where T : IUserEntity

That way the user control doesn't have to worry about the generics:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<(...).Models.IContainErrorMessage>" %>
Sign up to request clarification or add additional context in comments.

Comments

1

You could try this:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<dynamic>" %>

1 Comment

Well good shot!! It should be with this of course: 'Inherits="System.Web.Mvc.ViewUserControl<(...).Models.BaseCustomerModel<dynamic>>"', but unfortunately: Compiler Error Message: CS0311: The type 'dynamic' cannot be used as type parameter 'T' in the generic type or method '(...).Models.BaseCustomerModel<T>'. There is no implicit reference conversion from 'dynamic' to '(...).IUserEntity'.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.