2016-09-01 11 views
0

以下のリンクで、フィールドに同じ値が含まれていないことを確認する方法について質問しました(たとえば、C#の原因となるフィールドに固有の制約がある無防備な時の例外)。私が受け取った答えで、それはその問題を解決しましたが、別のものを提示しました。C# - MVC CMS - リモート検証のカスタマイズ

Ensuring another record does not already contain the same value for a field

私が今持っている主な問題は、私は新しいビューを作成するときにということです。検証は期待通りに機能します。要約 - ViewNameとViewPath(ルート)が両方とも一意であることを確認して、DBの検索が必要であることを確認する必要があります。

しかし、私がビューを編集すると、もう一度検証が行われます(ビューを編集しているので、ビューがすでに存在しているため実際には表示しないでください)。

ここで私の問題は、リモート検証がedit vs createに対して別々に動作するようにカスタマイズすることです。既存のビューと一致するようにビューの名前を編集できないはずですが、現在のビューが現在のビューと同じであるため保存してもいけません。以下は

(たぶん)ツール:-)によって生成されていない部分(私のモデルである:

[MetadataType(typeof(IViewMetaData))] 
public partial class View : IViewMetaData { } 

public interface IViewMetaData 
{ 
    [Required(AllowEmptyStrings = false, ErrorMessageResourceType = typeof(DALResources), ErrorMessageResourceName = "ErrorRequiredField")] 
    [StringLength(50, ErrorMessageResourceType = typeof(DALResources), ErrorMessageResourceName = "ErrorLessThanCharacters")] 
    [Display(ResourceType = typeof(DALResources), Name = "ViewName")] 
    [Remote("IsViewNameAvailable", "Validation")] 
    string ViewName { get; set; } 

    [Required(AllowEmptyStrings = false, ErrorMessageResourceType = typeof(DALResources), ErrorMessageResourceName = "ErrorRequiredField")] 
    [StringLength(400, ErrorMessageResourceType = typeof(DALResources), ErrorMessageResourceName = "ErrorLessThanCharacters")] 
    [Display(ResourceType = typeof(DALResources), Name = "ViewPath")] 
    [Remote("IsViewPathAvailable", "Validation")] 
    string ViewPath { get; set; } 

    [Display(ResourceType = typeof(DALResources), Name = "ViewContent")] 
    string ViewContent { get; set; } 
} 

私はとの問題を抱えています部分が定義されている[リモート]検証属性です次のようになります。

[OutputCache(Location = OutputCacheLocation.None, NoStore = true)] 
public class ValidationController : Controller 
{ 
    private FRCMSV1Entities db = new FRCMSV1Entities(); 

    public JsonResult IsViewNameAvailable(View view) 
    { 
     bool isViewNameInvalid = db.View.Any(v => v.ViewName == view.ViewName && v.Id != view.Id); 

     if (!isViewNameInvalid) 
      return Json(true, JsonRequestBehavior.AllowGet); 

     string suggestedViewName = string.Format(UI_Prototype_MVC_Resources.ErrorViewAlreadyExists, view.ViewName); 

     for (int i = 1; i < 100; i++) 
     { 
      string altViewName = view.ViewName + i.ToString(); 
      bool doesAltViewNameExist = db.View.Any(v => v.ViewName == altViewName); 
      if (!doesAltViewNameExist) 
      { 
       suggestedViewName = string.Format(UI_Prototype_MVC_Resources.ErrorViewNotAvailableTry, view.ViewName, altViewName); 
       break; 
      } 
     } 
     return Json(suggestedViewName, JsonRequestBehavior.AllowGet); 
    } 

    public JsonResult IsViewPathAvailable(View view) 
    { 
     bool doesViewPathExist = db.View.Any(v => v.ViewPath == view.ViewPath && v.Id != view.Id); 

     if (!doesViewPathExist) 
      return Json(true, JsonRequestBehavior.AllowGet); 

     string suggestedViewPath = string.Format(UI_Prototype_MVC_Resources.ErrorViewAlreadyExists, view.ViewPath); 

     for (int i = 1; i < 100; i++) 
     { 
      string altViewPath = view.ViewPath + i.ToString(); 
      bool doesAltViewPathExist = db.View.Any(v => v.ViewPath == altViewPath); 
      if (!doesAltViewPathExist) 
      { 
       suggestedViewPath = string.Format(UI_Prototype_MVC_Resources.ErrorViewNotAvailableTry, view.ViewPath, altViewPath); 
       break; 
      } 
     } 
     return Json(suggestedViewPath, JsonRequestBehavior.AllowGet); 
    } 
} 

問題は、作成と編集の両方で検証が同じである必要があります。同じレコードを引き続き参照していることを確認するために、編集の追加チェックを行うだけで済みます。そうであれば、間違いがないので検証メッセージを表示する必要はありません。

私の質問は です。1.これを期待どおりに動作させるにはどうすればよいですか。 2.どちらの方法もDRYの原則に違反するものであることがわかります。これをもっと一般的にして単純化するにはどうすればよいですか?しかし最初の質問は本当に私が答えたいと思うものです。なぜなら、動作しないものをリファクタリングすることに意味がないからです。詳細については

、上記のコードは次のリンクでも、コードの編集です:任意の助け

https://msdn.microsoft.com/en-us/library/gg508808(VS.98).aspx

感謝。

答えて

1

モデルのIDプロパティを渡すパラメータを追加する必要があります。AdditionalFields。そして、そのint Id

[Remote("IsViewPathAvailable", "Validation", AdditionalFields = "Id")] 
public string ViewName { get; set; } 

を仮定し、この方法は、その値がバックによって掲載されますので、Editビューで、あなたは、Idプロパティの非表示の入力が含まれていることを

public JsonResult IsViewNameAvailable(string viewName, int? id) 

注意する必要がありますjquery.validateリモート関数

idのパラメータがnull(つまり新しいもの)か、値(既存のもの)があるかどうかを確認し、それに合わせてクエリを調整できます。

bool isViewNameInvalid; 
if (id.HasValue) 
{ 
    isViewNameInvalid = db.View.Any(v => v.ViewName == viewName && v.Id != id); 
} 
else 
{ 
    isViewNameInvalid = db.View.Any(v => v.ViewName == ViewName); 
} 

何現在起こっていることRemoteのみViewNameプロパティの値を掲示していることで、あなたのパラメータがモデルであるので、それはデフォルトid値(0)で初期化され、クエリがに変換されAny(v => v.ViewName == viewName && v.Id != 0);

また、私はむしろ、あなたのpartial class

サイドノートという見解モデルを使用することをお勧め:suggestedViewNameを生成するコードから、あなたは多くのを期待しViewNameは同じ値を持っていて、おそらくあなたの内部で多数のデータベース呼び出しを行うことを意味します。forループ。 linq .StartsWith()クエリを使用して、ViewName値で始まるすべてのレコードを取得し、ループ内のメモリ内のセットを確認することを検討できます。

+0

回答がうまくいった。あなたの助けをもう一度ありがとう。私はあなたの提案を別々のコメントでお答えします。 Remoteを使うという提案は、実際にはコントローラのコードを削減しています。私が気に入らない唯一のことは、これが検証の問題であることですが、コントローラとしてセットアップされています。私はこれを行う別の方法を見つけることを試みるかもしれないし、任意の提案を感謝します。 –

+0

ViewModels。私は実際にViewModelを使用しますが、私は現時点でこのプロトタイプを作成しており、そこから機能的なシステムを得ることができるかどうかを見たいと思っています。後でそれをレイヤーに分けて、すべての良いことを行います。これは、ViewModelsが本当に必須になるときです。しかし、私は同意する、彼らは使用する必要があります。 –

+0

.StartsWith() - これは素晴らしい提案でした。私は今すぐ実装しました。すべてのあなたの助けをお寄せいただきありがとうございます。 –

関連する問題