无法将对象从AngularJS发送到WebApi

时间:2016-06-04 00:20:10

标签: angularjs asp.net-web-api cors

以下对我的问题的描述。

情况:

我的后端服务器正在WebApi.NET上运行。我已经实现了数据库模型和所有基本控制器,并且它们可以很好地处理GET请求(下载一些对象)。我显然在Web.config文件中添加了这样的条目,以允许CORS响应我在其他端口上运行的AngularJS应用程序:

<httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*"/>
      </customHeaders>
</httpProtocol>

但是我无法强制AngularJS正确地发送新对象(应该放在数据库中)。我也尝试在AngularJS请求中添加一些标题,但没有效果。

这是AngularJS应用程序的关键部分:

    self.newRespond = function ()
    {
        var newRespond = {
            'respondID': 3,
            'date': ((new Date().getTime()).toString()),
            'location': 'PL',
            'content': self.respContent,
            'author': globalService.nickname,
            'imgScr':'Resources/thumb.jpg',
            'refID': 1};

        $http.post("http://localhost:52095/api/responds", newRespond, {
            headers: {
                'Access-Control-Allow-Origin':'*',
                'Access-Control-Allow-Methods' : 'POST, GET, PUT, DELETE',
                'Access-Control-Allow-Headers' : 'Content-Type, Authorization, Content-Length, X-Requested-With',
                'Content-Type': 'application/x-www-form-urlencoded' }})
        .success(function (data)
        {
            console.log("New respond added!");
        })
        .error(function (data)
        {
            console.log("Error while sending respond.")
        });
    };

WebApi控制器的部分(这并不重要)

    // POST api/Responds
    [ResponseType(typeof(Respond))]
    public IHttpActionResult PostRespond(Respond respond)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        db.Responds.Add(respond);
        db.SaveChanges();

        return CreatedAtRoute("DefaultApi", new { id = respond.respondID }, respond);
    }

问题:

调用此object-send方法后,抛出异常:

issue_ss

由于错误似乎与OPTIONS标题有关,我添加了这个:

angularModule.config(['$httpProvider', function ($httpProvider)
{
    //Reset headers to avoid OPTIONS request
    $httpProvider.defaults.headers.common = {};
    $httpProvider.defaults.headers.post = {};
    $httpProvider.defaults.headers.put = {};
    $httpProvider.defaults.headers.patch = {};
}]);

可悲的是,仍然没有结果。

问题:

问题很简单 - 如何解决此问题并强制AngularJS将该死的对象发送到.NET服务器?

@Edited:

改变了Angular方法,正如Vu Quyet建议的那样。还有同样的例外:

$http.post("http://localhost:52095/api/responds", newRespond, {
                headers: {
                    'Access-Control-Allow-Origin':'*',
                    'Access-Control-Allow-Methods' : 'GET,POST',
                    'Access-Control-Allow-Headers' : 'Content-Type',
                    'Content-Type': 'application/x-www-form-urlencoded' }})
            .success(function (data)
            {
                console.log("New respond added!");
            })
            .error(function (data, error)
            {
                console.log("Error while sending respond. " + error)
            });

@ Edited2:

现在我将序列化对象发送到WebApi控制器时遇到了麻烦。使用'Content-Type'标题WebApi控制器恢复空白对象(所有字段等于null或0)。

$http.post("http://localhost:52095/api/responds", newRespond, {
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' }}) ...

如果没有此标题,控制器会回复415错误 - HTTP Error 415 Unsupported media type

 $http.post("http://localhost:52095/api/responds", newRespond) ...

2 个答案:

答案 0 :(得分:1)

这是麻烦。通过在标题中添加一些键来处理您的请求:

gcc -Wall my_program.c -o my_program

您已通过简单请求成为Preflighted_requests 提出请求。 要处理预先请求的请求,您需要在服务器中更改配置,以便在访问控制请求标头

的配置值的标题中允许新密钥
'Access-Control-Allow-Origin':'*',
'Access-Control-Allow-Methods' : 'POST, GET, PUT, DELETE',
'Access-Control-Allow-Headers' : 'Content-Type, Authorization, Content-Length, X-Requested-With'

但在您的情况下,我认为您只需删除请求中的一些冗余密钥,那么您的请求将成为一个简单的cors请求(Content-Type是简单请求的接受键)。您的服务器可以接收它。

Access-Control-Request-Headers: Content-Type, Authentication ...

如果您确实需要添加一些自定义密钥,例如TokenAuthentication,那么在Access-Control-Request-Headers中添加配置值

Read here了解有关预先广告请求的更多信息 和here表示简单请求的已接受密钥

答案 1 :(得分:0)

在花了几个小时寻找解决方案之后我最终找到了一个 - 希望它会帮助那些遇到同样问题的人。

如何使用CORS和Preflighted请求标头将AnuglarJS应用程序中的对象发送到WebApi控制器?

<强> 1。 AngularJS方法:

var postObject = new Object();
postObject.someProperty = "someValue";
postObject.otherProperty = 125.289;

$http.post("http://myServerAdress:1234/api/someRoute", postObject, {
        headers: { 'Content-Type': 'application/json' }})
    .success(function (data)
    {
        console.log("New object added!"); // do what you wish with response data
    })
    .error(function (data, error)
    {
        console.log("Error while sending an object. " + error)
    });

正如您所看到的,我正在发送带有'application / json'标头的基本JS对象。无需包装,序列化或解析。

<强> 2。 WebAPI .NET项目配置:

我需要通过NuGet包管理器安装以下包:

  • Microsoft ASP.NET跨源支持(5.2.3)
  • Microsoft ASP.NET Web API 2.2核心库(5.2.3)
  • Microsoft ASP.NET Web API 2.2 Web主机(5.2.3)

然后运行命令来更新配置文件中的依赖项:

Update-Package Microsoft.AspNet.WebApi -reinstall

第3。 WebAPI代码:

在最后一步中,我只是将这两行添加到'App_Start / WebApiConfig.cs'中:

EnableCorsAttribute atribbutes = new EnableCorsAttribute("*", "*", "*");
config.EnableCors(atribbutes);

显然,您可以限制传递CORS的起源,标题或方法。在这种情况下,所有人都被允许。

这就是全部。现在可以从项目中的所有控制器免费发布和接收对象。