首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何通过.Net MVC4中带有JSON的ajax调用将复杂的视图模型传递给控制器操作?

如何通过.Net MVC4中带有JSON的ajax调用将复杂的视图模型传递给控制器操作?
EN

Stack Overflow用户
提问于 2014-01-04 01:30:49
回答 2查看 4.1K关注 0票数 3

因此,我尽可能多地搜索Stack溢出,却找不到这个特定问题的答案。如果这已经被问到了,我很抱歉。

我找到了以下问题的答案:

  • 如何将对象/类传递给操作
  • 如何通过查询字符串将对象传递给操作
  • 如何通过json将对象传递给操作
  • 如何将多态对象传递给操作并让自定义模型绑定处理它

假设您有以下代码,如何将上述技术组合成一个解决方案。因此,我希望使用json对象在控制器(使用jquery调用)上命中操作,将视图模型传递给操作,并让它确定正确的多态类型(在本例中是Notification类型)--可能通过使用自定义模型绑定器。

注意:这是用来说明问题的示例代码。

型号:

代码语言:javascript
复制
public class Notification
{
    public int ID { get; set; }
    public string ApplicationID { get; set; }
    public string Description { get; set; }
    public System.DateTime DateStamp { get; set; }
}

public class WarningNotification : Notification
{
    public string WarningText { get; set; }
}

public class AlertNotification : Notification
{
    public string AlertText { get; set; }
    public int AlertId { get; set; }
}

视图模型:

代码语言:javascript
复制
public class SaveNotificationViewModel
{
    public Notification Notification { get; set; }
    public string Hash { get; set; }
    public List<int> Users { get; set; }
}

主计长的行动:

代码语言:javascript
复制
public ActionResult Save(SaveNotificationViewModel model)
{
    //code inside method irrelevant...
}

模型粘合剂:

代码语言:javascript
复制
public class NoticationModelBinder : DefaultModelBinder
{
    protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
    {
        var typeValue = bindingContext.ValueProvider.GetValue("ModelType");
        var type = Type.GetType((string)typeValue.ConvertTo(typeof(string)), true);

        if (!typeof(Notification).IsAssignableFrom(type))
        {
            throw new InvalidCastException("Bad type");
        }

        var model = Activator.CreateInstance(type);
        bindingContext.ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(() => model, type);
        return model;
    }
}

最初的问题来源,把我从这个兔子洞和代码很大程度上借用了:Methodology for passing a mix of: list<>, object and primitives to an ASP MVC controller action

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-01-06 19:54:08

所以我想出的是..。我包括了WarningNotification和AlertNotification的代码。

对我来说,我忽略的关键是:

  1. 将"ModelType“放在JSON的根级,而不是在通知前缀下面(如"Notification.ModelType”)--这是错误的.不要那样做)。
  2. 所有字段都位于根类型(本例中为通知)之下,因此专门类型的字段仍然以“Notification”作为前缀。-参见"Notification.AlertId“。

Javascript代码将所有内容绑定在一起:

代码语言:javascript
复制
// this is an example warning notification
var data =
    {
        "Notification.Id": '21',
        "Notification.ApplicationId": 'TARDIS',
        "Notification.Description": "The most important warning notification ever!",
        "Notification.WarningText": "I gave them the wrong warning. I should have told them to run, as fast as they can. Run and hide, because the monsters are coming - the human race.",
        "ModelType": 'Models.WarningNotification',
        "Hash": '27ad5218-963a-4df8-8c90-ee67c5ba9f30'
    };

// this is an example alert notification
var data =
    {
        "Notification.Id": '21',
        "Notification.ApplicationId": 'TARDIS',
        "Notification.Description": "The most important alert notification ever!",
        "Notification.AlertText": "Rose,before I go, I just want to tell you, you were fantastic. Absolutely fantastic. And you know what....so was I.",
        "Notification.AlertId": "1024",
        "ModelType": 'Models.AlertNotification',
        "Hash": '27ad5218-963a-4df8-8c90-ee67c5ba9f32'
    };

$.ajax({
    type: 'POST',
    url: '/notification/save',
    dataType: 'json',
    data: data,
    success: function (result) {
        console.log('SUCCESS:');
        console.log(result);
    },
    error: function (xhr, ajaxOptions, thrownError) {
        console.log('ERROR:');
        console.log(thrownError);
    }
});
票数 0
EN

Stack Overflow用户

发布于 2014-01-04 02:04:57

因此,我希望使用json对象在控制器(使用jquery调用)上命中操作,将视图模型传递给操作,并让它确定正确的多态类型(在本例中是Notification类型)--可能通过使用自定义模型绑定器。

我建议不要使用任何一个动作。首先,尽管易于实现,但是自定义模型绑定与采取基本类型或接口的操作组合在一起通常会变得更难调试,更难进行单元测试,而且任何查看控制器操作的人都不能只通过查看操作本身就知道正在发生什么。

我强烈建议创建特定于正在发出的请求的操作。

我将这些简化为示例的相关代码。

代码语言:javascript
复制
public ProcessNotify(Notification model)
{
  this.SharedNotifyCode(model);

  // specific Notification only code
}

public ProcessWarningNotification(WarningNotification model)
{
  this.SharedNotifyCode(model);

  // specific WarningNotification only code
}

public ProcessAlertNotification(AlertNotification model)
{
  this.SharedNotifyCode(model);

  // specific AlertNotification only code
}

private SharedNotifyCode(Notification notification)
{
  // shared code
}

这很容易维护、调试、测试,而且代码本身也是自文档化的.

同样的事情可以用javascript (jQuery)代码来完成:

代码语言:javascript
复制
function ProcessNotify()
{
  notify = {
    ID = 1,
    ApplicationID = 2,
    Description = "description",
    DateStamp = new Date() // something like this.. forgot JS datetimes
    };

  SendNotify(notify, "ProcessNotify");
}

function ProcessWarning()
{
  notify = {
    ID = 1,
    ApplicationID = 2,
    Description = "description",
    DateStamp = new Date(), // something like this.. forgot JS datetimes
    WarningText = "Oh noes!"
    };

  SendNotify(notify, "ProcessWarningNotification");
}

function ProcessAlert()
{
  notify = {
    ID = 1,
    ApplicationID = 2,
    Description = "description",
    DateStamp = new Date(), // something like this.. forgot JS datetimes
    AlertText = "Oh noes!",
    AlertId = 3
    };

  SendNotify(notify, "ProcessAlertNotification");
}

function SendNotify(notify, action)
{
  var jqXHR = $.ajax({
    url: '/' + Controller + '/' + action,
    data: notify,
    type: "POST",
    success: function(result)
    {
    }
    // etc
  });
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20915681

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档