Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在ASP.NET MVC中,在controller';s作用法_C#_Jquery_Asp.net Mvc_Json - Fatal编程技术网

C# 在ASP.NET MVC中,在controller';s作用法

C# 在ASP.NET MVC中,在controller';s作用法,c#,jquery,asp.net-mvc,json,C#,Jquery,Asp.net Mvc,Json,我正在一个网站上工作,该网站将发布一个JSON对象(使用jQuery post方法)到服务器端 { "ID" : 1, "FullName" : { "FirstName" : "John", "LastName" : "Smith" } } 同时,我在服务器端为这个数据结构编写了类 public class User { public int ID { get; set; } public Name FullName {

我正在一个网站上工作,该网站将发布一个JSON对象(使用jQuery post方法)到服务器端

{ 
    "ID" : 1,
    "FullName" : {
       "FirstName" : "John",
       "LastName" : "Smith"
    }
}
同时,我在服务器端为这个数据结构编写了类

public class User
{
    public int ID { get; set; }
    public Name FullName { get; set;}
}

public class Name
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
当我在控制器类中使用以下代码运行网站时,FullName属性不会被反序列化。我做错了什么

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Submit(User user)
{
    // At this point, user.FullName is NULL. 

    return View();
}
你可以试试。这是相当好的,它应该能够。当它返回可在ASP.NET MVC应用程序中使用的ActionResult时,您还需要抓取。它很容易使用

Json.NET还可以很好地处理日期序列化。更多关于这方面的信息


希望这有帮助。

1.创建自定义模型活页夹

  public class UserModelBinder : IModelBinder
  {
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
      User model;

      if(controllerContext.RequestContext.HttpContext.Request.AcceptTypes.Contains("application/json"))
      {
        var serializer = new JavaScriptSerializer();
        var form = controllerContext.RequestContext.HttpContext.Request.Form.ToString();
        model = serializer.Deserialize<User>(HttpUtility.UrlDecode(form));
      }
      else
      {
        model = (User)ModelBinders.Binders.DefaultBinder.BindModel(controllerContext, bindingContext);
      }

      return model;
    }
  }
3.使用jQuery$.get/$.post查看客户端JavaScript代码

  <% using(Html.BeginForm("JsonData","Home",new{},FormMethod.Post, new{id="jsonform"})) { %>

    <% = Html.TextArea("jsonarea","",new {id="jsonarea"}) %><br />

    <input type="button" id="getjson" value="Get Json" />
    <input type="button" id="postjson" value="Post Json" />
  <% } %>
  <script type="text/javascript">
    $(function() {
      $('#getjson').click(function() {
        $.get($('#jsonform').attr('action'), function(data) {
          $('#jsonarea').val(data);
        });
      });

      $('#postjson').click(function() {
        $.post($('#jsonform').attr('action'), $('#jsonarea').val(), function(data) {
          alert("posted!");
        },"json");
      });
    });
  </script>


$(函数(){ $('#getjson')。单击(函数(){ $.get($('#jsonform').attr('action'),函数(数据){ $('jsonarea').val(数据); }); }); $('#postjson')。单击(函数(){ $.post($('jsonform').attr('action'),$('jsonarea').val(),函数(数据){ 警报(“已发布!”); }“json”); }); });
试试这个

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Submit(FormCollection collection)
{
    User submittedUser = JsonConvert.DeserializeObject<User>(collection["user"]); 
    return View();
}
[AcceptVerbs(HttpVerbs.Post)]
公共行动结果提交(FormCollection集合)
{
User submittedUser=JsonConvert.DeserializeObject(集合[“用户]);
返回视图();
}

我通过实现操作过滤器解决了问题;下面提供了代码示例。从研究中,我了解到还有另一种解决方案,如上文所述的模型绑定器。但我真的不知道这两种方法的利弊

感谢Steve Gentile的解决方案

public class JsonFilter : ActionFilterAttribute
    {
        public string Parameter { get; set; }
        public Type JsonDataType { get; set; }

        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            if (filterContext.HttpContext.Request.ContentType.Contains("application/json"))
            {
                string inputContent;
                using (var sr = new StreamReader(filterContext.HttpContext.Request.InputStream))
                {
                    inputContent = sr.ReadToEnd();
                }

                var result = JsonConvert.DeserializeObject(inputContent, JsonDataType);
                filterContext.ActionParameters[Parameter] = result;
            }
        }
    }

[AcceptVerbs(HttpVerbs.Post)]
[JsonFilter(Parameter="user", JsonDataType=typeof(User))]
public ActionResult Submit(User user)
{
    // user object is deserialized properly prior to execution of Submit() function

    return View();
}

经过一些研究,我发现Takepara的解决方案是用Newtonsoft的JSON.NET替换默认MVC JSON反序列化程序的最佳选择。它还可以推广到程序集中的所有类型,如下所示:

using Newtonsoft.Json;

namespace MySite.Web
{
    public class MyModelBinder : IModelBinder
    {
        // make a new Json serializer
        protected static JsonSerializer jsonSerializer = null;

        static MyModelBinder()
        {
            JsonSerializerSettings settings = new JsonSerializerSettings();
            // Set custom serialization settings.
            settings.DateTimeZoneHandling= DateTimeZoneHandling.Utc;
            jsonSerializer = JsonSerializer.Create(settings);
        }

        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            object model;

            if (bindingContext.ModelType.Assembly == "MyDtoAssembly")
            {
                var s = controllerContext.RequestContext.HttpContext.Request.InputStream;
                s.Seek(0, SeekOrigin.Begin);
                using (var sw = new StreamReader(s))
                {
                    model = jsonSerializer.Deserialize(sw, bindingContext.ModelType);
                }
            }
            else
            {
                model = ModelBinders.Binders.DefaultBinder.BindModel(controllerContext, bindingContext);
            }
            return model;
        }
    }
}
然后,在
Global.asax.cs
中,
应用程序启动()


MVC不支持即时的JSON反序列化,但我们正在考虑为v2添加它。同时,您可以使用JavaScriptSerializer将请求主体转换为完全水合的用户对象。@Levi-这应该是一篇回答文章;)这很奇怪;不知何故,ID属性被正确反序列化。如果我使用JavaScriptSerializer,Submit()的输入参数会是Object类型吗?我只使用jQuery表单库,它只是像普通表单一样发布它。如果你不能做到这一点,我会使用定制的模型活页夹。awww snap,拥有133t MVC技能的weilin,你最好在周一教我;)与自定义ModelBinder相比,此方法有一个显著的优点,即您可以定义要反序列化的类型。使用自定义ModelBinder,它是硬编码的,因此只对一种类型有用。您的意思可能是“ContentType”而不是“AcceptTypes”
using Newtonsoft.Json;

namespace MySite.Web
{
    public class MyModelBinder : IModelBinder
    {
        // make a new Json serializer
        protected static JsonSerializer jsonSerializer = null;

        static MyModelBinder()
        {
            JsonSerializerSettings settings = new JsonSerializerSettings();
            // Set custom serialization settings.
            settings.DateTimeZoneHandling= DateTimeZoneHandling.Utc;
            jsonSerializer = JsonSerializer.Create(settings);
        }

        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
        {
            object model;

            if (bindingContext.ModelType.Assembly == "MyDtoAssembly")
            {
                var s = controllerContext.RequestContext.HttpContext.Request.InputStream;
                s.Seek(0, SeekOrigin.Begin);
                using (var sw = new StreamReader(s))
                {
                    model = jsonSerializer.Deserialize(sw, bindingContext.ModelType);
                }
            }
            else
            {
                model = ModelBinders.Binders.DefaultBinder.BindModel(controllerContext, bindingContext);
            }
            return model;
        }
    }
}
        var asmDto = typeof(SomeDto).Assembly;
        foreach (var t in asmDto.GetTypes())
        {
            ModelBinders.Binders[t] = new MyModelBinder();
        }