【问题标题】:Returning JSON to an Action in MVC 3.0将 JSON 返回到 MVC 3.0 中的操作
【发布时间】:2011-09-21 14:18:27
【问题描述】:

我承认,我很困惑:

我正在尝试返回一个已转换为 JSON 的简单对象,如下所示:

 viewModel.updateCoder = function (coder) {
   var coderJson = ko.toJSON(coder);
   var coderJsonString = ko.utils.stringifyJson(coderJson);
   $.ajax({
     url: "provider/UpdateCoder",
     type: 'POST',
     dataType: 'text',
     data: coderJsonString,
     contentType: 'text/csv',
     success: function () { alert("Updated!"); }
   });

我的 RouteTable 条目如下所示:

 routes.MapRoute(
    "UpdateCoder",
      "provider/UpdateCoder/{coderDTO}", // URL with parameters
    new { controller = "Provider", action = "UpdateCoder", coderDTO = UrlParameter.Optional }
    );

我的 Controler 操作如下所示:

[AcceptVerbs(HttpVerbs.Post)]
public string UpdateCoder( string coderDTO )
{
  var rslt = "success";
  //var coder = coderDTO.CoderDTOToCoder();
  return rslt;
}

我在 UpdateCoder 参数(字符串 coderDTO)中得到的是空值;

这是我的后备位置,我宁愿将 JSON 对象(coderJson)发送到操作,但我收到错误消息:“没有为此对象定义无参数构造函数。”当我这样做时,我将参数类型更改如下:

[AcceptVerbs(HttpVerbs.Post)]
public string UpdateCoder( **CoderDTO coderDTO** )
{
  var rslt = "success";
  //var coder = coderDTO.CoderDTOToCoder();
  return rslt;
}

连同:ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());在 Global.asax

CoderDTO 类如下所示:

public class CoderDTO
{
    public Int32 Id { get; set; }
    public String CoderCode { get; set; }
    public String Sal { get; set; }
    public String LName { get; set; }
    public String FName { get; set; }
    public String MI { get; set; }
    public String Facility { get; set; }
    public String Title { get; set; }
    public Boolean? IsContract { get; set; }
    public Boolean? IsInactive { get; set; }
    public Boolean? IsDeleted { get; set; }
    public String Comments { get; set; }
    public String AlternateId { get; set; }
    public int CasesCoded { get; set; }

    public CoderDTO(Coder coder)
    {
        Id = coder.Id;
        CoderCode = coder.CoderCode;
        Sal = coder.Sal;
        LName = coder.LName;
        FName = coder.FName;
        MI = coder.MI;
        Facility = coder.Facility;
        Title = coder.Title;
        if (coder.IsContract != null) IsContract = coder.IsContract;
        if (coder.IsInactive != null) IsInactive = coder.IsInactive;
        if (coder.IsDeleted != null) IsDeleted = coder.IsDeleted;
        Comments = coder.Comments;
        AlternateId = coder.AlternateId;
    }

    public Coder CoderDTOToCoder()
    {
        var coder = new Coder
                    {
                        Id = Id,
                        CoderCode = CoderCode,
                        Sal = Sal,
                        LName = LName,
                        FName = FName,
                        MI = MI,
                        Facility = Facility,
                        Title = Title
                    };
        coder.IsContract = IsContract ?? false;
        coder.IsInactive = IsInactive ?? false;
        coder.IsDeleted = IsDeleted ?? false;
        coder.Comments = Comments;
        coder.AlternateId = AlternateId;
        return coder;
    }


}

coderJsonString 如下所示:

{"Id":201,"CoderCode":"GP ","Sal":null,"LName":null,"FName":null,"MI":null,"IsContract":false,"IsInactive":false,"Comments":null,"CasesCoded":0,"isBeingEdited":false}

这是漫长的一天!感谢您的帮助,我正在吃晚饭!

【问题讨论】:

  • 您能否将 dto 对象与您发布到控制器的 JSON 示例 sn-p 一起包含在内?

标签: asp.net-mvc json asp.net-mvc-3 jquery knockout.js


【解决方案1】:

我找到了为什么我不能返回反序列化为我的 CoderDTO 对象的 JSON 的问题的答案:我的对象没有无参数的公共构造函数。我有一个 Coder 的构造函数参数,它填充了 CoderDTO。我把它分成一个单独的方法,现在可以工作了。

感谢

的帖子

StackOverflow - ASP.NET MVC 3 JSONP: Does this work with JsonValueProviderFactory?

【讨论】:

    【解决方案2】:

    我认为你最好的办法是弄清楚为什么你不能反序列化到你的 DTO。您至少需要为其添加一个默认构造函数。

    public CoderDTO() { }
    

    对于您当前传递字符串的情况,我认为您可以这样称呼它:

    viewModel.updateCoder = function (coder) {
       var coderJson = ko.toJSON(coder);
       var coderJsonString = ko.utils.stringifyJson({ coderDTO: coderJson });
       $.ajax({
         url: "provider/UpdateCoder",
         type: 'POST',
         dataType: 'text',
         data: coderJsonString,
         contentType: 'application/json; charset=utf-8',
         success: function () { alert("Updated!"); }
       });
    

    所以,基本上你创建一个带有参数名称和值的对象并将其字符串化。在这种情况下,coderJson 是双重编码的。

    【讨论】:

    • RP,谢谢,它适用于字符串值。我实际上尝试过这样做(包括 {coderDTO: coderJson} 并且它不起作用。也许是其他一些设置不正确,可能在路由中??但是,它令人困惑:为什么有一个 dataType 和一个 contentType?我我只是收到一个字符串,为什么“应用程序/json”工作?它是否关心我是否发送一个看起来不像 json 的字符串?也许它是去吃晚饭并清理我的头:-)。无论如何,现在讨论如何解析字符串化的 Json,或者更好地直接接收 CoderDTO。 -- 再次感谢!
    • 仅供参考,dataType 描述了您期望收到的内容,而contentType 描述了您发送的内容。当 JsonValueProvider 看到它接收的内容类型是 JSON 时,它就会启动。在这种情况下,您正在发送一个将 coderDTO 设置为字符串的对象,并且它与您的参数匹配。如果您有更多关于您当前状态的详细信息,我们很乐意为您提供帮助。理想情况下,您将希望直接在您的操作中接收您的对象(您也希望 contentType 为 json)。
    • 这是非常有用的信息。所以我经常在时间压力(或懒惰)下复制/粘贴一些代码,有点祈祷它会起作用。因此我的痛苦和痛苦:-)。有了这些信息,也许我可以把这个谜题放在一起。 ——娄
    【解决方案3】:

    尝试更改您的操作以使用 JsonResult:

    [AcceptVerbs(HttpVerbs.Post)]
    public JsonResult UpdateCoder(CoderDTO coderDTO)
    {
        var rslt = "success";
        //var coder = coderDTO.CoderDTOToCoder();
        return Json(rslt);
    }
    

    【讨论】:

    • 谢谢 duyker,你已经盯上了我真正的目标。我会尝试,但我的感觉是返回类型不会影响接收到的参数。
    猜你喜欢
    • 1970-01-01
    • 2011-08-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-11
    • 2013-06-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多