Asp.net mvc 3 使用接口作为局部视图的模型类型+;数据注释

Asp.net mvc 3 使用接口作为局部视图的模型类型+;数据注释,asp.net-mvc-3,interface,data-annotations,partial-views,Asp.net Mvc 3,Interface,Data Annotations,Partial Views,我有一个例子,复杂的局部视图需要根据局部视图的使用位置对字段进行不同的验证 我想我可以通过使局部视图采用一个接口作为模型类型,并基于该接口实现两个不同的视图模型来解决这个问题。两个ViewModel中的数据注释将不同。然后,我将向局部视图提供正确ViewModel的实例 但我发现,唯一被识别的注释是接口本身上的注释。实现ViewModel类的接口上的DAs将被忽略,即使这些是作为模型传递的对象。所以我的计划行不通 有办法解决这个问题吗?更好的方法?如果可以避免的话,我不希望将局部视图分割成单独的

我有一个例子,复杂的局部视图需要根据局部视图的使用位置对字段进行不同的验证

我想我可以通过使局部视图采用一个接口作为模型类型,并基于该接口实现两个不同的视图模型来解决这个问题。两个ViewModel中的数据注释将不同。然后,我将向局部视图提供正确ViewModel的实例

但我发现,唯一被识别的注释是接口本身上的注释。实现ViewModel类的接口上的DAs将被忽略,即使这些是作为模型传递的对象。所以我的计划行不通

有办法解决这个问题吗?更好的方法?如果可以避免的话,我不希望将局部视图分割成单独的视图

ETA:根据要求,这是局部视图的缩写版本:

@model IPerson
@Html.ValidationSummary(false)
<fieldset>
    <table class="editForm">
        <tr>
            <td class="editor-label">
                @Html.LabelFor(model => model.FirstName)
            </td>
            <td class="editor-field">
                @Html.EditorFor(model => model.FirstName)
                @Html.ValidationMessageFor(model => model.FirstName)
            </td>
            <td class="editor-label">
                @Html.LabelFor(model => model.LastName)
            </td>
            <td class="editor-field">
                @Html.EditorFor(model => model.LastName)
                @Html.ValidationMessageFor(model => model.LastName)
            </td>
        </tr>
     </table>
  <fieldset>
@model IPerson
@Html.ValidationSummary(false)
@LabelFor(model=>model.FirstName)
@EditorFor(model=>model.FirstName)
@Html.ValidationMessageFor(model=>model.FirstName)
@LabelFor(model=>model.LastName)
@EditorFor(model=>model.LastName)
@Html.ValidationMessageFor(model=>model.LastName)

真正的局部视图相当长,有许多@if语句管理可选部分的呈现(或不呈现),但它没有做任何棘手的事情

我的想法行不通:提醒我类不会从接口继承属性。(正如答案所指出的,如果两个接口使用不同的属性指定了相同的属性,并且都由一个类实现,会发生什么情况?)

它可能与公共基类一起工作。我明天就试试


谢谢大家

安,你说得对。我已经删除了我的评论。无法通过视图发回接口。然而,我不知道你到底想做什么,因为我看不到你的代码。也许是这样的?我正在向视图传递一个接口,但将其作为我期望的类传递回去。同样,我不确定应用程序是否在这里

假设您有这样的课程

[MetadataType(typeof(PersonMetaData))]
public class Customer : IPerson {
    public int ID { get; set; }
    public string Name { get; set; }
     [Display(Name = "Customer Name")]
    public string CustomerName { get; set; }
}

public class Agent : IPerson {
    public int ID { get; set; }
    public string Name { get; set; }
}

public partial class PersonMetaData : IPerson {
    [Required]
    public int ID { get; set; }

    [Required]
    [Display(Name="Full Name")]
    public string Name { get; set; }
}

public interface IPerson {
    int ID { get; set; }
    string Name { get; set; }
}

public interface IAgent {
    int AgentType { get; set; }
}

public interface ICustomer {
    int CustomerType { get; set; }
}
    public ActionResult InterfaceView() {
        IPerson person = new Customer {
            ID = 1
        };
        return View(person);
    }

    [HttpPost]
    public ActionResult InterfaceView(Customer person) {
        if (ModelState.IsValid) {
            TempData["message"] = string.Format("You posted back Customer Name {0} with an ID of {1} for the name: {2}", person.CustomerName, person.ID, person.Name);
        }
        return View();
    }
您的控制器看起来像

[MetadataType(typeof(PersonMetaData))]
public class Customer : IPerson {
    public int ID { get; set; }
    public string Name { get; set; }
     [Display(Name = "Customer Name")]
    public string CustomerName { get; set; }
}

public class Agent : IPerson {
    public int ID { get; set; }
    public string Name { get; set; }
}

public partial class PersonMetaData : IPerson {
    [Required]
    public int ID { get; set; }

    [Required]
    [Display(Name="Full Name")]
    public string Name { get; set; }
}

public interface IPerson {
    int ID { get; set; }
    string Name { get; set; }
}

public interface IAgent {
    int AgentType { get; set; }
}

public interface ICustomer {
    int CustomerType { get; set; }
}
    public ActionResult InterfaceView() {
        IPerson person = new Customer {
            ID = 1
        };
        return View(person);
    }

    [HttpPost]
    public ActionResult InterfaceView(Customer person) {
        if (ModelState.IsValid) {
            TempData["message"] = string.Format("You posted back Customer Name {0} with an ID of {1} for the name: {2}", person.CustomerName, person.ID, person.Name);
        }
        return View();
    }
您的视图如下所示:

@model DataTablesExample.Controllers.Customer

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

@if (@TempData["message"] != null) {
    <p>@TempData["message"]</p>
}

@using (Html.BeginForm()) {
    @Html.ValidationSummary(true)
    <fieldset>
        <legend>IPerson</legend>

        @Html.HiddenFor(model => model.ID)

        <div class="editor-label">
            @Html.LabelFor(model => model.Name)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.Name)
            @Html.ValidationMessageFor(model => model.Name)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.CustomerName)
        </div>
        <div class="editor-field">
            @Html.EditorFor(model => model.CustomerName)
            @Html.ValidationMessageFor(model => model.CustomerName)
        </div>

        <p>
            <input type="submit" value="Save" />
        </p>
    </fieldset>
}
@model datatableexample.Controllers.Customer
@如果(@TempData[“message”!=null){
@TempData[“消息”]

} @使用(Html.BeginForm()){ @Html.ValidationSummary(true) 伊佩森 @Html.HiddenFor(model=>model.ID) @LabelFor(model=>model.Name) @EditorFor(model=>model.Name) @Html.ValidationMessageFor(model=>model.Name) @LabelFor(model=>model.CustomerName) @EditorFor(model=>model.CustomerName) @Html.ValidationMessageFor(model=>model.CustomerName)

}
好吧,实际上你有一个非常合理的想法!如果您使用非通用版本的HtmlHelper方法(例如“@Html.Editor”而不是“@Html.EditorFor”),则可以存档,因为通用版本基于通用参数类型重新创建ModelMetadata(我不知道为什么!),而不使用视图的ModelMetadata。太可怕了,不是吗


希望这有帮助。

你能发布部分视图吗?@MattyMo页面很长,但我会尝试提出一个缩写版本。这与我试图做的很接近,只是我的视图将IPerson而不是Customer作为模型类型。这是因为我希望能够向视图传递两个不同的派生类(具有不同的元数据)。但这不起作用:派生类上的元数据被忽略。在通宵考虑之后,我想我会将一些常见的复杂内容从视图中分解成更小的部分视图,并拥有两个视图,而不是试图在模型之间共享一个视图。非常感谢您的评论和回答<代码>您无法通过视图发回界面。没有任何意义。您的意思是不能将值发布到采用接口的方法吗?您当然可以使用自定义模型活页夹。此外,仅仅因为您使用
Model/Interface-A
创建视图,绝对不意味着控制器上的post方法必须使用
Model/Interface-A
作为参数。@chrfin我想我没有这样做。不幸的是,很久以前我就不记得我是如何处理这个问题的了,而且我再也不能访问源代码了。很抱歉,我无法提供更多帮助。事实上,我可以确认,使用非*For()版本的方法可以工作。例如,使用Html.textBox(“Name”,Model.Name)代替Html.TextBoxFor(m=>m.Name)。