1

我不知道这是否是正确的做法,但我使用的是 Jquery 和 MVC2。我正在使用 $.ajax 方法来回调控制器以在文本框的 .blur 上执行一些业务逻辑。

我有两个视图,它们基本上对公共数据做同样的事情,但使用不同的模型。他们都使用相同的控制器。用代码解释可能更容易:

所以这里有两个模型:

public class RecordModel {
    public string RecordID { get; set; }
    public string OtherProperties { get; set; }
}

public class SecondaryModel {
    public string RecordID { get; set; }
    public string OtherPropertiesDifferentThanOtherModel { get; set; }
}

这些模型有两个强类型视图。一个是RecordModel,另一个是SecondaryModel。

现在在这些视图上是通过以下方式创建的 input="text":

<%= Html.TextBoxFor(model => model.RecordID) %>

有 jQuery javascript 将 .blur 方法绑定到调用:

<script>
    $('#RecordID').blur(function() {
        var data = new Object();
        data.RecordID = $('#RecordID').val();
        // Any other stuff needed

        $.ajax({
            url: '/Controller/ValidateRecordID',
            type: 'post',
            dataType: 'json',
            data: data,
            success: function(result) {
                 alert('success: ' + result);
            },
            error: function(result) {
                 alert('failed');
            }
         });
      }
 </script>

控制器看起来像:

[HttpPost]
public ActionResult ValidateRecordID(RecordModel model) {
    // TODO: Do some verification code here

    return this.Json("Validated.");
}

现在,如果我在控制器中为使用 RecordModel 的视图显式命名 RecordModel,这将正常工作。但是,SecondaryModel 视图也尝试调用此函数,但它失败了,因为它需要的是 RecordModel 而不是 SecondaryModel。

所以我的问题是这个。两个不同的强类型视图如何在控制器中使用相同的 Action 并且仍然遵守建模模式?我已经尝试过抽象类和接口(并更改视图页面以使用接口/抽象类),但它仍然失败。

有什么帮助吗?并为帖子的稳健性感到抱歉......

谢谢。

4

4 回答 4

1

您可以为这些类定义一个接口。

interface IRecord
{
    string RecordID { get; set; }
    string OtherProperties { get; set; }
}

并使用以下方法使该方法接收模型:

[HttpPost]
public ActionResult ValidateRecordID(IRecord model) 
{
    // TODO: Do some verification code here

    return this.Json("Validated.");
}
于 2011-01-26T19:20:58.180 回答
0

如果您只需要 RecordID,您可以让控制器方法采用 int RecordID,它会将其从表单发布数据中提取出来,而不是构建视图模型备份并将其提供给您的操作方法。

[HttpPost]
public ActionResult ValidateRecordID(int RecordID) {
    // TODO: Do some verification code here

    return this.Json("Validated.");
}
于 2011-01-26T19:19:36.867 回答
0

没有将数据绑定到接口/抽象类的直接方法。DefaultModelBinder 将尝试实例化该类型,这(根据定义)是不可能的。

所以,恕我直言,您不应该使用该选项。如果您仍然想在两个视图之间共享相同的控制器操作,那么通常的方法是使用ViewModel

让您的强类型视图引用该视图模型。使单个共享操作接收它的一个实例。在动作中,您将决定应该使用哪个“真实”模型......

如果您需要一些参数来区分帖子的来源(视图 1 或 2),只需将该参数添加到 ajax 调用 URL。

当然,另一种方法是保留您已经尝试过的内容(接口/抽象类),但在这种情况下您将需要一个自定义模型绑定器......对我来说听起来像是过度编码,但这是您的选择。

编辑在我亲爱的 SO 伙伴@Charles Boyung 在下面发表了一个亲切(和错误)的评论之后,我得出的结论是我的回答并不完全准确。所以我已经修正了我在这里使用的一些术语——希望现在更清楚了。

于 2011-01-26T19:18:34.463 回答
0

在上述情况下,您的操作可以接受两个字符串而不是具体类型。

另一种可能性是有两个动作。每个动作采取你的一种类型。我假设每种类型的功能基本相同。一旦提取了值,就将它们交给一个方法。在您的情况下,每个操作的方法可能都是相同的。

public ActionResult Method1(Record record)
{
ProcessAction(record.id, record.Property);

}

public ActionResult Action2(OtherRecord record)
{

ProcessAction(record.id, record.OtherProperty);

}


private void ProcessAction(string id, string otherproperity)
{
//make happen
}
于 2011-01-26T20:36:29.050 回答