我正在尝试使用NodeJS和typescript建立一个简单的Hello World REST服务。我想将路由器分成不同的文件,但不知怎的,它还没有解决。
简单地说,对于http://localhost:3000/welcome/hi
的GET调用,为什么项目1 有效,但项目2 不行?我试图寻找教程,但代码似乎没有按我希望的方式工作。
项目1
import express from "express";
import { Router, Request, Response } from "express";
const app: express.Application = express();
const port: any = process.env.PORT || 3000;
const router: Router = Router();
const welcomeRouter: Router = Router();
welcomeRouter.get("/", (req: Request, res: Response) => {
res.send({"message": "Welcome!"});
});
welcomeRouter.get("/:name", (req: Request, res: Response) => {
let { name } = req.params;
res.send(`Hello, ${name}!`);
});
router.get("/", (req: Request, res: Response) => {
res.send({"message":"Hello, World!"});
});
app.use("/", router);
app.use("/welcome", welcomeRouter);
app.listen(port, () => {
console.log(`Listening at http://localhost:${port}/`);
});
项目2
./ app.ts
import { Router, Request, Response } from "express";
const router: Router = Router();
router.get("/", (req: Request, res: Response) => {
res.send({"message": "Welcome!"});
});
router.get("/:name", (req: Request, res: Response) => {
let { name } = req.params;
res.send(`Hello, ${name}!`);
});
export default router;
./ server.ts
import express from "express";
import { Router, Request, Response } from "express";
import welcomeRouter from "./app";
const app: express.Application = express();
const port: any = process.env.PORT || 3000;
const router: Router = Router();
app.use("/welcome", welcomeRouter);
router.get("/", (req: Request, res: Response) => {
res.send({"message":"Hello, World!"});
});
app.use("/", router);
app.use("/welcome", welcomeRouter);
app.listen(port, () => {
console.log(`Listening at http://localhost:${port}/`);
});
答案 0 :(得分:0)
你" mount"的顺序或public class ExampleController : Controller
{
[ChildActionOnly]
private MyContainer InitialiseContainer()
{
MyContainer containter = new MyContainer();
containter.Header = new MyHeader(1, "Header Name");
containter.Details.Add(new MyDetail(1, 1, "Detail 1 Name", 100));
containter.Details.Add(new MyDetail(1, 2, "Detail 2 Name", 200));
return containter;
}
[HttpGet]
public ActionResult Host()
{
//ViewBag.xxSelectedItem = "Detail Name 4";
Session["isAjaxCall"] = false;
MyContainer container = InitialiseContainer();
ViewBag.Names = NamesLookup(null);
return View(container);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Host(MyContainer container, string actionPerformed)
{
if (actionPerformed == "Save All")
{
//return RedirectToAction("xxx");
}
if (actionPerformed == "Reload Detail")
{
if ((bool)Session["isAjaxCall"] == true)
{
ViewBag.DetailIndex = 0;
ViewBag.Names = NamesLookup(null);
NewModelContainer = (MyContainer)Session["MyContainer"];
return PartialView("Detail", NewModelContainer);
}
else
{
//this action runs if , from the ajax code we reference the Div(s) set by the parent view "Details"
container = setsomeValues(container);
ViewBag.DetailIndex = 0;
ViewBag.Names = NamesLookup(null);
return View(container);
}
}
ViewBag.Names = NamesLookup(null);
return View(container);
}
`public PartialViewResult GetAjaxPostBackData_OnlyTextBox(string ajaxDetailModelData, string index)
{
Session["isAjaxCall"] = true;
int i = 0;
int.TryParse(index, out i);
ViewBag.DetailIndex = i;
//get the items to populate the dropdown List with
ViewBag.Names = NamesLookup(null);
//get an instance of the Model (Container), either from session (with changed and persisted values in it, or Cleanly re-initialized)
MyContainer NewModelContainer = InitialiseContainer();
NewModelContainer = UnpackAjaxdetailModelData(ajaxDetailModelData,index);
//arb Test ..change the HTML Input
NewModelContainer.Details[i].SomeNumber = 777;
Session["NewModelContainer"] = NewModelContainer;
//return just the partial view as indexed, which's btnXXX_index was clicked
return PartialView("Detail", NewModelContainer);
}
[ChildActionOnly]
private SelectList NamesLookup(object selectedObject)
{
List<MyName> names = new List<MyName>();
names.Add(new MyName(1, "Detail Name 1"));
names.Add(new MyName(2, "Detail Name 2"));
names.Add(new MyName(3, "Detail Name 3"));
names.Add(new MyName(4, "Detail Name 4"));
names.Add(new MyName(5, "Detail Name 5"));
return new SelectList(names, "Name", "Name", selectedObject);
}
}
每个路由器都很重要。此外,为了与您安装它们的顺序一致,路径也很重要。将它们视为stack。
所以对于第一个你有:
app.use
- &gt; /welcome
welcomeRouter
- &gt; /
因此当您执行router
时,GET http://localhost:3000/welcome/hi
将处理请求,因为它是堆栈中第一个与路径welcomeRouter
匹配的请求。
只做/welcome
会产生GET http://localhost:3000/welcome
,对吗?然后最后做{"message": "Welcome!"}
收益:GET http://localhost:3000/welcome/hi
。
对于第二个你有:
Hello hi
- &gt; /
(我猜这个路由器指的是你在router
中定义的路由器)app.ts
- &gt; /welcome
在welcomeRouter
导出app.ts
对象的位置,您的路由定义为router
。
这将处理任何事情:/:name
。这意味着它还将处理/*
,其中/welcome
成为welcome
参数。
将name
移到welcomeRouter
之上应使其像项目1一样工作。