Development

Sửa lỗi AmbiguousMatchException trong Optimizely CMS 12

By Ginbok4 min read

Vấn đề

Khi bạn khởi động ứng dụng Optimizely CMS 12, bạn gặp lỗi sau:

System.Reflection.AmbiguousMatchException:
Ambiguous match found for property 'Category'

Ứng dụng của bạn sẽ không khởi động được. Hệ thống CMS không thể tải các loại nội dung (content types).


Nguyên nhân

Bạn có hai thuộc tính (property) cùng tên trong một loại nội dung (content type).

Điều này thường xảy xảy ra khi:

Ví dụ về vấn đề:

// Lớp cơ sở (trong Optimizely)
public class ContentData
{
    public virtual ContentReference Category { get; set; }
}

// Lớp của bạn
public class ArticlePage : PageData
{
    // ❌ LỖI: Điều này tạo ra một sự trùng lặp!
    public virtual ContentReference Category { get; set; }
}

Giải pháp

Đơn giản là đổi tên thuộc tính của bạn thành một tên duy nhất.

Chỉ vậy thôi. Không cần SQL. Không cần dọn dẹp cơ sở dữ liệu. Chỉ cần đổi tên thuộc tính.

Trước khi (Bị lỗi):

public class ArticlePage : PageData
{
    [Display(Name = "Category")]
    public virtual ContentReference Category { get; set; }  // ❌ Trùng lặp!
}

Sau khi (Đã sửa):

public class ArticlePage : PageData
{
    [Display(Name = "Category")]
    public virtual ContentReference ArticleCategory { get; set; }  // ✅ Tên duy nhất
}

Đó là tất cả những gì bạn cần làm.


Các bước sửa lỗi

  1. Tìm lỗi trong logs để xem thuộc tính nào bị trùng lặp
  2. Tìm loại nội dung (content type) gây ra sự cố
  3. Đổi tên thuộc tính thành một tên duy nhất
  4. Khởi động lại ứng dụng

Hoàn tất.


Các Lỗi Thường Gặp

Lỗi 1: Sử dụng Từ khóa new

// ❌ KHÔNG LÀM ĐIỀU NÀY
public class ArticlePage : PageData
{
    public new ContentReference Category { get; set; }
}

Trình biên dịch cho phép, nhưng cơ chế reflection của Optimizely thì không.

Lỗi 2: Che khuất Thuộc tính Cơ sở

// Nếu lớp cơ sở có "Category"
public class MyPage : BasePage
{
    // ❌ KHÔNG lặp lại tên thuộc tính này
    public virtual ContentReference Category { get; set; }
}

Giải pháp: Luôn kiểm tra lớp cơ sở của bạn để tìm các tên thuộc tính hiện có.


Cách Phòng ngừa

  1. Sử dụng tên thuộc tính duy nhất trong các loại nội dung của bạn
  2. Kiểm tra các lớp cơ sở trước khi thêm thuộc tính mới
  3. Không bao giờ sử dụng từ khóa new trên các thuộc tính CMS
  4. Sử dụng tiền tố nếu cần (ví dụ: ArticleCategory thay vì Category)

Các Câu Hỏi Thường Gặp

H: Tôi có bị mất dữ liệu nội dung không?

Đ: Không. Khi bạn đổi tên thuộc tính, Optimizely tạo một định nghĩa thuộc tính mới. Dữ liệu cũ vẫn nằm trong cơ sở dữ liệu nhưng sẽ không được hiển thị cho đến khi bạn di chuyển nó (migrate).

H: Tôi có cần chạy các tập lệnh SQL không?

Đ: Không. Chỉ cần đổi tên thuộc tính trong code của bạn. Optimizely sẽ xử lý phần còn lại.

H: Còn nội dung hiện có thì sao?

Đ: Nội dung hiện có sẽ hiển thị giá trị trống cho thuộc tính đã được đổi tên. Bạn có thể cần nhập lại dữ liệu hoặc tạo một script di chuyển (migration script) nếu bạn có nhiều nội dung.


Ví dụ Thực tế

Tôi đã có một ArticlePage với thuộc tính Category. Hóa ra PageData hoặc một trong các lớp cơ sở của tôi đã có sẵn thuộc tính Category.

Cách khắc phục của tôi:

// Đã thay đổi từ:
public virtual ContentReference Category { get; set; }

// Sang:
public virtual ContentReference ArticleCategory { get; set; }

Ứng dụng đã khởi động ngay lập tức sau khi build lại.


Tóm tắt

Vấn đề: Lỗi AmbiguousMatchException
Nguyên nhân: Trùng tên thuộc tính
Giải pháp: Đổi tên thuộc tính thành một tên duy nhất
Thời gian sửa lỗi: 2 phút

Chỉ vậy thôi. Không cần công việc cơ sở dữ liệu phức tạp nào.

#Optimizely#OptimizelyCMS12#CSharp#DotNet#AmbiguousMatchException#CMSDevelopment#SoftwareTroubleshooting#WebDevelopment
← Back to Articles