2

我有一个看起来像这样的用户界面:

在此处输入图像描述

我正在尝试将新创建的行的数据发送到服务器,以便服务器可以保存它。

我正在将 JSON 格式的数据从客户端发送到我的 MVC 应用程序。这是我的ajax请求:

var values = []; // an array with each item being an object/associative array

// more code to get values into variables

for (var i = 0; i < cultures.length; i++) {
  var cultureName = cultures[i];
  var valueTextBox = $(row).find(...);
  var value = $(valueTextBox).val();

  var cultureNameAndValue = { 'CultureShortName' : cultureName, 'StringValue' : value };

  values.push(cultureNameAndValue);
}

var stringTableRow = 
  { 
    'ResourceKeyId': resourceKeyId, 
    'Key': resourceKeyName, 
    'CategoryId': categoryId, 
    'CategoryName': categoryName, 
    'StringValues': values 
  };

var stringified = JSON.stringify({ StringTableRow: stringTableRow });

$.ajax('/Strings/JsonCreateNew', 
      { 
        cache: false, 
        async: false, 
        type: 'POST', 
        contentType: 'application/json; charset=UTF-8', 
        data: stringified, 
        dataType: 'json', 
        error: SaveNewResourceClientSideHandler.OnError, 
        success: SaveNewResourceClientSideHandler.OnSuccess 
      });

这是它发送的数据(如 Firebug 中所示):

{"StringTableRow":{"ResourceKeyId":"","Key":"Foo",
"CategoryId":"1","CategoryName":"JavaScript",
"StringValues":[
{"CultureShortName":"en-US","StringValue":"Something"},
{"CultureShortName":"fr-FR","StringValue":""}]
}}

这是我的服务器端代码:

public ActionResult JsonCreateNew(StringTableRow row)
{
  // CreateNewStringTableRow(row);

  // return a success code, new resource key id, new category id
  // return Json(
              new { Success = true, ResourceKeyId = row.ResourceKeyId, 
                    CategoryId = row.CategoryId }, 
                JsonRequestBehavior.AllowGet);

  return new EmptyResult();
}

这是我希望传入的 POST 数据绑定到的业务对象:

public class StringTableRow
{
    public StringTableRow()
    {
        StringValues = new List<CultureNameAndStringValue>();
    }

    public long ResourceKeyId { get; set; }

    public string Key { get; set; }

    public long CategoryId { get; set; }

    public string CategoryName { get; set; }

    public IList<CultureNameAndStringValue> StringValues { get; set; }  
}


public class CultureNameAndStringValue
{
  public string CultureShortName { get; set; }

  public string StringValue { get; set; }
}

全球.asax

public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();

            WebApiConfig.Register(GlobalConfiguration.Configuration);
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);

            ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());
        }
    }

问题:

该操作JsonCreateNew接收一个不为空但所有属性都未初始化的对象,即所有可为空的属性都为空,而值属性为其默认值。因此,即使客户端发送了一个完全有效的 Json 字符串,我也根本没有得到任何数据。

我需要做自定义模型绑定吗?

4

2 回答 2

2

好的,我解决了我的问题,这对于其他程序员来说可能也是一个重要的见解,因为我在解决自己的问题时学到了一些东西。

我的解决方案: 我不使用 JSON,而是使用 HTTP 用于编码表单发布值的默认编码,然后我使用了一些有点自定义模型绑定的东西(实际上没有创建模型绑定器)。

说明: 通常情况下,当你发出ajax请求,从客户端向任何服务器平台传递数据时,如果你没有指定编码,即contentTypejQuery的ajax方法的settings对象中的参数(或者你使用任何其他方式发出 jQuery 以外的 ajax 请求,然后设置ContentTypeHTTP 标头就是您所追求的),HTTP 使用其默认编码对您发布的数据进行编码,这很像您在查询字符串之后使用 GET 请求发布的内容,只有它是二进制编码的,而不是作为 URL 的一部分发送的。

如果是这种情况,并且您将任何类型(IListIEnumerableICollectionIDictionary等)的集合发布到 ASP.NET MVC,则不要在 JavaScript 中创建关联数组来体现该集合。甚至不要创建数组。不要创造任何东西。

实际上,只需使用约定在主要的大对象中传递它:

data = 
{ /*scalar property */ Gar: 'har', 
  /* collection */ 'Foo[index++].Bar' : 'value1', 
  'Foo[index++].Bar' : 'value2'
}

并且不要使用 JSON。这将解决你一半的问题。

在服务器端,接收 a 中发布的数据,FormCollection并使用它的IValueProvider方法 ( GetValue) 挖掘出你需要的数据。您不必显式创建模型绑定器来执行此操作。您可以在控制器本身的私有方法中执行此操作。

当我有更多时间时,我会稍后改进这个答案。

于 2013-10-15T16:43:42.643 回答
-3

使用 Backbone 或 KnockoutJs 进行数据绑定。

于 2013-10-10T20:31:03.760 回答