public void AddQuery(String rel, RequestDataBuilder queryString) { if (rel == HalSelfActionLinkAttribute.SelfRelName) { AddPageQuery(rel, queryString, Offset, Limit); } }
private void AddPageQuery(String rel, RequestDataBuilder queryString, int?offset, int?limit) { if (offset.HasValue && limit.HasValue) { queryString.AppendItem("offset", offset); queryString.AppendItem("limit", limit); } AddCustomQuery(rel, queryString); }
public virtual IEnumerable <HalLinkAttribute> CreateHalLinks(ILinkProviderContext context) { var typeInfo = this.GetType().GetTypeInfo(); foreach (var attr in typeInfo.GetCustomAttributes()) { //Grab the self link as the reference for page links var pageLinkAttr = attr as HalSelfActionLinkAttribute; if (pageLinkAttr != null) { //Next link if ((Offset + 1) * Limit < Total) { var builder = new RequestDataBuilder(); AddPageQuery(Rels.Next, builder, Offset + 1, Limit); var next = pageLinkAttr.Href; yield return(new HalLinkAttribute(Rels.Next, next, null, pageLinkAttr.Method, pageLinkAttr.DataMode, requestData: builder.Data)); } //Previous link if (Offset - 1 > -1) { var builder = new RequestDataBuilder(); AddPageQuery(Rels.Previous, builder, Offset - 1, Limit); var prev = pageLinkAttr.Href; yield return(new HalLinkAttribute(Rels.Previous, prev, null, pageLinkAttr.Method, pageLinkAttr.DataMode, requestData: builder.Data)); } //First link var firstBuilder = new RequestDataBuilder(); AddPageQuery(Rels.First, firstBuilder, 0, Limit); var first = pageLinkAttr.Href; yield return(new HalLinkAttribute(Rels.First, first, null, pageLinkAttr.Method, pageLinkAttr.DataMode, requestData: firstBuilder.Data)); //Last link if (Limit != 0) { var lastIndex = Total / Limit; //If there is no remainder this is an even multiple, do not start the last page on the even multiple, but one before it var remainder = Total % Limit; if (remainder == 0 && lastIndex > 0) { --lastIndex; } var builder = new RequestDataBuilder(); AddPageQuery(Rels.Last, builder, lastIndex, Limit); var last = pageLinkAttr.Href; yield return(new HalLinkAttribute(Rels.Last, last, null, pageLinkAttr.Method, pageLinkAttr.DataMode, requestData: builder.Data)); } } } }
/// <summary> /// This function can be overwritten to add any additional custom query strings needed /// to the query url. The base class version just returns url, so there is no need to /// call it from your subclass. /// </summary> /// <param name="rel">The input rel.</param> /// <param name="queryString">The query builder.</param> /// <returns>The customized query string.</returns> protected override void AddCustomQuery(String rel, RequestDataBuilder queryString) { //Get all properties except offset and limit foreach (var prop in typeof(TQuery).GetTypeInfo().GetProperties().Where(i => i.Name != nameof(IPagedCollectionQuery.Offset) && i.Name != nameof(IPagedCollectionQuery.Limit))) { var value = prop.GetValue(this.query); if (value != null) { var name = camelNaming.GetPropertyName(prop.Name, false); var collection = value as System.Collections.ICollection; if (collection != null) { foreach (var item in collection) { queryString.AppendItem(name, item?.ToString()); } } else { queryString.AppendItem(name, value.ToString()); } } } }
/// <summary> /// This will add all the properties from the query class to the query for this collection. /// </summary> /// <param name="rel"></param> /// <param name="queryString"></param> public virtual void AddQuery(string rel, RequestDataBuilder queryString) { //Get all properties except offset and limit foreach (var prop in typeof(TQuery).GetTypeInfo().GetProperties()) { var value = prop.GetValue(this.query); if (value != null) { var name = camelNaming.GetPropertyName(prop.Name, false); var collection = value as System.Collections.ICollection; if (collection != null) { foreach (var item in collection) { queryString.AppendItem(name, item?.ToString()); } } else { queryString.AppendItem(name, value.ToString()); } } } }
/// <summary> /// Get the links that the current user is allowed to use. /// </summary> /// <param name="model">The model class to scan.</param> /// <param name="context">The curren httpcontext.</param> /// <param name="endpointInfo">The info for this endpoint.</param> /// <returns></returns> public static IEnumerable <Link> GetUserLinks(object model, HttpContext context, IHalDocEndpointInfo endpointInfo) { var type = model.GetType(); var classAttributes = type.GetTypeInfo().GetCustomAttributes(); var queryProvider = model as IQueryStringProvider; foreach (var attribute in classAttributes) { //Handle our HalLinkAttributes, this way we can make sure the user can access the links var actionLinkAttribute = attribute as HalActionLinkAttribute; if (actionLinkAttribute != null) { if (actionLinkAttribute.CanUserAccess(context.User)) { if (!actionLinkAttribute.DocsOnly) { var href = actionLinkAttribute.Href; Dictionary <String, Object> requestData = null; if (queryProvider != null) { var builder = new RequestDataBuilder(); queryProvider.AddQuery(actionLinkAttribute.Rel, builder); requestData = builder.Data; } yield return(new Link(actionLinkAttribute.Rel, href, actionLinkAttribute.Title, actionLinkAttribute.Method, dataMode: actionLinkAttribute.DataMode, requestData: requestData)); } if (endpointInfo != null && actionLinkAttribute.HasDocs) { var docLink = actionLinkAttribute.GetDocLink(endpointInfo); if (docLink != null) { yield return(new Link(docLink.Rel, docLink.Href, docLink.Title, docLink.Method, false, dataMode: docLink.DataMode, requestData: docLink.RequestData)); //Don't replace parameters for these, already done } } } } else { var linkAttribute = attribute as HalLinkAttribute; if (linkAttribute != null) { yield return(new Link(linkAttribute.Rel, linkAttribute.Href, linkAttribute.Title, linkAttribute.Method, dataMode: linkAttribute.DataMode, requestData: linkAttribute.RequestData)); } } } var linkProvider = model as IHalLinkProvider; if (linkProvider != null) { var providerContext = new LinkProviderContext(context); var links = linkProvider.CreateHalLinks(providerContext); foreach (var linkAttribute in links) { //If we are getting action link attributes, do additional customization. var actionLinkAttribute = linkAttribute as HalActionLinkAttribute; if (actionLinkAttribute != null) { if (actionLinkAttribute.CanUserAccess(context.User)) { yield return(new Link(linkAttribute.Rel, linkAttribute.Href, linkAttribute.Title, linkAttribute.Method, dataMode: linkAttribute.DataMode, requestData: linkAttribute.RequestData)); //Include doc links for link provider links if (endpointInfo != null && actionLinkAttribute.HasDocs) { var docLink = actionLinkAttribute.GetDocLink(endpointInfo); if (docLink != null) { yield return(new Link(docLink.Rel, docLink.Href, docLink.Title, docLink.Method, false, dataMode: docLink.DataMode, requestData: docLink.RequestData)); //Don't replace parameters for these, already done } } } } else //Otherwise just include the link { yield return(new Link(linkAttribute.Rel, linkAttribute.Href, linkAttribute.Title, linkAttribute.Method, dataMode: linkAttribute.DataMode, requestData: linkAttribute.RequestData)); } } } }
/// <summary> /// This function can be overwritten to add any additional custom query strings needed /// to the query url. The base class version does nothing, so there is no need to /// call it from your subclass. /// </summary> /// <param name="rel">The input rel.</param> /// <param name="queryString">The query builder.</param> /// <returns>The customized query string.</returns> protected virtual void AddCustomQuery(String rel, RequestDataBuilder queryString) { }