在ASP.NET WebApi中修改UrlHelper.Link的GetQueryNameValuePairs()

时间:2014-09-16 12:57:11

标签: c# asp.net-web-api query-string

使用ASP.NET WebApi,当我发送GET api/question?page=0&name=qwerty&other=params时,API应该在分页信封中给出结果。

为此,我想将结果和给定page querystring更改为其他值。

我试过以下代码,但我对此感觉不好。

protected HttpResponseMessage CreateResponse(HttpStatusCode httpStatusCode, IEnumerable<Question> entityToEmbed)

    // get QueryString and modify page property
    var dic = new HttpRouteValueDictionary(Request.GetQueryNameValuePairs());
    if (dic.ContainsKey("page"))
        dic["page"] = (page + 1).ToString();
    else
        dic.Add("page", (page + 1).ToString());

    var urlHelper = new UrlHelper(Request);
    var nextLink= page > 0 ? urlHelper.Link("DefaultApi", dic) : null;

    // put it in the envelope
    var pageEnvelope = new PageEnvelope<Question>
        {
            NextPageLink = nextLink,
            Results = entityToEmbed
        };

        HttpResponseMessage response = Request.CreateResponse<PageEnvelope<Question>>(httpStatusCode, pageEnvelope, this.Configuration.Formatters.JsonFormatter);
        return response;
    }

NextPageLink给出了很多复杂的结果:
     http://localhost/api/Question?Length=1&LongLength=1&Rank=1&SyncRoot=System.Collections.Generic.KeyValuePair%602%5BSystem.String%2CSystem.String%5D%5B%5D&IsReadOnly=False&IsFixedSize=True&IsSynchronized=False&page=1

我的问题是,

  1. 使用Dictionary方法进行的页面处理似乎很脏而且错误。有没有更好的方法来解决我的问题?
  2. 我不知道为什么urlHelper.Link(routeName, dic)会给出如此详细的ToString结果。如何摆脱无法使用的与字典相关的属性?

1 个答案:

答案 0 :(得分:1)

您的代码中可能存在的关键问题是转换为HttpRouteValueDictionary。相反,新建它并添加循环所有键值对。

这种方法可以简化很多,你也应该考虑使用HttpActionResult(以便你可以更轻松地测试你的行为。

您还应该避免使用httproutevaluedictionary,而是将您的UrlHelper写为

urlHelper.Link("DefaultApi", new { page = pageNo }) // assuming you just want the page no, or go with the copying approach otherwise.

只需预先计算您的页面号(并避免使用ToString);

将所有内容全部写入IHttpActionResult,该页面使用页码公开int属性,这样您就可以轻松地测试操作结果,而不管您如何计算分页。

类似于:

public class QuestionsResult : IHttpActionResult
{
    public QuestionResult(IEnumerable<Question> questions>, int? nextPage)
    {
       /// set the properties here
    }

    public IEnumerable<Question> Questions { get; private set; }

    public int? NextPage { get; private set; }

    /// ... execution goes here

}

要获取页面号,请执行以下操作:

来源 - http://www.asp.net/web-api/overview/releases/whats-new-in-aspnet-web-api-21

string page = request.Uri.ParseQueryString()["page"]; 

您可以使用下面的扩展方法(来自Rick Strahl)

public static string GetQueryString(this HttpRequestMessage request, string key)
{      
    // IEnumerable<KeyValuePair<string,string>> - right!
    var queryStrings = request.GetQueryNameValuePairs();
    if (queryStrings == null)
        return null;

    var match = queryStrings.FirstOrDefault(kv => string.Compare(kv.Key, key, true) == 0);
    if (string.IsNullOrEmpty(match.Value))
        return null;

    return match.Value;
}