MVC2和两个不同的模型使用相同的控制器方法?可能?

时间:2011-01-26 19:14:30

标签: asp.net jquery asp.net-mvc-2 views controllers

我不知道这是否是正确的方法,但我使用的是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的View显式命名RecordModel,则此工作正常。但是,SecondaryModel视图也尝试调用此函数,但它失败了,因为它期望RecordModel而不是SecondaryModel。

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

有任何帮助吗?对于帖子的稳健性感到抱歉...

感谢。

4 个答案:

答案 0 :(得分: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.");
}

答案 1 :(得分:0)

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

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

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

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

当然,另一种方法是保留你已经尝试过的东西(界面/抽象类),但在这种情况下你需要一个custom Model Binder ......听起来像是在给我过度编码,但这是你的选择。

编辑在亲爱的SO同事@Charles Boyung在下面做了一个优雅(和错误的)评论后,我得出的结论是我的回答并不准确。所以我修复了一些我在这里使用过的术语 - 希望现在更清楚了。

答案 2 :(得分:0)

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

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

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

答案 3 :(得分: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
}