2009-03-02 67 views
21

Tôi tò mò muốn mọi người làm gì để xử lý/trừu tượng QueryString trong ASP.NET. Trong một số ứng dụng web của chúng tôi, tôi thấy rất nhiều điều này trên tất cả các trang web:Chuyển đổi/truy cập các giá trị QueryString trong ASP.NET

int val = 0; 
if(Request.QueryString["someKey"] != null) 
{ 
val = Convert.ToInt32(Request.QueryString["someKey"]); 
} 

Một số cách tốt hơn để xử lý doanh thu này là gì?

Trả lời

24

Tôi có xu hướng thích tóm tắt chúng dưới dạng thuộc tính. Ví dụ:

 public int age { 
     get 
     { 
      if (Request.QueryString["Age"] == null) 
       return 0; 
      else 
       return int.Parse(Request.QueryString["Age"]);          
     } 
    } 

Bạn có thể thêm xác thực khác nếu muốn. Nhưng tôi có xu hướng thích gói tất cả các biến chuỗi truy vấn theo cách này.

EDIT: --- Cũng như một áp phích khác đã chỉ ra rằng bạn phải tạo các thuộc tính này trên mọi trang. Câu trả lời của tôi là không bạn không. Bạn có thể tạo các thuộc tính này trong một lớp duy nhất mà bạn có thể gọi là "Chuỗi truy vấn" hoặc một thứ gì đó. Sau đó, bạn có thể nhanh chóng lớp này trong mỗi trang mà bạn muốn truy cập các chuỗi truy vấn của bạn, sau đó bạn chỉ có thể làm điều gì đó như

var queryStrings = new QueryStrings(); 
var age = queryStrings.age; 

Bằng cách này bạn có thể gói gọn tất cả các logic cho việc truy cập và xử lý từng loại biến truy vấn ở một vị trí duy nhất.

EDIT2: --- Và bởi vì nó là một thể hiện của lớp, bạn cũng có thể sử dụng tiêm phụ thuộc để tiêm lớp QueryStrings ở mọi nơi bạn đang sử dụng nó. StructureMap thực hiện tốt công việc đó. Điều này cũng cho phép bạn giả lập lớp QueryStrings và tiêm rằng nếu bạn muốn thực hiện kiểm thử đơn vị tự động. Nó là dễ dàng hơn nhiều để mô phỏng này lên hơn đối tượng yêu cầu của ASP.Net.

+0

Đã thêm tiền thưởng ở đây là nó cho các nhà phát triển tương lai biết chính xác những gì mong đợi từ chuỗi truy vấn khi họ lần đầu tiên ngồi xuống với mã của bạn. –

+0

Có cảm ơn bạn đã nhận thấy điều đó. Đó chắc chắn là ý định. – 7wp

+0

+1 - một cách tuyệt vời để xử lý nó – nailitdown

8

Có một điều là bạn hiện không ghi lại các giá trị trống tại đây. Bạn có thể có một url như "http://example.com?someKey=&anotherKey=12345" và trong trường hợp này giá trị param "someKey" là "" (trống). Bạn có thể sử dụng string.IsNullOrEmpty() để kiểm tra cả hai trạng thái rỗng và rỗng.

Tôi cũng sẽ thay đổi "someKey" để được lưu trữ trong một biến. Bằng cách đó bạn không lặp lại các chuỗi chữ ở nhiều nơi. Nó làm cho điều này dễ dàng hơn để duy trì.

int val = 0; 
string myKey = "someKey"; 
if (!string.IsNullOrEmpty(Request.QueryString[myKey])) 
{ 
    val = int.Parse(Request.QueryString[myKey]); 
} 

Tôi hy vọng điều đó sẽ hữu ích!

Ian

+0

điều này có khả năng sẽ ném một ngoại lệ! –

+0

bạn chắc chắn muốn bao gồm xử lý lỗi. Đó là một cho phải không? :) –

+0

'int val = 0; string myKey = "someKey"; chuỗi strVal = HttpContext.Current.Request.QueryString [myKey]; if (! String.IsNullOrEmpty (strVal) &&! Int.TryParse (strVal, out val)) { val = 0; } ' – GFoley83

3

Viết một số loại của một phương pháp helper (thư viện) để xử lý nó ...

public static void GetInt(this NameValueCollection nvCol, string key, out int keyValue, int defaultValue) 
{ 
    if (string.IsNullOrEmpty(nvCol[key]) || !int.TryParse(nvCol[key], out keyValue)) 
     keyValue = defaultValue; 
} 

Hoặc một cái gì đó dọc theo những đường ...

+0

Nhưng trình lập trình sẽ phải biết loại chuỗi truy vấn dự kiến ​​sẽ được trả về dưới dạng. (Để biết chức năng nào cần gọi) Nếu bạn quấn nó bằng cách sử dụng một trình thu thập thuộc tính giống như trong câu trả lời tôi đã đưa ra, thì tất cả những gì bạn phải biết là tên của thuộc tính bạn đang theo sau. Intellisense sẽ làm phần còn lại. – 7wp

+0

Vâng, giống như lập trình viên sẽ phải biết loại chuỗi truy vấn dự kiến ​​để thiết lập thuộc tính. Giải pháp của tôi là dừng các câu lệnh "if" lặp đi lặp lại trên toàn bộ chương trình như được mô tả trong câu hỏi. Những gì họ làm với mã sau đó là tùy thuộc vào họ - hey, đặt nó vào một tài sản! – Charlino

+0

nhưng một khi tài sản được thiết lập, đó là nó thực hiện.các lập trình viên khác đến sau sẽ không phải đoán loại dữ liệu nào trong chuỗi truy vấn và xác thực cụ thể nào sẽ xảy ra. bạn có thể bọc tất cả những thứ đó lên trong tài sản. – 7wp

1

Chúng tôi đã được sử dụng hằng số để giữ cho tất cả các "lỏng lẻo" chìa khóa ở vị trí trung tâm:

public class Constants 
{ 
    public class QueryString 
    { 
    public const string PostID = "pid"; 
    public const string PostKey = "key"; 
    } 
    public class Cookie 
    { 
    public const string UserID = "mydomain.com-userid"; 
    } 
    public class Cache 
    { 
    public const string PagedPostList = "PagedPostList-{0}-{1}"; 
    } 
    public class Context 
    { 
    public const string PostID = "PostID"; 
    } 
    public class Security 
    { 
    public const RoleAdministrator = "Administrator"; 
    } 
} 

bằng cách đó, bạn dễ dàng truy cập vào các hằng số mà bạn cần với:

public void Index() 
{ 
    if (Request[Constants.QueryString.PostKey] == "eduncan911") 
    { 
    // do something 
    } 
} 

public object GetPostsFromCache(int postID, int userID) 
{ 
    String cacheKey = String.Format(
     Constants.Cache.PagedPostList 
     , userID 
     , postID); 
    return Cache[cacheKey] as IList<Post>; 
} 
0

Tôi có áp phích đề xuất phương pháp trợ giúp (tôi sẽ bình luận về anh ấy, nhưng vẫn chưa thể). Một người khác không đồng ý với anh ta về việc tạo ra các thuộc tính, nhưng câu trả lời của tôi là nó không xử lý một cách duyên dáng vấn đề kiểm tra null hoặc định dạng không hợp lệ, v.v. Nếu bạn có các phương thức trợ giúp, tất cả logic đó có thể được viết một lần và tập trung.

Nếu bạn có nhiều trang, việc thêm thuộc tính cho mỗi trang có thể mất nhiều thời gian hơn giá trị. Nhưng đó rõ ràng chỉ là một sở thích, do đó, cho mỗi của riêng mình.

Một điều thú vị mà bạn có thể cải thiện trên phương thức trợ giúp của người đăng bài khác là làm cho tham số ngoài thay thế tham số (thay đổi thành ref). Bằng cách đó bạn có thể đặt giá trị mặc định cho thuộc tính, trong trường hợp nó không được chuyển. Đôi khi bạn có thể muốn tham số tùy chọn, ví dụ - bạn có thể bắt đầu với một số giá trị mặc định cho những trường hợp thông số tùy chọn không được chuyển một cách rõ ràng (dễ dàng hơn giá trị mặc định được chuyển riêng trong). Bạn thậm chí có thể thêm một tham số boolean IsRequired ở cuối, và có nó ném một ngoại lệ nếu bool được đặt thành true và tham số không được chuyển. Điều đó có thể hữu ích trong nhiều trường hợp.

+0

Bạn không phải tạo thuộc tính trên mọi trang. Chỉ có một lớp duy nhất chứa tất cả các thuộc tính mà bạn mong muốn sử dụng. Sau đó, bạn có thể khởi tạo lớp đó trong các trang bạn đang sử dụng để truy cập các tham số truy vấn. – 7wp

+0

Vâng, giả sử rằng bạn có cùng một tham số chuỗi truy vấn trên mỗi trang. Trong một hệ thống lớn, bạn sẽ có một số lượng lớn các hệ thống khác nhau, giống như bạn có các tham số khác nhau với các phương thức khác nhau. Có vẻ như sự nhất quán là một điều tốt. – x4000

3

Đây là những gì tôi nghĩ ra. Nó sử dụng Generics để trả về một giá trị mạnh mẽ-gõ từ QueryString hoặc một giá trị mặc định tùy chọn nếu tham số không có trong các QueryString:

/// <summary> 
    /// Gets the given querystring parameter as a the specified value <see cref="Type"/> 
    /// </summary> 
    /// <typeparam name="T">The type to convert the querystring value to</typeparam> 
    /// <param name="name">Querystring parameter name</param> 
    /// <param name="defaultValue">Default value to return if parameter not found</param> 
    /// <returns>The value as the specified <see cref="Type"/>, or the default value if not found</returns> 
    public static T GetValueFromQueryString<T>(string name, T defaultValue) where T : struct 
    { 
     if (String.IsNullOrEmpty(name) || HttpContext.Current == null || HttpContext.Current.Request == null) 
      return defaultValue; 

     try 
     { 
      return (T)Convert.ChangeType(HttpContext.Current.Request.QueryString[name], typeof(T)); 
     } 
     catch 
     { 
      return defaultValue; 
     } 
    } 

    /// <summary> 
    /// Gets the given querystring parameter as a the specified value <see cref="Type"/> 
    /// </summary> 
    /// <typeparam name="T">The type to convert the querystring value to</typeparam> 
    /// <param name="name">Querystring parameter name</param> 
    /// <returns>The value as the specified <see cref="Type"/>, or the types default value if not found</returns> 
    public static T GetValueFromQueryString<T>(string name) where T : struct 
    { 
     return GetValueFromQueryString(name, default(T)); 
    } 

Kể từ khi viết bài này, tôi đã viết một thư viện lớp rất nhỏ cho các thao tác giá trị chuỗi truy vấn - xem https://github.com/DanDiplo/QueryString-Helper

+0

+1 cho sử dụng đơn giản của generics. – GFoley83

+0

Bắt: 'Loại 'chuỗi' phải là một kiểu giá trị không nullable để sử dụng nó như tham số 'T' trong chung ...' –

+0

@PierreLebon Strings là các loại giá trị, do đó ràng buộc cấu trúc chung sẽ không với họ. Nhưng bạn không cần phải chuyển đổi chúng, vì giá trị đã là một chuỗi. Vì bài đăng này tôi đã viết một thư viện nhỏ - hãy xem https://github.com/DanDiplo/QueryString-Helper - điều đó sẽ giúp bạn. –

1

Theo tôi, cách tốt nhất để có được chuỗi truy vấn giá trị như sau:
Nếu chuỗi truy vấn không tìm thấy thì giá trị của val sẽ 0.

int val = 0; 
int.TryParse(Request.QueryString["someKey"], out val); 
Các vấn đề liên quan