如何在 HAL 中获取链接资源的关联名称

How to get associated name of linked resources in HAL

我正在为项目任务创建 API。它有一个如下所列的 TasksController。我正在使用 WebApi.Hal 生成超媒体,该服务还支持 hal+jsonhal+xml media types

以下是我目前对 GET 请求 http://localhost:51910/api/tasks/1 的响应。在响应中有一个优先级链接列表——但它们在响应中没有关联的名称(在 UI 中显示——如 LowMediumHigh, 等等).

使用 WebApi.HAL 获取优先级名称的最佳 HAL 方法是什么?

注意:优先级列表可以在未来得到增强。

优先级

public class Priority
{
    public int PriorityID { get; set; }
    public string PriorityName { get; set; }
    public string Revision { get; set; }
    public DateTime ApprovalDate { get; set; }
}

控制器

public class TasksController : ApiController
    {
        // GET api/values/5
         [HttpGet]
        public TaskRepresentation Get(int id)
        {

            Task selectedTask = TasksHelper.GetTask(id);
            TaskRepresentation taskRepresentation = new TaskRepresentation(selectedTask);
            return taskRepresentation;
        }

        //PUT For Setting Priority
        [HttpPut]
        [Route("api/tasks/{taskID}/priorities/{priorityID}")]
        public TaskRepresentation PutSetPriority(int taskID, int priorityID)
        {
            Task selectedTask = TasksHelper.GetTask(taskID);

            Priority selectedPriority = null;
            List<Priority> allPriorities = TasksPrioritiesHelper.GetAllPriorities();
            foreach (Priority p in allPriorities)
            {
                if (p.PriorityID == priorityID)
                {
                    selectedPriority = p;
                }
            }

            //Update Task
            if (selectedPriority != null)
            {
                selectedTask.CurrentPriority = selectedPriority.PriorityName;
            }
            else
            {

                throw new Exception("Not available");
            }


            TaskRepresentation taskRepresentation = new TaskRepresentation(selectedTask);
            return taskRepresentation;
        }

        [HttpGet]
        [Route("api/tasks/{taskID}/priorities/{priorityID}")]
        public Priority Get(int taskID, int priorityID)
        {
            Priority selectedPriority = null;
            List<Priority> allPriorities = TasksPrioritiesHelper.GetAllPriorities();
            foreach (Priority p in allPriorities)
            {
                if (p.PriorityID == priorityID)
                {
                    selectedPriority = p;
                }
            }

            return selectedPriority;
        }

    }

HAL生成相关类

public static class LinkTemplates
    {

        public static class TaskLinks
        {
            public static Link TaskEntry { get { return new Link("self", "~/api/tasks/{taskID}"); } }
            public static Link PriorityLink { get { return new Link("priorities", "~/api/tasks/{taskID}/priorities/{priorityID}"); } }
        }
    }

public class TaskRepresentation : Representation
    {
        Task theTask;

        public int TaskID{get{return theTask.TaskID;}}
        public string TaskName{get{return theTask.Name;}}
        public string CurrentPriority{get{return theTask.CurrentPriority;}}
        public string Category{get{return theTask.Category;}}

        public TaskRepresentation(Task t)
        {
            theTask = t;
        }


        public override string Rel
        {
            get { return LinkTemplates.TaskLinks.TaskEntry.Rel; }
            set { }
        }

        public override string Href
        {
            get { return LinkTemplates.TaskLinks.TaskEntry.CreateLink(new { taskID = theTask.TaskID }).Href; }
            set { }
        }


        protected override void CreateHypermedia()
        {
            foreach (Priority p in theTask.PossiblePriorities)
            {
                Links.Add(LinkTemplates.TaskLinks.PriorityLink.CreateLink(new { taskID = theTask.TaskID, priorityID = p.PriorityID }));
            }
        }
    }

HAL 规范提到 title - 这将满足要求。

以下是更新后的回复。

{
  "TaskID": 1,
  "TaskName": "Task1",
  "CurrentPriority": "Medium",
  "Category": "IT",
  "_links": {
    "self": {
      "href": "/api/tasks/1"
    },
    "priorities": [
      {
        "href": "/api/tasks/1/priorities/101",
        "title": "Low"
      },
      {
        "href": "/api/tasks/1/priorities/103",
        "title": "High"
      },
      {
        "href": "/api/tasks/1/priorities/104",
        "title": "Critical"
      }
    ]
  }
}

WebAPI.HAL 变化

protected override void CreateHypermedia()
        {
            foreach (Priority p in theTask.PossiblePriorities)
            {
                Link lnk = LinkTemplates.TaskLinks.PriorityLink.CreateLink(new { taskID = theTask.TaskID, priorityID = p.PriorityID });
                lnk.Title = p.PriorityName;
                Links.Add(lnk);
            }
        }

代码

public static class LinkTemplates
    {

        public static class TaskLinks
        {
            public static Link TaskEntry { get { return new Link("self", "~/api/tasks/{taskID}"); } }
            //public static Link PriorityLink { get { return new Link("priorities", "~/api/tasks/{taskID}/priorities/{priorityID}"); } }
            public static Link PriorityLink 
            { 
                get 
                {
                    Link l = new Link("priorities", "~/api/tasks/{taskID}/priorities/{priorityID}");
                    return l;
                } 
            }
        }
    }


    public class TasksController : ApiController
    {
        // GET api/values/5
         [HttpGet]
        public TaskRepresentation Get(int id)
        {

            Task selectedTask = TasksHelper.GetTask(id);
            TaskRepresentation taskRepresentation = new TaskRepresentation(selectedTask);
            return taskRepresentation;
        }

        //PUT For Setting Priority
        [HttpPut]
        [Route("api/tasks/{taskID}/priorities/{priorityID}")]
        public TaskRepresentation PutSetPriority(int taskID, int priorityID)
        {
            Task selectedTask = TasksHelper.GetTask(taskID);

            Priority selectedPriority = null;
            List<Priority> allPriorities = TasksPrioritiesHelper.GetAllPriorities();
            foreach (Priority p in allPriorities)
            {
                if (p.PriorityID == priorityID)
                {
                    selectedPriority = p;
                }
            }

            //Update Task
            if (selectedPriority != null)
            {
                selectedTask.CurrentPriority = selectedPriority.PriorityName;
            }
            else
            {

                throw new Exception("Not available");
            }


            TaskRepresentation taskRepresentation = new TaskRepresentation(selectedTask);
            return taskRepresentation;
        }

        [HttpGet]
        [Route("api/tasks/{taskID}/priorities/{priorityID}")]
        public Priority Get(int taskID, int priorityID)
        {
            Priority selectedPriority = null;
            List<Priority> allPriorities = TasksPrioritiesHelper.GetAllPriorities();
            foreach (Priority p in allPriorities)
            {
                if (p.PriorityID == priorityID)
                {
                    selectedPriority = p;
                }
            }

            return selectedPriority;
        }

    }

    public class TaskRepresentation : Representation
    {
        Task theTask;

        public int TaskID{get{return theTask.TaskID;}}
        public string TaskName{get{return theTask.Name;}}
        public string CurrentPriority{get{return theTask.CurrentPriority;}}
        public string Category{get{return theTask.Category;}}

        public TaskRepresentation(Task t)
        {
            theTask = t;
        }


        public override string Rel
        {
            get { return LinkTemplates.TaskLinks.TaskEntry.Rel; }
            set { }
        }

        public override string Href
        {
            get { return LinkTemplates.TaskLinks.TaskEntry.CreateLink(new { taskID = theTask.TaskID }).Href; }
            set { }
        }


        protected override void CreateHypermedia()
        {
            foreach (Priority p in theTask.PossiblePriorities)
            {
                Link lnk = LinkTemplates.TaskLinks.PriorityLink.CreateLink(new { taskID = theTask.TaskID, priorityID = p.PriorityID });
                lnk.Title = p.PriorityName;
                Links.Add(lnk);
            }
        }
    }

    public class Task
    {
        public string Name { get; set; }
        public int TaskID { get; set; }
        public string Category { get; set; }
        public string CurrentPriority  { get; set; }
        public List<Priority> PossiblePriorities { get; set; }
    }
    public class Priority
    {
        public int PriorityID { get; set; }
        public string PriorityName { get; set; }
        public string Revision { get; set; }
        public DateTime ApprovalDate { get; set; }
    }

    public static class TasksPrioritiesHelper
    {

        public static List<Priority> GetAllPriorities()
        {
            List<Priority> possiblePriorities = new List<Priority>();
            Priority pLow = new Priority { PriorityID = 101, PriorityName = "Low" };
            Priority pMedium = new Priority { PriorityID = 102, PriorityName = "Medium" };
            Priority pHigh = new Priority { PriorityID = 103, PriorityName = "High" };
            Priority pCritical = new Priority { PriorityID = 104, PriorityName = "Critical" };

            possiblePriorities.Add(pLow);
            possiblePriorities.Add(pMedium);
            possiblePriorities.Add(pHigh);
            possiblePriorities.Add(pCritical);

            return possiblePriorities;
        }

        public static List<Priority> GetAdministrativePriorities()
        {
            List<Priority> possiblePriorities = new List<Priority>();
            Priority pLow = new Priority { PriorityID = 101, PriorityName = "Low" };
            Priority pHigh = new Priority { PriorityID = 103, PriorityName = "High" };

            possiblePriorities.Add(pLow);
            possiblePriorities.Add(pHigh);

            return possiblePriorities;
        }


        public static List<Priority> GetPossiblePrioritiesForTask(Task t)
        {
            List<Priority> possibleTaskPriorities = new List<Priority>();


            if (String.Equals(t.Category, "IT"))
            {
                possibleTaskPriorities = GetAllPriorities();
            }
            else
            {
                possibleTaskPriorities = GetAdministrativePriorities();
            }

            Priority currentTaskPriority = null;
            foreach(Priority p in possibleTaskPriorities )
            {
                if(String.Equals(t.CurrentPriority,p.PriorityName ))
                {
                    currentTaskPriority=p;
                }
            }

            if(currentTaskPriority!=null)
            {
                possibleTaskPriorities.Remove(currentTaskPriority);
            }


            return possibleTaskPriorities;
        }


    }
    public static class TasksHelper
    {
        public static Task GetTask(int id)
        {
            Task selectedTask = null;
            List<Task> tasks = GetAllTasks();

            foreach (Task t in tasks)
            { 
                if(t.TaskID==id)
                {
                    selectedTask = t;
                }
            }
            return selectedTask;
        }


        public static List<Task> GetAllTasks()
        {

            List<Task> tasks;
            tasks = new List<Task>();

            Task t1 = new Task{Category = "IT",CurrentPriority = "Medium",Name = "Task1",TaskID = 1};
            t1.PossiblePriorities = TasksPrioritiesHelper.GetPossiblePrioritiesForTask(t1);

            tasks.Add(t1);

            return tasks;
        }


    }