2013-11-22 3 views
3

ContentArea에 삽입 할 블록의 종류를 제한하는 데 문제가 있습니다. 내가 원한 것은 SliderBlock의 ContentArea 속성은 SlideItemBlock 삽입만을 가질 수 있다는 것이다.ContentArea의 블록 제한

[ContentType(...)] 
public class SlideItemBlock : BlockData 
{ 
    [Required] 
    Display(Name = "Image")] 
    public virtual string Image { get; set;} 
} 

[ContentType(...)] 
public class SliderBlock : BlockData 
{ 
    [Required] 
    [Display(Name = "Slides")] 
    public virtual ContentArea Slides { get; set; } 
    //Should only accept insertion of SlideItemBlock 
} 

또는 잘못된 형식의 드래그 앤 드롭을 사용하지 않도록 편집기에서 제한하려고 시도하는 것은 잘못된 방법입니까?

이제는 SliderBlock을 만들고 SlideItemBlocks를 삽입 할 수 있습니다. 그런 다음 만들어진 SliderBlock을 새로운 SliderBlock에 삽입하면 영원히 반복되는 루프가 생겨 사이트가 손상됩니다. 이것이 내가 통제하려고하는 것입니다.

답변

5

멋져요 당신이 내장되어 콘텐츠 영역에서 사용할 수있는 블록 EPiServer 7.5의 규제를 사용하는 경우 자세한 내용은이 블로그 게시물을 살펴 : Restricting the allowed types in a content area. 블로그 게시물에서

코드 예제 : 프레데릭 우리는 우리가 단지이 작업을 수행하기 위해 다음과 같은 속성을 만들었습니다 제안 당신의

[EditorDescriptorRegistration(TargetType = typeof(ContentArea), UIHint = "Gallery")] 
    public class ImageGalleryEditorDescriptor : EditorDescriptor 
    {  
    public ImageGalleryEditorDescriptor()  
    {  
     // Setup the types that are allowed to be dragged and dropped into the content   
     // area; in this case only images are allowed to be added.   
     AllowedTypes = new Type[] { typeof(IContentImage) };   

     // Unfortunetly the ContentAreaEditorDescriptor is located in the CMS module   
     // and thus can not be inherited from; these settings are copied from that   
     // descriptor. These settings determine which editor and overlay should be   
     // used by this property in edit mode.   
     ClientEditingClass = "epi-cms.contentediting.editors.ContentAreaEditor";   
     OverlayConfiguration.Add("customType", "epi-cms.widget.overlay.ContentArea");  
    } 
    } 
-1

허용되는 블록 유형을 제한하기 위해 유효성 검증 속성을 컨텐츠 영역 특성에 추가 할 수 있습니다. 자세한 예제는 this link을 참조하십시오.

그런 다음 AvailableContentTypes 속성을 사용하면 SlideItemBlock 유형 만 허용하도록 제한 할 수 있습니다. .

[Required] 
    [Display(Name = "Slides")] 
    [AvailableContentTypes(Include = new []{typeof(SlideItemBlock)})] 
    public virtual ContentArea Slides { get; set; } 
+0

시도는 응답에 일부 코드뿐만 아니라 링크를 포함 EpiWorld에이 일을 Theres는 것이다. – shenku

1

아직 7.5로 업그레이드하지 않았습니다.

using EPiServer.Core; 
using System; 
using System.Collections.Generic; 
using System.ComponentModel.DataAnnotations; 
using System.Linq; 

namespace xxx.Com.Core.Attributes 
{ 
    [AttributeUsage(AttributeTargets.Property)] 
    public class OurAvailableContentTypesAttribute : ValidationAttribute 
    { 
     public Type[] Include { get; set; } 
     public Type[] Exclude { get; set; } 

     public override bool IsValid(object value) 
     { 
      if (value == null) 
      { 
       return true; 
      } 

      if (!(value is ContentArea)) 
      { 
       throw new ValidationException("OurAvailableContentTypesAttribute is intended only for use with ContentArea properties"); 
      } 

      var contentArea = value as ContentArea; 

      var notAllowedcontentNames = new List<string>(); 

      if (contentArea != null) 
      { 
       if (Include != null) 
       { 
        var notAllowedContent = contentArea.Contents.Where(x => !ContainsType(Include, x.GetType())); 
        if (notAllowedContent.Any()) 
        { 
         notAllowedcontentNames.AddRange(notAllowedContent.Select(x => string.Format("{0} ({1})", x.Name, x.ContentLink.ID))); 
        } 
       } 
       if (Exclude != null) 
       { 
        var notAllowedContent = contentArea.Contents.Where(x => ContainsType(Exclude, x.GetType())); 
        if (notAllowedContent.Any()) 
        { 
         notAllowedcontentNames.AddRange(notAllowedContent.Select(x => string.Format("{0} ({1})", x.Name, x.ContentLink.ID))); 
        } 
       } 
      } 

      if (notAllowedcontentNames.Any()) 
      { 
       ErrorMessage = "contains invalid content items :"; 
       foreach (var notAllowedcontentName in notAllowedcontentNames) 
       { 
        ErrorMessage += " " + notAllowedcontentName + ","; 
       } 
       ErrorMessage = ErrorMessage.TrimEnd(','); 

       return false; 
      } 
      return true; 
     } 

     private bool ContainsType(Type[] include, Type type) 
     { 
      return include.Any(inc => inc.IsAssignableFrom(type)); 
     } 

     protected override ValidationResult IsValid(object value, ValidationContext validationContext) 
     { 
      var result = base.IsValid(value, validationContext); 
      if (result != null && !string.IsNullOrEmpty(result.ErrorMessage)) 
      { 
       result.ErrorMessage = string.Format("{0} {1}", validationContext.DisplayName, ErrorMessage); 
      } 
      return result; 
     } 
    } 
} 

이의 사용은

public class OurBlock : BlockData 
    { 
     [CultureSpecific] 
     [Editable(true)] 
     [Display(Name = "", 
      Description = "", 
      GroupName = SiteConstants.GroupNames.ContentArea, 
      Order = 1)] 
     [OurAvailableContentTypes(Include = new[] { typeof(OurImageBlock) })] 
     public virtual ContentArea ImageContentArea { get; set; } 

HTH

아담

+0

대신 Epi 7.5에서 AllowedTypes 주석을 사용하지 않아야합니까? 똑같은 일을하는 것 같습니다. –

+0

@EricHerlitz 이것이 내 제안이 OP가 아직 7.5로 업그레이드되지 않았다는 전제로 시작한 이유입니다. –

+0

아, 죄송합니다 :) –

0

검증 클래스를 작성하고 EPiServer.validation에서 IValidate 인터페이스를 구현합니다. 이 유효성 검사는 PageData 및 BlockData 클래스 외부에서 유지됩니다.

이것은 당신이 당신은 내가 모르고 오전

[AllowedTypes(new [] {typeof(SlideItemBlock)})] 
public virtual ContentArea Slides { get; set; } 

을 AllowedTypes 주석을 사용할 수 있습니다 EPI 7.5으로 업그레이드 한 경우 http://sdkbeta.episerver.com/SDK-html-Container/?path=/SdkDocuments/CMS/7/Knowledge%20Base/Developer%20Guide/Validation/Validation.htm&vppRoot=/SdkDocuments//CMS/7/Knowledge%20Base/Developer%20Guide/

에서

using System.Collections.Generic; 
using System.Linq; 
using EPiServer.Validation; 

public class SliderBlockValidator : IValidate<SliderBlock> 
{ 
    public IEnumerable<ValidationError> Validate(SliderBlock instance) 
    { 
     var errors = new List<ValidationError>(); 
     if (instance.Slides != null && 
      instance.Slides.Contents.Any(x => x.GetType().BaseType != typeof (SlideItemBlock))) 
     { 
      errors.Add(new ValidationError() 
       { 
        ErrorMessage = "Only SlideItemBlocks are allowed in this area", 
        PropertyName = "Slides", 
        Severity = ValidationErrorSeverity.Error, 
        ValidationType = ValidationErrorType.StorageValidation 
       }); 
     } 

     return errors; 
    } 
} 

더 읽기 찾고있는 것을해야한다 나중에 솔루션을 사용하여 메시지를 사용자 정의 할 수있는 경우 몇 가지 알려진 제한 사항이 있습니다.

  • 페이지에서 편집 할 때 오버레이에 대한 제한이 작동하지 않습니다. 이 버그는 수정되어 몇 주 안에 패치로 발표 될 것입니다.
  • 서버 유효성 검사가 없습니다. 현재이 속성은 UI에 제한 사항 만 추가합니다. 조만간 서버 유효성 검사에 대한 지원을 추가하여 사용자 정의 속성의 유효성을 검사 할 수 있기를 바랍니다.
  • 콘텐츠 영역에 로컬 블록을 만들 때 유효성을 검사하지 않습니다. 새 기능을 사용하여 콘텐츠 영역에 로컬 블록을 추가하는 경우 현재 새 블록을 만들 때 콘텐츠 형식이 필터링되지 않습니다.

모든 최초의 솔루션에 http://world.episerver.com/Blogs/Linus-Ekstrom/Dates/2013/12/Restriction-of-content-types-in-properties/

모든 현재 하나 더 더에보십시오.

2

EpiServer 8부터는 [AllowedTypes]라는 새 속성이 있습니다. 이것은 이제 블록을 제한하는 최선의 방법입니다. [AvailableContentTypes]의 많은 한계를 극복합니다. 블록을 내용 영역으로 드래그하면 유효성 검사가 실제로 작동합니다.

예제 코드는

[AllowedTypes(new []{ typeof(SlideBlock) })] 
public virtual ContentArea Slides { get; set; } 

여기 좋은 코드 예제 또한 How To Restrict The Blocks Allowed Within A Content Area Episerver

http://world.episerver.com/blogs/Ben-McKernan/Dates/2015/2/the-new-and-improved-allowed-types/