Angular HTTP请求无法正常工作

时间:2018-09-06 12:41:20

标签: angular asp.net-core

角使我发疯。

我有两个按钮。 如果我单击第一个,则要发出此请求:

https://localhost:44373/api/events

如果我单击第二个,则要发出该请求:

https://localhost:44373/api/events/1

将调用方法“ getNextPost()”,它似乎可以工作,但是在服务器端,不会调用已寻址的方法。

这是我的客户端实现:

 export class AppComponent implements OnInit {
  title = 'EventsPresenter';
  _hubconnection : signalR.HubConnection;

  _notification : string = '';

  displayedColumns: string[] = ['eventDateTime', 'nbr', 'element', 'parent', 'stateTypeTitle', 'enumValueTitle', 'customerObject'];

  ROOT_URL = 'https://localhost:44373/';
  ROOT_API_URL = this.ROOT_URL + 'api/';
  dataSource: Observable<EventData[]>;
  dataSource2: Observable<EventData>;

  constructor(private http: HttpClient) {}

  getPosts(){
    this.dataSource = this.http.get<EventData[]>(this.ROOT_API_URL + 'events')
  }

  getNextPost(){
    this.dataSource2 = this.http.get<EventData>(this.ROOT_API_URL + 'events/1')
  }


  ngOnInit() {

    this._hubconnection = new signalR.HubConnectionBuilder() 
    .configureLogging(signalR.LogLevel.Trace) 
    .withUrl('https://localhost:44373/notify') 
   .build(); 

    this._hubconnection
      .start()
      .then(() => console.log('Connection Started'))
      .catch(err => console.log('Error while establishing connection'));

      this._hubconnection.on('BroadcastMessage', (data: EventData) => {    
        console.log(data);
        this.dataSource.subscribe(v => v.push(data));
      });

  }
}

这是我的服务器实现:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using convisAPI.DataProvider;
using convisAPI.Interfaces;
using EntityLibrary;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;

namespace convisAPI.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class EventsController : ControllerBase
    {
        //EventDataProvider eventDataProvider;

        IEventDataRepository _eventDataRepository;

        IHubContext<NotifyHub> _hubContext;

        public EventsController(IEventDataRepository eventDataRepository, IHubContext<NotifyHub> hubContext)
        {
            _eventDataRepository = eventDataRepository;
            _hubContext = hubContext; 
        }

        // GET api/events
        [HttpGet]
        public async Task<ActionResult<IEnumerable<EventSummary>>> Get()
        {
            return await _eventDataRepository.GetEvents();
        }

        // GET api/values/5
        [HttpGet("{id}")]
        public async Task<ActionResult<EventSummary>> Get(int id)
        {

            Random r = new Random();

            var ra = r.Next(212, 220);

            await _hubContext.Clients.All.SendAsync("BroadcastMessage", new EventSummary()
            {
                Element = "Mein Element " + ra,
                Details = "Das ist mein Eventgrund",
                EventID = Guid.NewGuid(),
                ElementID = Guid.NewGuid(),
                EventDateTime = DateTime.Now,
                Nbr = ra,
                StateNbr = ra,
                EnumValueTitle = "Störung",
                StateEnumValue = 110 + ra
            });


            return new EventSummary();



        }

        // POST api/values
        [HttpPost]
        public void Post([FromBody] string value)
        {
        }

        // PUT api/values/5
        [HttpPut("{id}")]
        public void Put(int id, [FromBody] string value)
        {
        }

        // DELETE api/values/5
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
        }
    }
}

我知道代码“ Get(int id)”对您来说可能看起来很奇怪,但是我基本上想触发SignalR Notification。

有什么想法吗?

最好的问候

3 个答案:

答案 0 :(得分:3)

在Angular中,每个HTTP请求仅在有人收听时才会“触发”。

因此,如果没有人订阅,那么将不会有任何http请求。

getPosts(){
    this.http.get<EventData[]>(this.ROOT_API_URL + 'events')
         .subscribe(result => this.dataSource = result)
}

getNextPost(){
    this.http.get<`EventData>(this.ROOT_API_URL + 'events/1')
        .subscribe(result => this.dataSource2 = result)
}

我会写一些不同,但这就是个人风格 代替

getPosts(){
   this.dataSource = this.http.get<EventData[]>(this.ROOT_API_URL + 'events')
 }

我会写

getPosts():Observable<EventData[]>{
   return this.http.get<EventData[]>(this.ROOT_API_URL + 'events')
}

然后我将在需要数据的位置进行订阅。

...
this.getPosts().subscribe(result => this.isWhereINeedit = result)

热烈的问候

答案 1 :(得分:1)

这里有2个问题。

第一名: HttpClient.get()方法返回一个Observable。除非已订阅,否则Observable不会被触发/激发。 例如:

/* This wont work because it is not subscribed. */
someMethod() {
http.get(someUrl);
}

// this is work since it is subscribed.
someMethod() {
http.get(someUrl).subscribe(res => console.log(res));
}

因此,在您的情况下,不会调用服务器。检入浏览器的网络。如果已拨打电话,则应该在那里显示。

第二名: CORS发行。由于对服务器的请求和服务器的响应的来源不同,因此可能会出现问题。在开发阶段,您可以使用浏览器插件来解决该问题,但是在生产过程中(当您上线时)它仍然会发生。为了正确解决它,需要在服务器端进行一些更改。 将它们添加到您的服务器上:

  // Website you wish to allow to connect
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8888');

    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');

    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

    // Set to true if you need the website to include cookies in the requests sent
    // to the API (e.g. in case you use sessions)
    res.setHeader('Access-Control-Allow-Credentials', true);

答案 2 :(得分:0)

对于那些没有提到任何问题的降落者,值得检查拦截器,如果有的话。