Ionic 4-如何通过Web API将应用程序连接到现有SQL Server?
已经提出了许多类似的问题,但是对于此版本的Ionic框架,没有一个问题,也没有一个问题可以对我有实际帮助.
背景:
我制作了一个应用程序,需要从现有的SQL Server中获取数据.从研究来看,唯一可行的方法是使用Web API作为中间件,因为Ionic无法直接连接到SQL Server.
I have made an app and need to fetch data from an existing SQL Server. From research the only way this can be done is to use a Web API as a middleware seeing as Ionic cannot directly connect to SQL Server.
请参阅本教程,因为这是我一直关注的内容: https://www.youtube.com/watch?v=Js_8ijftKC0&index=21&list=PLaU76WfrROI6LO_YqTDd8ADul3xQoao5L&t=0s
Please refer to this tutorial as this is what I have been following: https://www.youtube.com/watch?v=Js_8ijftKC0&index=21&list=PLaU76WfrROI6LO_YqTDd8ADul3xQoao5L&t=0s
我在哪里如此遥远:
- 我已经完成了本教程的离子"部分,添加了服务和所有CRUD操作等.
- 我已经在Visual Studio的ASP.NET Web MVC中创建了Web API.
- 该API已连接到我的SQL数据库并启用CRUD操作.
问题:
多次阅读本教程后,没有任何提示. Ionic中的任何CRUD方法都不会返回任何东西.无需根据请求更新或检索数据库中的任何内容.
After following this tutorial multiple times, not missing a hint. None of the CRUD methods in Ionic return anything. Nothing is updated or retrieved from the database on request.
- 缺少的教程是什么?甚至准确吗?
感谢您的帮助,谢谢.
sql.service.ts
import { Injectable } from '@angular/core';
import { Http, Headers, RequestMethod, RequestOptions } from '@angular/http';
import { map } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class SqlService {
url:string="http://localhost:50287/api/APIDemo/"
constructor(private http: Http) { }
getAll(){
return this.http.get(this.url).pipe(map(res=>res.json()));
}
Create(name) {
var body={"name":name};
var header=new Headers({'Content-Type':'application/json'})
var option=new RequestOptions({method:RequestMethod.Post,headers:header})
return this.http.post(this.url + "Posttest",body,option).pipe(map(res=>res.json()))
}
Update(id, name) {
var body={"id":id,"name":name};
var header=new Headers({'Content-Type':'application/json'})
var option=new RequestOptions({method:RequestMethod.Post,headers:header})
return this.http.post(this.url,body,option).pipe(map(res=>res.json()))
}
Read(id) {
return this.http.get(this.url+id).pipe(map(res=>res.json()))
}
Delete(id) {
return this.http.delete(this.url+id).pipe(map(res=>res.json()))
}
}
sql.page.ts
import { Component, OnInit } from '@angular/core';
import { SqlService } from '../../services/sql.service'
@Component({
selector: 'app-sql',
templateUrl: './sql.page.html',
styleUrls: ['./sql.page.scss'],
})
export class SqlPage implements OnInit {
items=[];
id: string;
name: string;
constructor(public sql: SqlService) {
this.getAll()
}
ngOnInit() {
}
getAll() {
this.items=[];
this.sql.getAll().subscribe(data=>{
for(var i=0;i<data.length;i++){
this.items.push(data[i]);
}
})
}
Add() {
if(this.id==null){
this.sql.Create(this.name).subscribe(data=>{
this.name="";
this.getAll();
})
}else {
this.sql.Update(this.id, this.name).subscribe(data=>{
this.id=null
this.name=""
this.getAll()
})
}
}
Edit(item) {
this.id = item.id
this.name = item.name
}
Delete(item) {
this.sql.Delete(item.id).subscribe(data=>{
this.getAll()
})
}
}
sql.page.html
<ion-header>
<ion-toolbar>
<ion-title>sql</ion-title>
</ion-toolbar>
</ion-header>
<ion-content padding>
<ion-item>
<ion-label>Name</ion-label>
<ion-input type="text" [(ngModel)]="id" hidden></ion-input>
<ion-input type="text" [(ngModel)]="name"></ion-input>
</ion-item>
<ion-button (click)="Add()">Add</ion-button>
<ion-list>
<ul>
<li *ngFor="let items of items">
{{ item.name }}
<ion-button (click)="Edit(item)">Edit</ion-button>
<ion-button (click)="Delete(item)">Delete</ion-button>
</li>
</ul>
</ion-list>
</ion-content>
app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { RouteReuseStrategy } from '@angular/router';
import { IonicModule, IonicRouteStrategy } from '@ionic/angular';
import { SplashScreen } from '@ionic-native/splash-screen/ngx';
import { StatusBar } from '@ionic-native/status-bar/ngx';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { HttpClientModule } from '@angular/common/http';
import { EmailComposer } from '@ionic-native/email-composer/ngx';
import { EmailPageModule } from './pages/email/email.module';
import { MapsPageModule } from './pages/maps/maps.module';
import { CallNumber } from '@ionic-native/call-number/ngx';
import { HttpModule } from '@angular/http'
import { SqlService } from './services/sql.service'
@NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule, HttpClientModule, EmailPageModule, MapsPageModule, HttpModule],
providers: [
StatusBar,
SplashScreen,
EmailComposer,
CallNumber,
SqlService,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
],
bootstrap: [AppComponent]
})
export class AppModule {}
DemoAPI(C#)
WebApiConfig.cs
WebApiConfig.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
using System.Web.Http.Cors;
namespace DemoAPI
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.EnableCors(new EnableCorsAttribute(origins: "http://localhost:8100", headers: "*", methods: "*"));
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
}
APIDemoController.cs
APIDemoController.cs
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Description;
using DemoAPI.Models;
namespace DemoAPI.Controllers
{
public class APIDemoController : ApiController
{
private demoEntities db = new demoEntities();
// GET: api/APIDemo
public IQueryable<test> Gettests()
{
return db.tests;
}
// GET: api/APIDemo/5
[ResponseType(typeof(test))]
public IHttpActionResult Gettest(int id)
{
test test = db.tests.Find(id);
if (test == null)
{
return NotFound();
}
return Ok(test);
}
// PUT: api/APIDemo/5
[ResponseType(typeof(void))]
public IHttpActionResult Puttest(int id, test test)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
if (id != test.id)
{
return BadRequest();
}
db.Entry(test).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
if (!testExists(id))
{
return NotFound();
}
else
{
throw;
}
}
return StatusCode(HttpStatusCode.NoContent);
}
// POST: api/APIDemo
[HttpPost]
[ResponseType(typeof(test))]
public HttpResponseMessage Posttest(test test)
{
if (test.id == 0)
{
if (!ModelState.IsValid)
{
db.tests.Add(test);
db.SaveChanges();
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, test);
response.Headers.Location = new Uri(Url.Link("DefaultAPI", new { id = test.id }));
return response;
}
else
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
}
else
{
if (ModelState.IsValid)
{
db.Entry(test).State = EntityState.Modified;
try
{
db.SaveChanges();
}
catch (DbUpdateConcurrencyException)
{
return Request.CreateResponse(HttpStatusCode.NotFound);
}
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.Created, test);
response.Headers.Location = new Uri(Url.Link("DefaultAPI", new { id = test.id }));
return response;
}
else
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
}
}
// DELETE: api/APIDemo/5
[ResponseType(typeof(test))]
public IHttpActionResult Deletetest(int id)
{
test test = db.tests.Find(id);
if (test == null)
{
return NotFound();
}
db.tests.Remove(test);
db.SaveChanges();
return Ok(test);
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
private bool testExists(int id)
{
return db.tests.Count(e => e.id == id) > 0;
}
}
}
我将尝试简化原始答案.让我们接受一个HTTP GET
请求.
I will try and simplify the original answer. Lets take a HTTP GET
request.
在您的服务中,您拥有:
In your service you have:
getAll(){
return this.http.get(this.url).pipe(map(res=>res.json()));
}
在Web API中,您有一个控制器,您将在其中定义一些操作.您的HTTP请求被映射到以下路由,如下所示:
In the web API you have a controller where you will define some actions. Your HTTP request gets mapped to the following route like so:
routeTemplate: "api/{controller}/{id}"
Routing is how Web API matches a URI to an action
因此,在WebAPI中,您将创建以下操作:
So in the WebAPI you would create an action like:
// GET: api/APIDemo/getall
[HttpGet]
[ResponseType(typeof(test))]
public IHttpActionResult GetAll(int id)
{
test test = db.tests.Find(id);
if (test == null)
{
return NotFound();
}
return Ok(test);
}
您的样品请求可以像这样:
You a sample request can be like so:
localhost:8080/api/apidemo/getall?id=1
您还需要发出正确的HTTP请求,这里我们正在检索所有测试, [HttpGet]属性定义一个GET.
You also need to make a correct HTTP request, here we are retrieving a all tests, The [HttpGet] attribute defines a GET.
您应该在路由.
好的,因此您需要创建一个与Web API中的方法签名匹配的对象,因此对于您的创建"示例.
okay so you need to create an object which matches what the method signature in the web API, so for your "Create" example.
Create(name) {
// use JSON.Stringigy to get an JSON string
var body=JSON.stringify({id: 1, name:name});
var header=new Headers({'Content-Type':'application/json'})
var option=new RequestOptions({method:RequestMethod.Post,headers:header})
return this.http.post(this.url + "Posttest",body,option).pipe(map(res=>res.json()))
}