2015-12-04 19 views
5

Tôi đang làm việc trên trang web MVC sẽ có nhiều bản dịch. Chúng tôi đang tìm cách thực hiện điều đó thông qua các tên miền phụ như http://en.domain.com hoặc http://fr.domain.com. Chúng tôi cũng muốn hỗ trợ miền thông thường http://domain.com.Nhận tên miền phụ trong MVC để quốc tế hóa

Bản dịch đang làm việc với điều kiện bạn thay đổi tên miền phụ theo cách thủ công, nhưng tôi đang tìm cách tự động hóa điều này và duy trì toàn bộ URL hiện tại để cho phép người dùng tìm thấy http://en.domain.com/product để nhấp vào liên kết và nhận phiên bản ngôn ngữ khác của cùng một trang. Có vẻ như đơn giản chỉ cần tách biệt tên miền phụ nếu nó tồn tại, loại bỏ nó khỏi url hiện tại và thay thế bằng phiên bản ngôn ngữ được chỉ định.

Về bản chất:

http://en.domain.com/product (gốc)

http://domain.com/product (làm sạch)

http://fr.domain.com/product hoặc http://de.domain.com/product vv ... (đầu ra)

Tôi bắt đầu tìm kiếm được xây dựng trong chức năng như Request.Url.Subdomain nhưng đã kết luận không có sinh vật kỳ diệu như vậy. Sau đó tôi chuyển sang thao tác chuỗi cơ bản, nhưng nó dường như thực sự bị pha trộn vì vậy tôi đặt ra để tìm một giải pháp regex.

Tôi đã thử nghiệm regex này với một số người kiểm tra regex trực tuyến thường làm việc cho tôi và họ đang xác định chính xác tên miền phụ khi nó tồn tại, nhưng không tìm thấy kết quả khi mã thực sự chạy.

Tôi chỉ sử dụng cụm từ thông dụng một chút và tôi hy vọng có điều gì đó thực sự rõ ràng là tôi đang làm sai ở đây. Nếu có một giải pháp tốt hơn, tôi sẽ mở ra cho những sự cố gắng khác.

C#

string url = Request.Url.AbsoluteUri; //http://en.domain.com/ 
Regex regex = new Regex(@"/(?:http[s]*\:\/\/)*(.*?)\.(?=[^\/]*\..{2,5})/", RegexOptions.IgnoreCase); 
GroupCollection results = regex.Match(url).Groups; 
Group result = results[0]; 

Dưới đây là giải pháp tôi có bây giờ. Không thanh lịch như tôi muốn, nhưng đối với một cái gì đó mà ăn quá nhiều thời gian nó hiện đang làm việc như dự định.

Xem

<a href="@Html.Action("ChangeLanguage", new { lang = "en" })">English</a> 
<a href="@Html.Action("ChangeLanguage", new { lang = "fr" })">French</a> 

Action

public string ChangeLanguage(string controller, string lang) 
    { 
     string url = Request.Url.AbsoluteUri; 

     Regex regex = new Regex(@"(?:https*://)?.*?\.(?=[^/]*\..{2,5})", RegexOptions.IgnoreCase); 
     GroupCollection results = regex.Match(url).Groups; 
     Group result = results[0]; 
     if (result.Success) 
     { 
      string[] resultParts = result.Value.Split('/'); 
      string newSubDomain = resultParts[0] + "//" + lang + "."; 
      url = url.Replace(result.Value, newSubDomain); 
     } 
     else 
     { 
      string[] urlParts = url.Split('/'); 
      string oldParts = urlParts[0] + "//"; 
      string newParts = urlParts[0] + "//" + lang + "."; 
      url = url.Replace(oldParts, newParts); 
     } 


     return url; 
    } 
+1

Điều hiển nhiên: bạn không cần phân cách regex trong C#. Hãy thử '@" (?: Https *: //)?. *? \. (? = [^ /] * \ .. {2,5}) '. –

+0

Bạn đã cân nhắc sử dụng thứ gì đó khác với tên miền phụ?' Http : // domain.com/fr/product' cũng hoạt động tốt và không yêu cầu mỗi "bản dịch" mới được đăng ký dưới dạng mục nhập DNS. –

+0

@stribizhev Đó là nó. Tôi không chắc chắn 100% lý do tại sao phần giữa hoạt động, nhưng có vẻ như từ thử nghiệm –

Trả lời

2

Sử dụng một cái gì đó như sau (psuedocode - nên thêm kiểm tra an toàn và như vậy):

Uri myHost = new Uri("https://en.mydomain.com"); 
string hostname = myHost.Host; // returns en.mydomain.com 
string subdomain = string.split(".", hostname)[0]; // subdomain = "en" 

này sẽ nhận được các hos tname, sau đó bạn có thể chia nhỏ trên "." vào một mảng và lấy phần tử đầu tiên.

EDIT: Liên kết tới tài liệu MSDN trên Uri.Đăng cai

https://msdn.microsoft.com/en-us/library/system.uri.host(v=vs.110).aspx

+0

Đây thực chất là những gì tôi đã thử lúc đầu, nhưng tôi cần một giải pháp không yêu cầu một miền "chuỗi ma thuật" được nhập vào. ở vị trí tiếp thị ở đâu đó để xuất bản một URL có tài liệu in hoặc pháp lý và chỉ "chọn" một miền cho nó. Điều này có nghĩa là chúng tôi thường không có lựa chọn nhưng để hỗ trợ nhiều tên miền cho cùng một trang. –

+1

Điều này không đòi hỏi bất kỳ chuỗi ma thuật nào cả. Tham số hàm tạo Uri trong ví dụ này có thể đến từ bất cứ thứ gì, bao gồm thuộc tính yêu cầu, tệp cấu hình, v.v. Tôi chỉ sử dụng một chữ cái ở đó để ngắn gọn. Phần quan trọng là thuộc tính Uri.Host trả về tên miền mà không có "thứ" khác trong đó, và nếu, theo quy ước, ngôn ngữ luôn là đầu tiên, sau đó bạn có thể chia nhỏ thời gian và lấy phần tử đầu tiên hoặc tìm kiếm mảng cho mẫu. Những người tiếp thị có khả năng tuyệt vời để phá vỡ bất kỳ mã nào, bất kể bạn làm như thế nào. – DVK

3

Bạn có thể sử dụng định tuyến tùy chỉnh để làm cho nó đơn giản

routes.Add("LanguageRoute", new DomainRoute( 
"{language}.example.com/{controller}/{action}", // Domain with parameters 
"{controller}/{action}/{id}", // URL with parameters 
new { controller = "Home", action = "Index", id = "" } // Parameter defaults 

))

Và nhận được giá trị ngôn ngữ trên bộ điều khiển

public ActionResult Index(string language) 
    { 
     return View(); 
    } 

một liên kết hữu ích có thể giúp bạn: http://benjii.me/2015/02/subdomain-routing-in-asp-net-mvc/

+0

Đây là loại giải pháp tôi muốn sử dụng, nhưng tôi không hoàn toàn hiểu việc sử dụng ghi đè RouteBase trong liên kết vì tôi có thể thấy rằng nó đang chạy và cập nhật tuyến đường, nhưng nó đang xảy ra sau khi hành động chạy do đó tham số hành động luôn là null. Tôi giả sử nó có một cái gì đó để làm với phương pháp GetVirtualPath mà vẫn còn để được thực hiện, nhưng đã không figured rằng ra được nêu ra. –

+0

Hey Locke tôi vừa lấy mẫu mã như cách sử dụng cơ bản. Tôi cần ngủ nhưng tôi sẽ cho bạn một ví dụ làm việc với chỉnh sửa vào ngày mai. Hi vọng nó sẽ giúp ích cho bạn. – c0demaster

+0

Chắc chắn, đó là nhiều hơn tôi thực sự có thể yêu cầu. Trong lúc đó tôi sẽ tiếp tục cố gắng. –

0

Chúng tôi làm điều gì đó tương tự trên một trong những dự án của tôi, và đây là cách tôi nhận được các tên miền phụ hiện tại:

string GetSubDomain(Uri url, string defaultValue) 
{ 
    string subdomain = defaultValue; 

    if (url.HostNameType == UriHostNameType.Dns) 
    { 
     string host = url.Host; 
     if (host.Split('.').Length > 2) 
     { 
      int index = host.IndexOf("."); 
      int lastIndex = host.LastIndexOf("."); 
      subdomain = index.Equals(lastIndex) ? defaultValue : host.Substring(0, index); 
     } 
    } 

    return subdomain; 
} 

Bạn sẽ sử dụng nó như vậy:

var subdomain = GetSubDomain(HttpContext.Current.Request.Url, "en"); 

này giả định rằng bạn chỉ bao giờ muốn tên miền phụ đầu tiên trong URL hiện tại, do đó cả hai http://fr.example.comhttp://fr.something.example.com sẽ mang lại fr, trong khi http://example.com sẽ mang lại en (giá trị mặc định trong ví dụ này).