2016-09-01 3 views
0

아래 링크에서 필드에 이미 동일한 값이 포함되지 않도록하는 방법에 대한 질문을했습니다. 예를 들어, C#에서 문제를 일으키는 필드에 고유 제한 조건이있는 경우 예외가있을 때). 내가받은 대답으로이 문제를 해결했지만 다른 문제를 제시했습니다.원격 유효성 검사 사용자 정의

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

내가 지금 가지고있는 가장 큰 문제는 내가 새로운보기를 생성 할 때이다. 유효성 검사는 예상대로 작동합니다. 요약 - 시스템은 ViewName과 ViewPath (경로)가 모두 고유하여 DB 검색이 필요하다는 것을 확인해야합니다.

그러나보기를 편집 할 때 유효성 검사가 다시 시작됩니다. 실제로보기가 이미 편집 중이므로 분명히 표시되어서는 안됩니다.

내 문제는 이제 편집 대 제작과 다르게 작동하도록 원격 유효성 검사를 사용자 정의하는 방법입니다. 기존 뷰와 일치하도록 뷰의 이름을 편집 할 수는 없지만 현재 뷰와 동일하기 때문에 현재 뷰를 저장하지 않아야합니다.

[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); 
} 

은 무엇 현재 일어나고있는 것은 RemoteViewName 속성 값을 게시하고, 당신의 매개 변수는 모델이기 때문에, 그것은 기본 id 값 (0)로 초기화되고 쿼리가로 번역되어있다 Any(v => v.ViewName == viewName && v.Id != 0);

나는 또한 당신의 partial class

사이드 노트는 오히려 뷰 모델을 사용하는 것이 좋습니다

: suggestedViewName를 생성하는 코드에서 당신의,175 많이 기대은 동일한 값을 가지고 있습니다. 즉, 내부에서 수많은 데이터베이스 호출을 할 수 있습니다. for 루프. linq .StartsWith() 쿼리를 사용하여 ViewName 값으로 시작하는 모든 레코드를 가져온 다음 루프의 메모리 세트를 확인할 수 있습니다.

+0

답변이 효과적입니다. 도와 줘서 고마워. 각 의견을 별도의 의견으로 언급하겠습니다. Remote를 사용하라는 제안은 실제로 컨트롤러에서 코드를 줄였습니다. 내가 싫어할 수있는 유일한 것은 이것이 검증 문제이지만 컨트롤러로 설정된다는 것입니다. 나는 이것을 할 수있는 대체 방법을 찾으려고 노력할 것이고 어떤 제안이라도 고맙게 여길 것이다. –

+0

ViewModels. ViewModel을 사용할 것입니다. 그러나 지금은 프로토 타입을 작성 중이고 기능적 시스템을 얻을 수 있는지 확인하고 싶습니다. 나중에 레이어로 분리하고 모든 좋은 작업을 수행하며 ViewModels가 실제로 필수 요소가 될 때입니다. 그러나 나는 그들이 동의해야한다. –

+0

.StartsWith() - 이것은 훌륭한 제안이었습니다. 방금 구현했습니다. 스티븐의 모든 도움에 다시 한번 감사드립니다. –

관련 문제