Http Post没有执行到ASP.NET,但是GET请求没有

时间:2016-08-29 22:23:00

标签: javascript c# http angular asp.net-core

我试图在Angular2中发布帖子请求。出于某种原因,我无法发出POST请求。我将客户端和服务器都更改为GET请求,并将其他所有内容保持不变,并且工作正常。所以我想知道我是否可以以不同的方式配置标头以便能够发出POST请求。
更新
所以我设法让它执行,但现在location参数显示为null

客户端

search(latitude: any, longitude: any){
        let headers = new Headers(); 
        headers.append('Content-Type', 'application/json'); 
        let body = JSON.stringify({ latitude, longitude });
        this.http.post('/api/SampleData/CurrentForecasts',body, { headers: headers })
        .map(response => response.json())
        .subscribe(
            data =>  this.Debug(data),
            err =>  console.log("Error: \n"+err),
            () => console.log('Get Complete')
        ); 
}

服务器

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using System.Net.Http;
using System.Net.Http.Headers;

namespace Weather.Controllers
{
    [Route("api/[controller]")]
    public class SampleDataController : Controller
    {
        private static string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };
        [HttpPost("[action]")]
        public async Task<IActionResult> CurrentForecasts(string location)
        {
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri(" https://api.forecast.io/");
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                // HTTP GET
                HttpResponseMessage response = await client.GetAsync("forecast/APIKEY/"+location);
                if (response.IsSuccessStatusCode)
                {
                    var forecast = await response.Content.ReadAsStringAsync();
                    return Content(forecast, "application/json");
                }
            }
            return Json(null); 
        }
        [HttpGet("[action]")]
        public async Task<IActionResult> SendRequest()
        {
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri(" https://api.forecast.io/");
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                // HTTP GET
                HttpResponseMessage response = await client.GetAsync("forecast/APIKEY/37.8267,-122.423");
                if (response.IsSuccessStatusCode)
                {
                    var forecast = await response.Content.ReadAsStringAsync();
                    return Content(forecast, "application/json");
                }
            }
            return Json(null); 
        }
    }
}

错误 location [null]

4 个答案:

答案 0 :(得分:1)

import {Http, Response, Headers, RequestOptions, URLSearchParams} from 'angular2/http';


let headers = new Headers({ 'Content-Type': 'application/json' });
let options = new RequestOptions({
   headers: headers,           
   search: new URLSearchParams('location='+body)
});
this.http.post('/api/SampleData/CurrentForecasts', null, options)

修改 最好在服务器中创建class

public class Location
{
    public double Latitude { get; set; }
    public double Longitude { get; set; }
}

并将您的方法签名更改为:

public async Task<IActionResult> CurrentForecasts(Location location)

从Angular2发布数据:

let location = { Latitude: latitude, Longitude: longitude }
let headers = new Headers({ 'Content-Type': 'application/json' });
let body = JSON.stringify(location);
this.http.post('/api/SampleData/CurrentForecasts', body, headers)

答案 1 :(得分:0)

注意:以下代码是AngularJS的解决方案。对于Angular2,请查看this

var param = {location: body}
var configObj = { headers: headers, params: param };
this.http.post('/api/SampleData/CurrentForecasts', null, configObj )

答案 2 :(得分:0)

HttpGet不应处理您的帖子请求。您可能需要在Web API控制器上定义RouteAttribute

[HttpPost]
[Route("api/SampleData")]
public async Task<IActionResult> CurrentForecasts(string location)
{
    using (var client = new HttpClient())
    {
        client.BaseAddress = new Uri(" https://api.forecast.io/");
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        // HTTP GET
        HttpResponseMessage response = await client.GetAsync("forecast/APIKEY/"+location);
        if (response.IsSuccessStatusCode)
        {
            var forecast = await response.Content.ReadAsStringAsync();
            return Content(forecast, "application/json");
        }
    }
    return Json("Failed");

此外,在您的客户端,您可以说:

    let headers = new Headers(); 
    headers.append('Content-Type', 'application/json')
    let body = latitude+','+longitude ; 

    this.http.post('/api/SampleData/',body, { headers: headers })
    .map(response => response.json())
    .subscribe(
        data =>  this.Debug(data),
        err =>  console.log("Error: \n"+err),
        () => console.log('Get Complete')
    ); 

返回Json(null)Json("Failed")之类的内容可能会导致上述错误。可能如果您尝试将响应包装到某个具有布尔值Success属性的对象中,以便在尝试读取某些data属性之前可以先查询它。如果您创建模型或视图模型,如:

public class ResponseModel
{
    public IList<SomeModel> Data {get; set;}
    public bool Success { get; set; }
    public string ErrorMessage { get; set; }
}

然后围绕上述模型创建您的回复。您可能需要/需要详细说明上述模型。

答案 3 :(得分:0)

.Net中的默认路由是将映射操作转换为类似的方法名称(按惯例编码)。如果没有直接匹配,默认的GET操作将找到第一个可用的方法。

由于您的控制器名为&#34; SampleData&#34;,您将需要...

A)以类似的方式重命名您的方法,例如&#34; GetSampleData&#34;,&#34; PostSampleData&#34;等

B)为HttpPost和Action添加数据注释,以便路由器知道如何映射,例如

[HttpPost]
[ActionName("CurrentForecasts")]
public async Task<IActionResult> CurrentForecasts(string location)
{
   ...your code here
}

只需更新您的正文,以便表单字段匹配,您就应该设置。