2017-12-01 2 views
2

私は.NETフレームワークを初めて使用しており、Microsoft.AspNetCore.Http.HttpRequestインターフェイスに関する問題が発生しています。私はGetDisplayUri拡張子を使用しようとしていますが、無効なURIを返しています。その後、私はSystem.Uri.CreateThis()にURIを渡すと、次の例外が投げている:.NET Microsoft.AspNetCore.Http.Extensions UriHelper.GetDisplayUrlが無効なURIを返します

System.UriFormatException: Invalid URI: The format of the URI could not be determined. 

GetDisplayUri方法はHttpRequest内部のフィールドに基づいてURLを作成することになっているが、私はのどの部分を把握することはできませんどのフィールドにURLが入っているのですか?このオンラインの例は見つかりません。私は具体的にどのようにURLをPathPathBase、およびQueryString変数に分解しなければならないのだろうかと思っています。

たとえば、URL "http://example.com/route/endpoint?foo=bar"を作成したいとします。私はかなり私のQueryStringがちょうど"?foo=bar"であると確信していますが、残りのURLを他のフィールドに分割する方法はわかりません。 GetDisplayUriに関連する、私が述べた3つの他のフィールドがあるかどうかも教えてください。

不明な点がある場合は教えてください。

答えて

2

申し訳ありませんが、約1時間の試行錯誤の末、どのフィールドがURLのどの部分にマップされているかを把握しました。一般的な形式はurl = [Scheme]://[Host][PathBase][Path][QueryString]であり、それぞれに接続方法に関する特定の規則があります(たとえば、PathおよびPathBaseは/で始まる必要があります)。

したがって、質問("http://example.com/route/endpoint?foo=bar")の例では、HttpRequestオブジェクトには次のフィールドが必要です。

var request = class_implementing_HttpRequest() { 
    Scheme = "http", 
    Host = new HostString("example.com"), 
    PathBase = new PathString("/route"), 
    Path = new PathString("/endpoint"), 
    QueryString = new QueryString("?foo=bar") 
} 

これは、GetDisplayUriの実装が隠されているために分かりにくいものでした。うまくいけば、他の誰かがこの問題に遭遇したら、私はあなたに1時間の推測とチェックを保存しました。

編集:デイビッドは彼の答えに関するコメントで指摘したように、.NET Coreはオープンソースであり、私は答えがhereのように見えている可能性があります。

2

例外がどこから来たのか理解できないかもしれませんが、要求とクエリ文字列からURLを構築/再構築する方法の例を挙げることができます。

私はレコードのリストを表示する画面を持っています。それらの多くがあるので、私はフィルタリングと改ページをサポートする必要があります。フィルタはクエリ文字列として配置されます(例:?foo1=bar1&foo2=bar2)。改ページは、ページサイズと現在のページ番号をURLにも追加します(size=15&page=1)。

代わりのGetDisplayUri()を使用して、私は現在のURLを取りUrlHelperExtensionsを持っている、URLのクエリ文字列を調べ、URLに必要に応じて追加のクエリ文字列(ページサイズ&現在のページ)を追加します。ページネーションを行うために

namespace DL.SO.Project.Framework.Mvc.Extensions 
{ 
    public static class UrlHelperExtensions 
    { 
     public static string Current(this IUrlHelper url, object routeValues) 
     { 
      // Get current route data 
      var currentRouteData = url.ActionContext.RouteData.Values; 

      // Get current route query string and add them back to the new route 
      // so that I can preserve them. 
      // For example, if the user applies filters, the url should have 
      // query strings '?foo1=bar1&foo2=bar2'. When you construct the 
      // pagination links, you don't want to take away those query 
      // strings. 

      var currentQuery = url.ActionContext.HttpContext.Request.Query; 
      foreach (var param in currentQuery) 
      { 
       currentRouteData[param.Key] = param.Value; 
      } 

      // Convert new route values to a dictionary 
      var newRouteData = new RouteValueDictionary(routeValues); 

      // Merge new route data 
      foreach (var item in newRouteData) 
      { 
       currentRouteData[item.Key] = item.Value; 
      } 

      return url.RouteUrl(currentRouteData); 
     } 
    } 
} 

、私は現在のページサイズ、総アイテムの数、現在のページ、総ページ数、開始ページと終了ページを追跡する必要があります。私はそのためのクラス、Pager.csを作成します。

namespace DL.SO.Project.Framework.Mvc.Paginations 
{ 
    public class Pager 
    { 
     public int TotalItems { get; private set; } 
     public int CurrentPage { get; private set; } 
     public int CurrentPageSize { get; private set; } 
     public int TotalPages { get; private set; } 
     public int StartPage { get; private set; } 
     public int EndPage { get; private set; } 

     public Pager(int totalItems, int currentPage = 1, int currentPageSize = 15) 
     { 
      currentPageSize = currentPageSize < 15 
       ? 15 
       : currentPageSize; 

      // Calculate total, start and end pages 
      var totalPages = (int)Math.Ceiling(
       (decimal)totalItems/(decimal)currentPageSize 
      ); 

      currentPage = currentPage < 1 
       ? 1 
       : currentPage; 

      // Only display +- 2 
      var startPage = currentPage - 2; 
      var endPage = currentPage + 2; 
      if (startPage <= 0) 
      { 
       endPage = endPage - startPage + 1; 
       startPage = 1; 
      } 
      if (endPage > totalPages) 
      { 
       endPage = totalPages; 
       if (endPage > 5) 
       { 
        startPage = endPage - 4; 
       } 
      } 

      this.TotalItems = totalItems; 
      this.CurrentPage = currentPage; 
      this.CurrentPageSize = currentPageSize; 
      this.TotalPages = totalPages; 
      this.StartPage = startPage; 
      this.EndPage = endPage; 
     } 
    } 
} 

最後に、私はポケベルを構築するために部分図にURL拡張子とPagerクラスを使用することができます。

この方法で、ページ番号のリンクは、ページサイズと現在のページだけでなく、クエリ文字列とともに現在のURLに反映されます。

+0

これは素晴らしい情報であり、私は助けに感謝します。私はGetDislpayUri()を呼び出すメソッドの単体テストを書いていますが、実際に実装を変更する権限はありませんので、ここではこれを実際に使用することはできません。 – Tom

+1

ありがとうございます。 .NET Coreはオープンソースなので、実装を見てみることができますか? https://github.com/aspnet/HttpAbstractions/blob/dev/src/Microsoft.AspNetCore.Http.Extensions/UriHelper.cs –

+1

ああ、拡張メソッドがオープンソースであるという手掛かりはありませんでした。それは数時間前には素晴らしいことでした。とにかくありがとう! – Tom

関連する問題