【问题标题】:POSTing an MVC style model to an external API将 MVC 样式模型发布到外部 API
【发布时间】:2014-02-04 15:16:15
【问题描述】:

我编写了一小段代码,它针对我的 MVC 应用程序连接到的外部 API 执行简单的 HTTP 发布。

代码有效,但我厌倦了从我的对象构建一个字符串以便发布它。我想做的是重新使用 MVC 模式的模型部分,然后发布。这就是我想做的事情。

MyModel model = new MyModel();
model.Name = "joe";
model.Age = 33;
model.Hobbies = new List<Hobby>();
model.Hobbies.Add(new Hobby{ hobby = "fargling", level = "expert"}); 
model.Hobbies.Add(new Hobby{ hobby = "dibbling", level = "novice"}); 

HttpHelper.doPOST("http://www.myservice.com/api", model);

doPost() 会将模型序列化为如下所示的字符串

Name=Joe&Age=33&Hobbies[0].hobby=fargling&Hobbies[0].level=expert&Hobbies[1].hobby=dibbling&Hobbies[1].level=novice

对于任何个别情况,我都可以编写代码来构建这样的字符串,但是是否有 .NET 方法已经可以做到这一点?

【问题讨论】:

    标签: c# asp.net-mvc post serialization


    【解决方案1】:

    我找到了一种解决方法,结果证明这是一种更好的做事方式。

    我可以简单地将对象序列化为 JSON,然后将 JSON 发布到 API,而不是 POST 查询字符串。我使用的 API 也接受 JSON,所以这为我省去了很多麻烦。

    对于任何对上述问题的解决方案感兴趣的人,我在这个问题下找到了一些结果 - How do I serialize an object into query-string format(这也是表达我想说的更好的方式)

    【讨论】:

      【解决方案2】:

      我不知道 C# 中有什么可以做到这一点,但你可以使用 jQuery 来做这个客户端。

      var data = @Html.Raw(Json.Encode(Model));
      var query = $.param(data);
      

      更新

      我没有注意到您刚刚决定使用 JSON。当然,如果 API 端点支持它,那是最简单和最好的选择(但真的有什么不支持的吗?)。尽管如此,我对如何在 C# 中将对象实际序列化为 x-www-form-urlecoded 很感兴趣,并且对我找不到任何内置方式感到非常惊讶。即使使用 Web API 中的FormUrlEncodedMediaTypeFormatter,他们通过将其设为只读格式化程序(即它可以将 x-www-form-urlencoded 读取到对象中,但反之不行)来回避问题。所以,我写了这种又快又脏的方法。 (注意:它使用反射,所以在这里插入火焰,但我不确定你还能如何实现这样的效果。)

      public void BuildFormUrlEncodedDataString(Type type, object obj, StringBuilder builder, string prefix = "")
      {
      
          var props = type.GetProperties();
          foreach (var prop in props)
          {
              if (prop.CanRead)
              {
                  if (typeof(IEnumerable).IsAssignableFrom(prop.PropertyType) && prop.PropertyType.IsGenericType)
                  {
                      IEnumerable list = (IEnumerable)prop.GetValue(obj);
                      if (list != null)
                      {
                          var i = 0;
                          foreach (var item in list)
                          {
                              if (item != null)
                              {
                                  prefix += string.Format("{0}[{1}].", HttpUtility.UrlEncode(prop.Name), i);
                                  BuildFormUrlEncodedDataString(item.GetType(), item, builder, prefix);
                                  i++;
                              }
                          }
                      }
                  }
                  else  if (prop.PropertyType.IsPrimitive || prop.PropertyType.Equals(typeof(String)))
                  {
                      var item = prop.GetValue(obj);
                      if (item != null)
                      {
                          builder.AppendFormat("{0}{1}{2}={3}",
                              builder.Length == 0 ? string.Empty : "&",
                              prefix,
                              prop.Name,
                              HttpUtility.UrlEncode(item.ToString())
                          );
                      }
                  }
                  else
                  {
                      var item = prop.GetValue(obj);
                      if (item != null)
                      {
                          prefix += string.Format("{0}.", HttpUtility.UrlEncode(prop.Name));
                          BuildFormUrlEncodedDataString(item.GetType(), item, builder, prefix);
                      }
                  }
              }
          }
      }
      

      你会像这样使用它:

      var builder = new StringBuilder();
      BuildFormUrlEncodedDataString(myObject.GetType(), myObject, builder)
      var queryString = builder.ToString();
      

      此时它更像是一种智力练习,因为您不再需要它,但它是一种有趣的消遣。也许它会对其他人派上用场。

      【讨论】:

      • 既然你遇到了这么多麻烦,如果我没有将其标记为答案,我会感到难过。干得好!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-13
      • 2016-06-05
      • 2013-06-21
      • 2017-05-26
      • 2017-10-12
      • 1970-01-01
      相关资源
      最近更新 更多