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

发布于 2024-10-14 07:15:09 字数 1720 浏览 1 评论 0原文

我不知道这是否是正确的方法,但我正在使用 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。

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

有什么帮助吗?对这篇文章的稳健性表示歉意……

谢谢。

I don't know if this is the right way of doing this or not, but I am using Jquery and MVC2. I am using a the $.ajax method to make a call back to a controller to do some business logic on a .blur of a textbox.

I have two views that basically do the same thing with the common data, but are using different models. They both use the same controller. It might be easier to explain with code:

So here are the two models:

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; }
}

There are two views that are strongly typed to these models. One is RecordModel, the other SecondaryModel.

Now on these views is a input="text" that is created via:

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

There is jQuery javascript that binds the .blur method to a call:

<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>

The controller looks like:

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

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

Now this works fine if I explicitly name the RecordModel in the controller for the View that uses the RecordModel. However, the SecondaryModel view also tries to call this function, and it fails because it's expecting the RecordModel and not the SecondaryModel.

So my question is this. How can two different strongly typed views use the same Action in a controller and still adhering to the modeling pattern? I've tried abstract classes and interfaces (and changing the view pages to use the Interface/abstract class) and it still fails.

Any help? And sorry for the robustness of the post...

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

南渊 2024-10-21 07:15:09

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

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.");
}

You could define an interface for those classes.

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

and make the method receive the model by using that:

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

    return this.Json("Validated.");
}
不再让梦枯萎 2024-10-21 07:15:09

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

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

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

If you only need the RecordID, you can just have the controller method take int RecordID and it will pull that out of the form post data instead of building the view model back up and providing that to your action method.

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

    return this.Json("Validated.");
}
二手情话 2024-10-21 07:15:09

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

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

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

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

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

编辑在我亲爱的SO同伴@Charles Boyung在下面发表了慷慨的(但错误的)评论后,我得出的结论是我的答案并不完全准确。所以我修正了我在这里使用的一些术语 - 希望现在更清楚了。

There is no direct way of binding data to a interface/abstract class. The DefaultModelBinder will try to instantiate that type, which is (by definition) impossible.

So, IMHO, you should not use that option. And if you still want to share the same controller action between the two views, the usual way of doing that would be using a ViewModel.

Make your strongly-typed views reference that viewmodel. Make the single shared action receive an instance of it. Inside the action, you will decide which "real" model should be used...

If you need some parameter in order to distinguish where the post came from (view 1 or 2), just add that parameter to the ajax call URL.

Of course, another way is keeping what you have already tried (interface/abstract class), but you'll need a custom Model Binder in that case... Sounds like overcoding to me, but it's your choice.

Edit After my dear SO fellow @Charles Boyung made a gracious (and wrong) comment below, I've come to the conclusion that my answer was not exactly accurate. So I have fixed some of the terminology that I've used here - hope it is clearer now.

烏雲後面有陽光 2024-10-21 07:15:09

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

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

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
}

In the case above your action could accept two strings instead of a concrete type.

Another possibility is having two actions. Each action taking one of your types. I'm assuming that functionality each type is basically the same. Once the values have been extracted hand them off to a method. In your case method will probably be the same for each action.

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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文