-->

之后的参数总是空之后的参数总是空(Post parameter is always null)

2019-05-17 15:16发布

由于升级到RC为的WebAPI我的WebAPI调用POST当我有一些真正奇怪的问题。 我甚至已经回到上新项目所产生的基本版本。 所以:

public void Post(string value)
{
}

从提琴手呼吁:

Header:
User-Agent: Fiddler
Host: localhost:60725
Content-Type: application/json
Content-Length: 29

Body:
{
    "value": "test"
}

当我调试,字符串“值”是永远不会被分配到。 这只是总是NULL。 任何人有这个问题?

(我第一次看到一个更复杂类型的问题)

这个问题不仅是必然ASP.NET MVC 4,对于RC安装后,一个新的ASP.NET MVC 3项目会出现同样的问题

Answer 1:

因为你只有一个参数,你可以尝试用它装饰[FromBody]属性,或更改接受DTO与价值特性的方法,我这里建议: MVC4 RC的WebAPI参数绑定

UPDATE:官方ASP.NET站点今天更新具有优异的解释: https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/sending-html-form-data-part- 1

概括地说,发送在体内单个简单类型时,给刚以等号(=),例如体前缀的值:

=test



Answer 2:

我一直在抓我的头今天这个结束。

我的解决方案是改变[FromBody]HttpRequestMessage ,基本上向上移动HTTP栈。

在我的情况下,我穿过这是压缩JSON,然后base64'd线发送数据。 这所有的Android应用程序。

我的网络端点的原始签名看起来像这样(使用[FromBody]

我对这个问题的修复是为了恢复使用HttpRequestMessage我的端点的签名。

然后,您可以访问使用此行代码后的数据:

这工作,并允许您访问原始不变后的数据。 你不必与小提琴手把一个等号(=)在您的字符串的开头或改变内容类型陷入混乱。

顺便说一句,我首先尝试以下的答案中的一个以上,其是改变内容类型:“内容类型:应用程序/ x WWW的形式进行了urlencoded”。 对于原始数据,这是不好的建议,因为它剔除了+字符。

所以,一个base64字符串开头是这样的:“MQ0AAB + LCAAAAAA”结束了这样的“MQ0AAB LCAAAAAA”! 不是你想要的。

使用的另一个好处HttpRequestMessage是您从端点中获得所有的HTTP标头。



Answer 3:

我刚刚发生这种情况使用招。 问题是,我没有指定Content-Type

尝试包括一个头Content-Type在POST请求。

Content-Type: application/x-www-form-urlencoded

另外,按照下面的评论,你可能需要包括一个JSON头

Content-Type: application/json


Answer 4:

我碰到这个问题为好,这是我如何解决我的问题

的WebAPI代码:

public void Post([FromBody] dynamic data)
{
    string value = data.value;
    /* do stuff */
}

客户代码:

$.post( "webapi/address", { value: "some value" } );


Answer 5:

我用的是Postman ,我在做同样的错误..传递value作为JSON对象,而不是字符串

{
    "value": "test"
}

显然当API参数是字符串类型的上述一个是错误的

所以,仅仅通过在API体双引号的字符串:

"test"


Answer 6:

尝试创建一个类来作为数据模型,然后发送一个JSON对象相匹配的数据模型类的属性属性。 (注:我已经测试了这一点,它与最新的MVC 4 RC 2012,我今天刚刚下载的作品)。

public HttpResponseMessage Post(ValueModel model)
{
    return Request.CreateResponse<string>(HttpStatusCode.OK, "Value Recieved: " + model.Value);
}

public class ValueModel
{
    public string Value { get; set; }
}

下面JSON对象在HTTP-POST体送出,内容类型是application / JSON

{ "value": "In MVC4 Beta you could map to simple types like string, but testing with RC 2012 I have only been able to map to DataModels and only JSON (application/json) and url-encoded (application/x-www-form-urlencoded body formats have worked. XML is not working for some reason" }

我相信,你为什么要创建一个数据模型类的原因是因为简单的值被认为是从URL参数,和一个复杂的数值被认为是从身体。 他们确实有[FromBody][FromUrl]属性,但使用[FromBody] string value仍然没有为我工作。 好像他们仍在制定了很多的错误,所以我敢肯定,这将在未来发生改变。

编辑:GOT XML在体内工作。 默认XML序列化改为DataContractSerializer的,而不是XmlSerializer的。 把我的Global.asax文件中的以下行修复了这个问题( 参考 )

GlobalConfiguration.Configuration.Formatters.XmlFormatter.UseXmlSerializer = true;


Answer 7:

一些尝试后,我觉得默认的行为是正确的,并没有什么破解。

唯一的技巧就是:如果您的帖子方法参数string如下图所示,你应该发送一个普通字符串与身体中的双引号 (用ajax或邮递员时),例如,

//send "{\"a\":1}" in body to me, note the outer double quotes
[HttpPost("api1")]
public String PostMethod1([FromBody]string value)
{
    return "received " + value; //  "received {\"a\":1}"
}

否则,如果你在帖子正文中发送一个JSON字符串,不外双引号和逃脱内报价,那么它应该可以被解析到模型类(参数类型),例如, {"a":1, "b":2}

public class MyPoco{
    public int a;
    public int b;
}

//send {"a":1, "b":2} in body to me
[HttpPost("api2")]
public String PostMethod2([FromBody]MyPoco value)
{
    return "received " + value.ToString();  //"received your_namespace+MyPoco"
}


Answer 8:

我一直在寻找一个解决这个问题了几分钟了,所以我将分享我的解决方案。

如果您发布模型模型需要有一个空/默认构造函数,否则不能创建的模型,效果显着。 要同时重构小心。 ;)



Answer 9:

我有同样的问题,并发现改变内容类型时,“应用/ JSON”,没有解决问题。 然而 “应用程序/ JSON;字符集= UTF-8” 的工作。



Answer 10:

这为我工作:

  1. 创建一个C#类DTO,具有每个属性要从jQuery的/ Ajax的传递特性

     public class EntityData { public string Attr1 { get; set; } public string Attr2 { get; set; } } 
  2. 定义Web API方法:

     [HttpPost()] public JObject AddNewEntity([FromBody] EntityData entityData) { 
  3. 调用web API这样:

     var entityData = { "attr1": "value1", "attr2": "value2" }; $.ajax({ type: "POST", url: "/api/YOURCONTROLLER/addnewentity", async: true, cache: false, data: JSON.stringify(entityData), contentType: "application/json; charset=utf-8", dataType: "json", success: function (response) { ... } }); 


Answer 11:

对于那些谁是有像我一样用扬鞭同样的问题或邮差 ,如果你是在后经过简单的属性字符串,甚至用“的ContentType”规定,你还是会得到一个空值。

只是传递:

myvalue的

将让你在控制器为空。

但是,如果你通过:

“myvalue的”

该值将得到正确的。

引号在这里所作的区别。 当然,这只是针对扬鞭和邮差。 例如,在采用了棱角分明一个前端应用程序这应该是由全自动的框架解决。



Answer 12:

我也有类似的问题,即我们的Web API方法请求对象总是空。 我注意到,因为控制器动作名称与前缀“GET”,网页API处理这个作为HTTP GET而不是POST。 重命名控制器动作后,现在按预期工作。



Answer 13:

在我的情况的问题是,该参数是一个字符串,而不是一个对象,我改变了参数是Newsoft.Json的JObject和它的作品。



Answer 14:

添加行

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

到函数的末尾protected void Application_Start()在Global.asax.cs中的ASP.NET MVC3固定类似的问题对我来说。



Answer 15:

具有角,我能够在这个格式的数据传递:

 data: '=' + JSON.stringify({ u: $scope.usrname1, p: $scope.pwd1 }),
 headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8' }

而在网页API的Controler:

    [HttpPost]
    public Hashtable Post([FromBody]string jsonString)
    {
        IDictionary<string, string> data = JsonConvert.DeserializeObject<IDictionary<string, string>>(jsonString);
        string username = data["u"];
        string pwd = data["p"];
   ......

另外,我还可以发布这样的JSON数据:

    data: { PaintingId: 1, Title: "Animal show", Price: 10.50 } 

而且,在控制器,接受类类型是这样的:

    [HttpPost]
    public string POST(Models.PostModel pm)
    {

     ....
    }

无论哪种方式工作,如果你在API中有一个既定的公共类,然后张贴JSON,否则后“=” + JSON.stringify({.. ... .. ...})



Answer 16:

如果你正在使用你的XML格式化或JSON格式化一个DataContractSerializer的 ,你需要摆脱它。 我在WebApiConfig文件中有这样的:

public static void Register(HttpConfiguration config)
{
     config.Routes.MapHttpRoute(
           name: "DefaultApi",
           routeTemplate: "api/{controller}/{id}",
           defaults: new { id = RouteParameter.Optional }
     );    

     var jsonFormatter = config.Formatters.OfType<JsonMediaTypeFormatter>().First();
     jsonFormatter.UseDataContractJsonSerializer = true;
}

只要我注释掉jsonFormatter.UseDataContractJsonSerializer = true; 和我的输入参数不为空了。 由于“神电”给我一个线索。



Answer 17:

如果你确信你发送JSON,那么你必须仔细跟踪您的API:

  1. 安装Microsoft.AspNet.WebApi.Tracing
  2. 加入config.EnableSystemDiagnosticsTracing();WebApiConfig内部类Register方法。

现在看调试输出,你可能会发现一个无效ModelState日志条目。

如果ModelState是无效的,你可能会发现它的真正原因Errors

甚至没有人能猜到这样的例外:

Could not load file or assembly 'Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)


Answer 18:

我知道这是不是一个回答这个问题,但对于一个解决我的问题搜索时我碰到它。

在我的情况下,复杂类型没有被束缚,但我没有做一个帖子,我是做与查询字符串参数的GET。 解决的办法是添加[FromUri]将ARG:

public class MyController : ApiController
{
    public IEnumerable<MyModel> Get([FromUri] MyComplexType input)
    {
        // input is not null as long as [FromUri] is present in the method arg
    }
}


Answer 19:

我在提琴手有同样的问题。 我已经有Content-Type: application/json; charset=utf-8 Content-Type: application/json; charset=utf-8Content-Type: application/json在请求报头。

我请求主体也是一个普通字符串,并在提琴手我写: {'controller':'ctrl'} 这改变了我的POST方法的字符串参数为null

修复 :记得用引号,由此表明一个字符串。 也就是说,我写固定它"{'controller':'ctrl'}" 。 (注:写JSON的时候,或者是一定要使用单引号或逃避这样引号: "{\"controller\":\"ctrl\"}" )。



Answer 20:

最简单的方法,我发现对付我进入MVC 6个简单的JSON对象获得这个职位的参数一样NewtonSoft jObject的类型:

public ActionResult Test2([FromBody] jObject str)
{
        return Json(new { message = "Test1 Returned: "+ str }); ;
}


Answer 21:

对我来说,最好的解决办法是如下准备完整的HTTP:

[Route("api/open")]
[HttpPost]
public async Task<string> open(HttpRequestMessage request)
{
    var json = await request.Content.ReadAsStringAsync();
    JavaScriptSerializer jss = new JavaScriptSerializer();            
    WS_OpenSession param = jss.Deserialize<WS_OpenSession>(json);
    return param.sessionid;
}

然后反序列化字符串您在帖子正文期待的对象。 对我来说,WS_OpenSession是包含会话ID,用户和关键的一类。

你可以从那里用参数对象并访问其属性。

非常非常有效的。

我是说从这个网址来源:

http://bizcoder.com/posting-raw-json-to-web-api



Answer 22:

对于复杂类型,网络API尝试读取从消息主体的值,使用介质型格式化。

请检查您是否有任何[Serializable]属性装饰你的模型类。

删除属性,看看它是否工作。 这为我工作。



Answer 23:

我有点迟到了,但任何人使用控制器只需添加“=”你的POST请求的前跨时传递空值谁绊倒。

该控制器还通过NULL值时,我使用的应用/ JSON内容类型。 请注意 “应用程序/ x-WWW的形式,进行了urlencoded” 的内容类型。 但是从API返回的类型是“应用/ JSON”。

 public static string HttpPostRequest(string url, Dictionary<string, string> postParameters)
    {
        string postData = "=";

        foreach (string key in postParameters.Keys)
        {
            postData += HttpUtility.UrlEncode(key) + "="
                  + HttpUtility.UrlEncode(postParameters[key]) + ",";
        }

        HttpWebRequest myHttpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
        myHttpWebRequest.Method = "POST";

        byte[] data = System.Text.Encoding.ASCII.GetBytes(postData);

        myHttpWebRequest.ContentType = "application/x-www-form-urlencoded";
        myHttpWebRequest.ContentLength = data.Length;

        Stream requestStream = myHttpWebRequest.GetRequestStream();
        requestStream.Write(data, 0, data.Length);
        requestStream.Close();

        HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();

        Stream responseStream = myHttpWebResponse.GetResponseStream();

        StreamReader myStreamReader = new StreamReader(responseStream, System.Text.Encoding.Default);

        string pageContent = myStreamReader.ReadToEnd();

        myStreamReader.Close();
        responseStream.Close();

        myHttpWebResponse.Close();

        return pageContent;
    }


Answer 24:

不要紧什么类型的,你想张贴价值,只是将其括在引号内,把它作为字符串。 不为复杂类型。

JavaScript的:

    var myData = null, url = 'api/' + 'Named/' + 'NamedMethod';

    myData = 7;

    $http.post(url, "'" + myData + "'")
         .then(function (response) { console.log(response.data); });

    myData = "some sentence";

    $http.post(url, "'" + myData + "'")
         .then(function (response) { console.log(response.data); });

    myData = { name: 'person name', age: 21 };

    $http.post(url, "'" + JSON.stringify(myData) + "'")
         .then(function (response) { console.log(response.data); });

    $http.post(url, "'" + angular.toJson(myData) + "'")
         .then(function (response) { console.log(response.data); });

C#:

    public class NamedController : ApiController
    {
        [HttpPost]
        public int NamedMethod([FromBody] string value)
        {
            return value == null ? 1 : 0;
        }
    }


Answer 25:

我越来越null作为参数的同样的问题,但它涉及到大对象。 原来,这个问题是关系到IIS最大长度。 它可以在web.config中进行配置。

  <system.web>
    <httpRuntime targetFramework="4.7" maxRequestLength="1073741824" />
  </system.web>

我不知道为什么网页API抑制错误和空对象发送到我的API。 我发现错误使用Microsoft.AspNet.WebApi.Tracing。



Answer 26:

我非常晚了这一点,但在遇到类似问题,并通过大量的答案会在这里并获得背景的前一天,我已经找到了最简单/轻量级的解决方案,以一个或多个参数传回给Web API 2动作是为如下:

这是假设你知道如何安装与正确的路由一个Web API控制器/动作,如果不是指: https://docs.microsoft.com/en-us/aspnet/web-api/overview/getting-started-with -aspnet-Web的API /教程你先网上API 。

首先,控制器动作,该解决方案还需要Newtonsoft.Json库。

[HttpPost]
public string PostProcessData([FromBody]string parameters) {
    if (!String.IsNullOrEmpty(parameters)) {
        JObject json = JObject.Parse(parameters);

        // Code logic below
        // Can access params via json["paramName"].ToString();
    }
    return "";
}

使用jQuery客户端

var dataToSend = JSON.stringify({ param1: "value1", param2: "value2"...});
$.post('/Web_API_URI', { '': dataToSend }).done(function (data) {
     console.debug(data); // returned data from Web API
 });

我发现关键问题是要确保你只发送一个总体参数返回给Web API,并确保它没有名字只是值{ '': dataToSend }否则你的价值将在服务器端空。

有了这个,你可以在一个JSON结构送一个或多个参数到Web API,你不需要声明任何额外的对象服务器端来处理复杂的数据。 该JObject还允许你动态迭代中用户可以方便的可扩展性如果您的参数随时间而改变传递的所有参数。 希望这有助于有人指出,挣扎和我一样。



Answer 27:

在身体的WebAPI正确传递单个参数的工作原理是代码$.post(url, { '': productId }

而在动作捕捉它[HttpPost] public ShoppingCartAddRemoveViewModel Delete([FromBody]string value)

关键是使用魔法字“值”。 其也可以被INT,或某些原始类型。 无论内容类型或标题更正混乱的是,这个代码不MVC后行动工作。



Answer 28:

问题是,你的动作方法需要一个简单的类型,即,一个字符串参数值。 你所提供的对象。

有2个解决您的问题。

  1. 创建“ ”属性的简单类,然后使用这个类作为参数,在这种情况下的Web API模型绑定将请求读取JSON对象,并将其绑定到你的参数对象“值”属性。

  2. 只是通过字符串值“ 测试 ”,它会工作。



Answer 29:

如果你把[FromBody]注释,你有一个DTO对象作为参数传递给你的方法,仍然无法得到通过数据,开始寻找到的属性和你的DTO的领域。

我有同样的问题,在我的DTO来了空。 我发现原因是其中一个属性是指向这将导致媒体格式化失败解析数据不能被序列化对象 :(。因此,目标是始终为空。希望它可以帮助别人太



Answer 30:

API:

[HttpPost]
public bool UpdateTicketStatus(Ticket t)
{    
    string Id=t.Id;
}

模型:

public class Ticket
{
    public int Id { get; set; }
    public string AssignedTo { get; set; }
    public string State { get; set; }
    public string History { get; set; }
}

使用后的人的工具发送的内容与下面的原始数据JSON。 有用

{ “ID”: “169248”, “AssignedTo”: “XXXX”, “国家”: “承诺”, “历史”: “测试1”}

请确保您已启用一个Cors。

[EnableCors(origins: "*", headers: "*", methods: "*")]
    public class TicketController : ApiController
    {
}


文章来源: Post parameter is always null