1

我为迷宫游戏服务创建了 Web API 项目。它使用WebApi.Hal来返回hal+jsonhal+xml媒体类型。它在大多数情况下都有效——除了以下问题。

  1. 虽然 page 在请求中是 2,但它返回所有页面的所有单元格。如何纠正它?
  2. 在 hal+json 中,除了嵌入的单元格之外,还有指向自身中所有单元格的“链接”。在 hal+xml 中,只有嵌入的单元格。为什么有区别?哪个是对的?
  3. 有一个链接添加为rel="page" href="~/api/cells/page/{page}"。尽管我已经编写了以下代码,但为什么会rel以“页面”的形式出现

    `public static Link GetCells { get { return new Link("cell","~/api/cells/page/{page}"); } }

  4. searchTerm 添加了一个链接。如何在客户端使用它?我找不到任何有用的例子。
  5. 所有的细胞都是嵌入的。是正确的HAL 收藏方式吗?还是应该是链接?

请求:http://localhost:51910/api/cells/page/2

应用程序/hal+xml

<?xml version="1.0" encoding="utf-8"?>
<resource rel="" href="~/api/cells/page/2">
    <link rel="prev" href="~/api/cells/page/1" />
    <link rel="next" href="~/api/cells/page/3" />
    <link rel="page" href="~/api/cells/page/{page}" />
    <link rel="page" href="~/api/cells{?searchTerm,page}" />
    <TotalResults>6</TotalResults>
    <TotalPages>3</TotalPages>
    <Page>2</Page>
    <resource rel="self" href="~/api/cells/00">
        <link rel="left" href="~/api/cells/10" />
        <link rel="left" href="~/api/cells/01" />
        <CellID>00</CellID>
        <IsExit>False</IsExit>
    </resource>
    <resource rel="self" href="~/api/cells/10">
        <link rel="down" href="~/api/cells/00" />
        <link rel="down" href="~/api/cells/20" />
        <CellID>10</CellID>
        <IsExit>False</IsExit>
    </resource>
    <resource rel="self" href="~/api/cells/20">
        <link rel="left" href="~/api/cells/10" />
        <link rel="right" href="~/api/cells/21" />
        <CellID>20</CellID>
        <IsExit>False</IsExit>
    </resource>
    <resource rel="self" href="~/api/cells/01">
        <link rel="down" href="~/api/cells/00" />
        <link rel="left" href="~/api/cells/11" />
        <CellID>01</CellID>
        <IsExit>False</IsExit>
    </resource>
    <resource rel="self" href="~/api/cells/11">
        <link rel="left" href="~/api/cells/01" />
        <link rel="right" href="~/api/cells/21" />
        <CellID>11</CellID>
        <IsExit>False</IsExit>
    </resource>
    <resource rel="self" href="~/api/cells/21">
        <link rel="down" href="~/api/cells/20" />
        <link rel="left" href="~/api/cells/11" />
        <CellID>21</CellID>
        <IsExit>False</IsExit>
    </resource>
</resource>

应用程序/hal+json

在此处输入图像描述

控制器

public class CellsController : ApiController
    {

        //Get all cells in the maze
        [HttpGet]
        [Route("api/cells")] 
        public CellListRep Get()
        {
            Maze m = new Maze();
            int page = 1;
            int totalPages = 1;
            List<CellRepresentation> cellRepresentations = GetAllCellRepresentation(m);
            int totalCells = cellRepresentations.Count;
            return new CellListRep(cellRepresentations, totalCells, totalPages, page, LinkTemplates.CellLinks.GetCells);
        }

        //Get paged list
        [HttpGet]
        [Route("api/cells/page/{page}")] 
        public CellListRep Get(int page)
        {
            Maze m = new Maze();
            List<CellRepresentation> cellRepresentations = GetAllCellRepresentation(m);
            int totalCells = cellRepresentations.Count;
            int totalPages = cellRepresentations.Count / 2;
            return new CellListRep(cellRepresentations, totalCells, totalPages, page, LinkTemplates.CellLinks.GetCells);
        }

        //Get specific cell
        [HttpGet]
        [Route("api/cells/{id}")] 
        public CellRepresentation Get(string id)
        {
            Maze m = new Maze();
            Cell c = m.GetSpecificCell(id);
            List<Cell> possibleLists = m.GetPossibleRelatedCells(c);
            CellRepresentation beerRep = new CellRepresentation(c, possibleLists);
            return beerRep;
        }

        private List<CellRepresentation> GetAllCellRepresentation(Maze m)
        {
            List<CellRepresentation> cellRepresentations = new List<CellRepresentation>();
            List<Cell> cells = m.GetAllCells();

            foreach (Cell c in cells)
            {
                List<Cell> possibleLists = m.GetPossibleRelatedCells(c);
                CellRepresentation beerRep = new CellRepresentation(c, possibleLists);
                cellRepresentations.Add(beerRep);
            }

            return cellRepresentations;
        }
    }

表示和链接

public static class LinkTemplates
    {

        public static class CellLinks
        {
            public static Link CellEntry { get { return new Link("self", "~/api/cells/{id}"); } }

            public static Link UpLink { get { return new Link("up", "~/api/cells/{id}"); } }
            public static Link RightLink { get { return new Link("right", "~/api/cells/{id}"); } }
            public static Link DownLink { get { return new Link("down", "~/api/cells/{id}"); } }
            public static Link LeftLink { get { return new Link("left", "~/api/cells/{id}"); } }

            public static Link GetCells { get { return new Link("cell", "~/api/cells/page/{page}"); } }
            public static Link SearchCells { get { return new Link("page", "~/api/cells{?searchTerm,page}"); } }
        }
    }


  public class CellRepresentation : WebApi.Hal.Representation
        {
            Cell theCell;
            List<Cell> possibleMoveCells;


            public String CellID
            {
                get
                {
                    return theCell.CellID ;
                }
            }

            public bool IsExit
            {
                get
                {
                    return theCell.IsExtCell;
                }

            }

            public CellRepresentation(Cell c, List<Cell> possibleMoveCells )
            {
                theCell = c;
                //_cellIDVal = c.CellID;
                this.possibleMoveCells = possibleMoveCells;
            }

            public override string Rel
            {
                get { return LinkTemplates.CellLinks.CellEntry.Rel; }
                set { }
            }

            public override string Href
            {
                get { return LinkTemplates.CellLinks.CellEntry.CreateLink(new { id = theCell.CellID }).Href; }
                set { }
            }

            protected override void CreateHypermedia()
            {
                foreach (Cell relatedCell in possibleMoveCells)
                {
                    if (relatedCell.RelativeName == "Up")
                    {
                        Links.Add(LinkTemplates.CellLinks.UpLink.CreateLink(new { id = relatedCell.CellID }));
                    }
                    if (relatedCell.RelativeName == "Right")
                    {
                        Links.Add(LinkTemplates.CellLinks.RightLink.CreateLink(new { id = relatedCell.CellID }));
                    }
                    if (relatedCell.RelativeName == "Down")
                    {
                        Links.Add(LinkTemplates.CellLinks.DownLink.CreateLink(new { id = relatedCell.CellID }));
                    }
                    if (relatedCell.RelativeName == "Left")
                    {
                        Links.Add(LinkTemplates.CellLinks.LeftLink.CreateLink(new { id = relatedCell.CellID }));
                    }
                }
            }
        }

        public class CellListRep : PagedRepresentationList<CellRepresentation>
        {
            public CellListRep(IList<CellRepresentation> beers, int totalResults, int totalPages, int page, Link uriTemplate) :
                base(beers, totalResults, totalPages, page, uriTemplate, null)
            { }
            public CellListRep(IList<CellRepresentation> beers, int totalResults, int totalPages, int page, Link uriTemplate,
                object uriTemplateSubstitutionParams) :
                base(beers, totalResults, totalPages, page, uriTemplate, uriTemplateSubstitutionParams)
            { }

            protected override void CreateHypermedia()
            {
                base.CreateHypermedia();
                var search = LinkTemplates.CellLinks.SearchCells;
                if (Links.Count(l => l.Rel == search.Rel && l.Href == search.Href) == 0)
                {
                    Links.Add(LinkTemplates.CellLinks.SearchCells);
                }
            }
        }

        public abstract class PagedRepresentationList<TRepresentation> : SimpleListRepresentation<TRepresentation> where TRepresentation : Representation
        {
            readonly Link uriTemplate;

            protected PagedRepresentationList(IList<TRepresentation> res, int totalResults, int totalPages, int page, Link uriTemplate, object uriTemplateSubstitutionParams)
                : base(res)
            {
                this.uriTemplate = uriTemplate;
                TotalResults = totalResults;
                TotalPages = totalPages;
                Page = page;
                UriTemplateSubstitutionParams = uriTemplateSubstitutionParams;
            }

            public int TotalResults { get; set; }
            public int TotalPages { get; set; }
            public int Page { get; set; }

            protected object UriTemplateSubstitutionParams;

            protected override void CreateHypermedia()
            {
                var prms = new List<object> { new { page = Page } };
                if (UriTemplateSubstitutionParams != null)
                    prms.Add(UriTemplateSubstitutionParams);

                Href = Href ?? uriTemplate.CreateLink(prms.ToArray()).Href;

                Links.Add(new Link { Href = Href, Rel = "self" });

                if (Page > 1)
                {
                    var item = UriTemplateSubstitutionParams == null
                                    ? uriTemplate.CreateLink("prev", new { page = Page - 1 })
                                    : uriTemplate.CreateLink("prev", UriTemplateSubstitutionParams, new { page = Page - 1 }); // page overrides UriTemplateSubstitutionParams
                    Links.Add(item);
                }
                if (Page < TotalPages)
                {
                    var link = UriTemplateSubstitutionParams == null // kbr
                                   ? uriTemplate.CreateLink("next", new { page = Page + 1 })
                                   : uriTemplate.CreateLink("next", UriTemplateSubstitutionParams, new { page = Page + 1 }); // page overrides UriTemplateSubstitutionParams
                    Links.Add(link);
                }
                Links.Add(new Link("page", uriTemplate.Href));
            }
        }

商务舱

public class Cell
    {
        public int XVal { get; set; }
        public int YVal { get; set; }
        public bool TopIsWall { get; set; }
        public bool RightIsWall { get; set; }
        public bool BottomIsWall { get; set; }
        public bool LeftIsWall { get; set; }

        public bool IsStartCell { get; set; }
        public bool IsExtCell { get; set; }

        public string RelativeName { get; set; }  //Top, Right, Etc.

        public string CellID
        {
            get
            {
                string characterID = XVal.ToString() + YVal.ToString();
                return characterID; //Example 10
            }

         }  
    }

public class Maze
    {
        List<Cell> cells;
        public Maze()
        {
            cells = CreateCells();
        }


        public Cell GetFirtCell()
        {
            Cell firstCell = null;

            foreach (Cell c in cells)
            {
                if(c.IsStartCell )
                {
                    firstCell = c;
                    break;
                }
            }
            return firstCell;
        }

        public Cell GetSpecificCell(string cellID)
        {
            Cell theCell = null;

            foreach (Cell c in cells)
            {
                if (c.CellID == cellID)
                {
                    theCell = c;
                    break;
                }
            }
            return theCell;
        }

        public List<Cell> GetAllCells()
        {
            return cells;
        }

        public List<Cell> GetPossibleRelatedCells(Cell inputCell)
        {
            List<Cell> possibleCells = new List<Cell>();

            foreach (Cell c in cells)
            {
                if (c.YVal == 2 && c.XVal == 3)
                {
                    int test = 0;
                }

                if (c.XVal == inputCell.XVal-1 && c.RightIsWall == false  && c.YVal== inputCell.YVal  )
                {
                    //Go left from the input cell
                    c.RelativeName = "Left";
                    possibleCells.Add(c);

                }
                else if (c.XVal == inputCell.XVal + 1 && c.LeftIsWall == false && c.YVal == inputCell.YVal )
                {
                    //Go right from the input cell
                    c.RelativeName = "Right";
                    possibleCells.Add(c);
                }
                else if (c.YVal == inputCell.YVal - 1 && c.TopIsWall == false && c.XVal == inputCell.XVal )
                {
                    //Go down from the input cell
                    c.RelativeName = "Down";
                    possibleCells.Add(c);
                }
                else if (c.YVal == inputCell.YVal + 1 && c.BottomIsWall == false && c.XVal == inputCell.XVal)
                {
                    //Go up from the input cell
                    c.RelativeName = "Up";
                    possibleCells.Add(c);
                }

            }
            return possibleCells;
        }

        public List<Cell> CreateCells()
        {
            List<Cell> cells = new List<Cell>();

            Cell cell1 = new Cell
            {
                XVal = 0,YVal = 0,TopIsWall = false,RightIsWall = false,BottomIsWall = true,LeftIsWall = true,
                RelativeName="Self"
            };

            Cell cell2 = new Cell
            {
                XVal = 1,YVal = 0,TopIsWall = true,RightIsWall = false,BottomIsWall = false,LeftIsWall = false,
                IsStartCell = true, //--Start
                RelativeName="Self"
            };

            Cell cell3 = new Cell
            {
                XVal = 2,YVal = 0,TopIsWall = false,RightIsWall = false,BottomIsWall = true,LeftIsWall = false,
                RelativeName="Self"
            };


            Cell cell5 = new Cell
            {
                XVal = 0,YVal = 1,TopIsWall = true,RightIsWall = false,BottomIsWall = false,LeftIsWall = true,
                RelativeName = "Self"
            };

            Cell cell7 = new Cell
            {
                XVal = 1,YVal = 1,TopIsWall = true,RightIsWall = false,BottomIsWall = true,LeftIsWall = false,
                RelativeName = "Self"
            };


            Cell cell8 = new Cell
            {
                XVal = 2,YVal = 1,TopIsWall = false,RightIsWall = true,BottomIsWall = false,LeftIsWall = false,
                RelativeName = "Self"
            };


            cells.Add(cell1);
            cells.Add(cell2);
            cells.Add(cell3);
            cells.Add(cell5);
            cells.Add(cell7);
            cells.Add(cell8);

            return cells;

        }

    }

4

0 回答 0