4

Global.asax(MVC 3 Webプロジェクト)で次のルートが定義されています。

routes.MapRoute(
                "BlogCategory", // Route name
                "Blog/Category/{*category}", // URL with parameters
                new { controller = "Blog", action = "Index", category = "" } // Parameter defaults
            );

そして、私のアクションは次のようなカテゴリパラメータを受け入れます。

   public ViewResult Index(string category, int page = 1)
        {
            PostListViewModel viewModel;
            if (string.IsNullOrEmpty(category))
            { 
....show all cats else show only the one passed in

これは正常に機能し、カテゴリをコントローラに渡し、結果を適切にフィルタリングします。

私の問題は、私が作成したカテゴリの1つが、そのカテゴリ名に対して次のようになっている場合です。

プロジェクト/ラボ

(スペースとスラッシュに注意してください)

これにより、次のようなURLが作成されます。

/ Blog / Category / Projects%20 /%20Lab

リンクをたどると、次のエラーが発生します。

説明:HTTP404。探しているリソース(またはその依存関係の1つ)が削除されたか、名前が変更されたか、一時的に使用できなくなった可能性があります。次のURLを確認し、スペルが正しいことを確認してください。

リクエストされたURL:/ Blog / Category / Projects / Lab

デバッグ時にインデックスアクションに到達することはありません。

私の質問は、これをどのように機能させることができるか、またはこれが発生しないようにカテゴリ名を作成するときに入力検証を行う必要があるかどうかです。

4

2 に答える 2

0

Tyrsiusが提案したように、カテゴリIDを渡す方が簡単ですが、名前を渡したい場合はUrl.Encode()、リンクを作成するか、カスタムを作成するたびに使用することをお勧めUrlHelperします。コントローラのアクションにヒットしたら、Url.Decode()を実行して元の文字列を元に戻します。

よりクリーンな方法は、独自のルートハンドラー(実装IRouteHandler)を作成して、それを実行することです。

于 2011-12-13T13:02:27.773 に答える
-1

まず、Tyrsius、Romias、eth0の提案に感謝します。

カテゴリにIDを使用したくないと判断し、ルートハンドラを作成したくありませんでした。これは、根本的な問題を実際には解決していないためです。

代わりに、 「UsedAsUrl」という検証属性を作成し、これをドメインモデルのCategory.Nameに適用しました。これには、組み込みの検証(エンドユーザーに適している)と、開発者の観点から見た再利用性に優れているという利点があります。

したがって、私のカテゴリモデルは次のようになります([UsedAsUrl]属性に注意してください)。

public class Category
{
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int Id { get; set; }

        [Required]
        [UsedAsUrl]
        [MaxLength(50, ErrorMessage = "One word or groups of words please")]
        public string Name { get; set; }

        public virtual List<Post> Posts { get; set; }
}

そして、私が作成した属性は次のようになります。

using System;
using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;

namespace CommonWebsiteUtilities.Attributes
{
    [AttributeUsage(AttributeTargets.Field | AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
    public class UsedAsUrlAttribute : ValidationAttribute
    {
        public UsedAsUrlAttribute() : base("Must not contain a slash with spaces either side") {}

        public override bool IsValid(object value)
        {
            var input = value.ToString();
            var result = true;

            if (input.Contains("/"))
            {
                input = Regex.Replace(input, @"\s+", " ");
                if (input.Contains(" /")) result = false;
                if (input.Contains("/ ")) result = false;
                if (input.Contains(" / ")) result = false;
            }

            return result;
        }
    }
}

カテゴリを追加すると、次のようになります。

検証に失敗することがわかっているカテゴリを追加する

私はこの応答を自動的に受け取ります:

検証による応答の失敗

JSはまだ機能していませんが、コントローラーはモデルの状態を取得できます。これはモデルの状態からの応答であるため、属性は正しく機能しています。

これは基本的に、いずれかの側にスペースがあるスラッシュをチェックします。これは完全なURLバリデーターではありませんが、私の現在のプロジェクトでは機能することに注意してください。誰かが何か改善があれば、私に知らせてください、そして私はこの答えを修正します。

私はRegExpが苦手なので、RegularExpressionAttributeから派生していません。また、モデル内からエラーメッセージを提供する必要もありませんでした。カテゴリをURLパーツとして使用すると、より多くのルールが表示されるため、この属性は実際に構築する必要があります。

于 2011-12-13T22:51:00.503 に答える