Post方法不适用于WebAPI 2和Angular 4

时间:2017-09-26 14:11:08

标签: angular asp.net-web-api

我正在尝试学习Angular4并实现在ASP WebAPI中开发的post方法并获取Angular4应用程序。

[Route("api/[controller]")]
[EnableCors(origins: "*", headers: "*", methods: "*")]
public class APIController : ApiController
{
    [HttpPost]
    [Route("api/savePerson")]
    public IHttpActionResult savePerson(PersonModel model)
    {
        try
        {
            if (model.name != string.Empty || model.weight != 0 || model.height != 0 || model.proffession != 0)
            {
                Guid guid = Guid.NewGuid();
                Random random = new Random();
                int i = random.Next();
                model.id = i;
                return Ok(model);
            }
            else
            {
                return BadRequest();
            }
        }
        catch (Exception ex)
        {
            return InternalServerError("Something Went Wrong : " + ex.ToString());
        }
    }
}

我已经从nuget包添加了System.Web.Cors。 在我的Angular类中,我试图发布这样的值: Services.ts

addPerson(person : Person){
    let headers = new Headers({ 'Content-Type': 'application/json' });
    let options = new RequestOptions({ headers: headers });
    return this.http.post(this.Base_URL + 'savePerson', person, options)
      .map(res=><Person>res.json()).catch(this.handleError);
  }

当我尝试从Postman测试API时,它的工作正常。但是,当我尝试从我的Angular应用程序中调用它时,我收到的错误是这样的:

  

选项http://sampleapi.ubiquitousdevelopers.com/api/savePerson 405   (不允许的方法)无法加载   http://sampleapi.ubiquitousdevelopers.com/api/savePerson:回复   预检具有无效的HTTP状态代码405

enter image description here

它只是一个示例API,所以我没有隐藏我的基本URL。任何人都可以测试此API。 我的Get方法在此URL上正常工作: http://sampleapi.ubiquitousdevelopers.com/api/getAllperson

POSTMAN工作截图: enter image description here

我的Web.Config文件

  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <remove name="OPTIONSVerbHandler" />
  <remove name="TRACEVerbHandler" />
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>

3 个答案:

答案 0 :(得分:2)

这可能与CORS(交叉原始请求)有关。

执行CORS和OPTIONS请求时会先触发。

在执行CORS时,您需要更改web.config中的一些内容。

以下是我的web.config中的示例。我将此配置用于开发

<system.webServer>
<defaultDocument enabled="false" />
<directoryBrowse enabled="false" />

<!-- https://github.com/aspnet/Docs/tree/master/aspnetcore/fundamentals/servers -->
<!-- https://docs.microsoft.com/en-us/aspnet/core/hosting/aspnet-core-module -->
<handlers>
  <remove name="OPTIONSVerbHandler" />
  <remove name="TRACEVerbHandler" />
  <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/>
  <!--<add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="ProtocolSupportModule" requireAccess="None" responseBufferLimit="4194304" />-->

</handlers>
</system.webServer>

在此片段中,我首先删除OPTIONS和TRACE处理程序,然后使用该行打开所有http动词到所有路径:

另请注意,我这样做是一个ASP.NET核心项目。

对于ASP.NET MVC 5:

  <system.webServer>
<defaultDocument enabled="false" />
<directoryBrowse enabled="false" />
<handlers>
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <remove name="OPTIONSVerbHandler" />
  <remove name="TRACEVerbHandler" />
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
  <!--<add name="OPTIONSVerbHandler" path="*" verb="OPTIONS" modules="ProtocolSupportModule" requireAccess="None" responseBufferLimit="4194304" />-->
</handlers>
</system.webServer>

其他可能性是允许这样的CORS标题:

<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Headers" value="Content-Type, Accept, X-Requested-With"/>
<add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS"/>
<add name="Access-Control-Allow-Origin" value="*"/>

     

答案 1 :(得分:1)

要启用CORS,您还需要在HttpConfiguration上致电EnableCors。请参阅herehere

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // New code
        config.EnableCors();

        ...

仅仅使用EnableCors属性是不够的。

答案 2 :(得分:0)

我得到405(方法不允许),这显然是CORS问题,所以我需要启用CORS。

首先,我需要通过

在WebAPIConfig.cs中启用CORS
public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // New code
        config.EnableCors();

        ...

另外,仅在WebAPIConfig.cs中启用CORS是不够的。如果我运行代码,我得到同样的错误。所以我需要通过以下方式装饰我的控制器:

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

现在当我运行代码时出现以下错误:

  

'Access-Control-Allow-Origin'标头包含多个值'*,   *',但只允许一个。因此,不允许原点“http://localhost:3000”访问。

通过搜索stackoverflow,我知道我的EnableCors头与我的Web.Config CORS头冲突。

所以我从Web.Config中删除了自定义标题

 <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Headers" value="Content-Type, Accept, X-Requested-With"/>
        <add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS"/>
        <add name="Access-Control-Allow-Origin" value="*"/>
      </customHeaders>
    </httpProtocol>

另外,VRPF,我没有在默认处理程序中进行任何更改并保持原样:

<handlers>
  <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
  <remove name="OPTIONSVerbHandler" />
  <remove name="TRACEVerbHandler" />
  <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>

现在我测试,一切正常。我认为这对任何新的Angular开发人员在学习目的时都会有所帮助。

最后,经过3周的搜索,Kirk Larkin和VRPF的帮助解决了这个问题。干杯:D