ASP.NET:URI 处理

发布于 2024-08-11 08:49:16 字数 528 浏览 7 评论 0原文

我正在编写一个方法,假设给定 1hello 应该返回 http://something.com/?something=1&hello=en

可以很容易地将其组合在一起,但是 ASP.NET 3.5 为构建 URI 提供了什么抽象功能?我想要这样的东西:

URI uri = new URI("~/Hello.aspx"); // E.g. ResolveUrl is used here
uri.QueryString.Set("something", "1");
uri.QueryString.Set("hello", "en");
return uri.ToString(); // /Hello.aspx?something=1&hello=en

我发现 Uri 类听起来非常相关,但我找不到任何真正执行上述操作的东西。有什么想法吗?

(就其价值而言,参数的顺序对我来说并不重要。)

I'm writing a method which, let's say, given 1 and hello should return http://something.com/?something=1&hello=en.

I could hack this together pretty easily, but what abstraction functionality does ASP.NET 3.5 provide for building URIs? I'd like something like:

URI uri = new URI("~/Hello.aspx"); // E.g. ResolveUrl is used here
uri.QueryString.Set("something", "1");
uri.QueryString.Set("hello", "en");
return uri.ToString(); // /Hello.aspx?something=1&hello=en

I found the Uri class which sounds highly relevant, but I can't find anything which does the above really. Any ideas?

(For what it's worth, the order of the parameters doesn't matter to me.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

春花秋月 2024-08-18 08:49:16

编辑以纠正大量错误的代码

基于这个答案对于类似的问题,您可以轻松地执行以下操作:

UriBuilder ub = new UriBuilder();

// You might want to take more care here, and set the host, scheme and port too
ub.Path = ResolveUrl("~/hello.aspx"); // Assumes we're on a page or control.

// Using var gets around internal nature of HttpValueCollection
var coll = HttpUtility.ParseQueryString(string.Empty);

coll["something"] = "1";
coll["hello"] = "en";

ub.Query = coll.ToString();
return ub.ToString();
// This returned the following on the VS development server:
// http://localhost/Hello.aspx?something=1&hello=en

这也将对集合进行urlencode,因此:

coll["Something"] = "1";
coll["hello"] = "en&that";

将输出:

Something=1&hello=en%26that 

Edited to correct massively incorrect code

Based on this answer to a similar question you could easily do something like:

UriBuilder ub = new UriBuilder();

// You might want to take more care here, and set the host, scheme and port too
ub.Path = ResolveUrl("~/hello.aspx"); // Assumes we're on a page or control.

// Using var gets around internal nature of HttpValueCollection
var coll = HttpUtility.ParseQueryString(string.Empty);

coll["something"] = "1";
coll["hello"] = "en";

ub.Query = coll.ToString();
return ub.ToString();
// This returned the following on the VS development server:
// http://localhost/Hello.aspx?something=1&hello=en

This will also urlencode the collection, so:

coll["Something"] = "1";
coll["hello"] = "en&that";

Will output:

Something=1&hello=en%26that 
庆幸我还是我 2024-08-18 08:49:16

到目前为止我对这里一无所知。所以每个人都有自己的实现。

示例来自 LinqToTwitter

    internal static string BuildQueryString(IEnumerable<KeyValuePair<string, string>> parameters)
    {
        if (parameters == null)
        {
            throw new ArgumentNullException("parameters");
        }

        StringBuilder builder = new StringBuilder();
        foreach (var pair in parameters.Where(p => !string.IsNullOrEmpty(p.Value)))
        {
            if (builder.Length > 0)
            {
                builder.Append("&");
            }

            builder.Append(Uri.EscapeDataString(pair.Key));
            builder.Append("=");
            builder.Append(Uri.EscapeDataString(pair.Value));
        }

        return builder.ToString();
    }

更新:

您还可以创建扩展方法:

public static UriBuilder AddArgument(this UriBuilder builder, string key, string value)
{
 #region Contract

 Contract.Requires(builder != null);
 Contract.Requires(key != null);
 Contract.Requires(value != null);

 #endregion

 var query = builder.Query;

 if (query.Length > 0)
 {
      query = query.Substring(1) + "&";
 } 

 query += Uri.EscapeDataString(key) + "="
      + Uri.EscapeDataString(value);

 builder.Query = query;

 return builder;
}

和用法:

var b = new UriBuilder();
b.AddArgument("test", "test");

请注意,这里的所有内容都未经测试。

As far I know nothing here. So everybody has its own implementation.

Example from LinqToTwitter.

    internal static string BuildQueryString(IEnumerable<KeyValuePair<string, string>> parameters)
    {
        if (parameters == null)
        {
            throw new ArgumentNullException("parameters");
        }

        StringBuilder builder = new StringBuilder();
        foreach (var pair in parameters.Where(p => !string.IsNullOrEmpty(p.Value)))
        {
            if (builder.Length > 0)
            {
                builder.Append("&");
            }

            builder.Append(Uri.EscapeDataString(pair.Key));
            builder.Append("=");
            builder.Append(Uri.EscapeDataString(pair.Value));
        }

        return builder.ToString();
    }

UPDATE:

You can also create extension method:

public static UriBuilder AddArgument(this UriBuilder builder, string key, string value)
{
 #region Contract

 Contract.Requires(builder != null);
 Contract.Requires(key != null);
 Contract.Requires(value != null);

 #endregion

 var query = builder.Query;

 if (query.Length > 0)
 {
      query = query.Substring(1) + "&";
 } 

 query += Uri.EscapeDataString(key) + "="
      + Uri.EscapeDataString(value);

 builder.Query = query;

 return builder;
}

And usage:

var b = new UriBuilder();
b.AddArgument("test", "test");

Please note that everything here is untested.

新雨望断虹 2024-08-18 08:49:16

只是合并答案=>

public static class UriBuilderExtensions
{
    public static void AddQueryArgument(this UriBuilder b, string key, string value)
    {
        key = Uri.EscapeDataString(key);
        value = Uri.EscapeDataString(value);

        var x = HttpUtility.ParseQueryString(b.Query);
        if (x.AllKeys.Contains(key)) throw new ArgumentNullException
                ("Key '{0}' already exists!".FormatWith(key));
        x.Add(key, value);
        b.Query = x.ToString();
    }

    public static void EditQueryArgument(this UriBuilder b, string key, string value)
    {
        key = Uri.EscapeDataString(key);
        value = Uri.EscapeDataString(value);

        var x = HttpUtility.ParseQueryString(b.Query);
        if (x.AllKeys.Contains(key))
            x[key] = value;
        else throw new ArgumentNullException
                ("Key '{0}' does not exists!".FormatWith(key));
        b.Query = x.ToString();
    }

    public static void AddOrEditQueryArgument(this UriBuilder b, string key, string value)
    {
        key = Uri.EscapeDataString(key);
        value = Uri.EscapeDataString(value);

        var x = HttpUtility.ParseQueryString(b.Query);
        if (x.AllKeys.Contains(key))
            x[key] = value;
        else
            x.Add(key, value);
        b.Query = x.ToString();
    }

    public static void DeleteQueryArgument(this UriBuilder b, string key)
    {
        key = Uri.EscapeDataString(key);
        var x = HttpUtility.ParseQueryString(b.Query);
        if (x.AllKeys.Contains(key))
            x.Remove(key);
        b.Query = x.ToString();
    }
}

半成品代码。但应该工作得足够好。

Just combined answers=>

public static class UriBuilderExtensions
{
    public static void AddQueryArgument(this UriBuilder b, string key, string value)
    {
        key = Uri.EscapeDataString(key);
        value = Uri.EscapeDataString(value);

        var x = HttpUtility.ParseQueryString(b.Query);
        if (x.AllKeys.Contains(key)) throw new ArgumentNullException
                ("Key '{0}' already exists!".FormatWith(key));
        x.Add(key, value);
        b.Query = x.ToString();
    }

    public static void EditQueryArgument(this UriBuilder b, string key, string value)
    {
        key = Uri.EscapeDataString(key);
        value = Uri.EscapeDataString(value);

        var x = HttpUtility.ParseQueryString(b.Query);
        if (x.AllKeys.Contains(key))
            x[key] = value;
        else throw new ArgumentNullException
                ("Key '{0}' does not exists!".FormatWith(key));
        b.Query = x.ToString();
    }

    public static void AddOrEditQueryArgument(this UriBuilder b, string key, string value)
    {
        key = Uri.EscapeDataString(key);
        value = Uri.EscapeDataString(value);

        var x = HttpUtility.ParseQueryString(b.Query);
        if (x.AllKeys.Contains(key))
            x[key] = value;
        else
            x.Add(key, value);
        b.Query = x.ToString();
    }

    public static void DeleteQueryArgument(this UriBuilder b, string key)
    {
        key = Uri.EscapeDataString(key);
        var x = HttpUtility.ParseQueryString(b.Query);
        if (x.AllKeys.Contains(key))
            x.Remove(key);
        b.Query = x.ToString();
    }
}

Half baked code. But should work well enough.

孤蝉 2024-08-18 08:49:16

还有 UriBuilder

There's also the UriBuilder class

紫竹語嫣☆ 2024-08-18 08:49:16

这可能会吸引你——最近在工作中我正在寻找一种“输入”常用的 URL 查询字符串变量的方法,因此开发了这个接口:

   'Represent a named parameter that is passed from page-to-page via a range of methods- query strings, HTTP contexts, cookies, session, etc.
Public Interface INamedParam

    'A key that uniquely identfies this parameter in any HTTP value collection (query string, context, session, etc.)
    ReadOnly Property Key() As String

    'The default value of the paramter.
    ReadOnly Property DefaultValue() As Object

End Interface

然后你可以实现这个接口来描述一个查询字符串参数,这样的实现您的“Hello”参数可能如下所示:

Public Class HelloParam
    Implements INamedParam

    Public ReadOnly Property DefaultValue() As Object Implements INamedParam.DefaultValue
        Get
            Return "0"
        End Get
    End Property

    Public ReadOnly Property Key() As String Implements INamedParam.Key
        Get
            Return "hello"
        End Get
    End Property
End Class

我开发了一个小型(非常非常基本)类来帮助使用这些强类型参数构建 URL:

Public Class ParametrizedHttpUrlBuilder

    Private _RelativePath As String
    Private _QueryString As String

    Sub New(ByVal relativePath As String)
        _RelativePath = relativePath
        _QueryString = ""
    End Sub

    Public Sub AddQueryParameterValue(ByVal param As INamedParam, ByVal value As Object)
        Dim sb As New Text.StringBuilder(30)
        If _QueryString.Length > 0 Then
            sb.Append("&")
        End If
        sb.AppendFormat("{0}={1}", param.Key, value.ToString())
        _QueryString &= sb.ToString()
    End Sub

    Public Property RelativePath() As String
        Get
            Return _RelativePath
        End Get
        Set(ByVal value As String)
            If value Is Nothing Then
                _RelativePath = ""
            End If
            _RelativePath = value
        End Set
    End Property

    Public ReadOnly Property Query() As String
        Get
            Return _QueryString
        End Get
    End Property

    Public ReadOnly Property PathAndQuery() As String
        Get
            Return _RelativePath & "?" & _QueryString
        End Get
    End Property

End Class

This is something that might appeal to you- recently at work I was looking at a way to "type" commonly used URL query string variables and so developed this interface:

   'Represent a named parameter that is passed from page-to-page via a range of methods- query strings, HTTP contexts, cookies, session, etc.
Public Interface INamedParam

    'A key that uniquely identfies this parameter in any HTTP value collection (query string, context, session, etc.)
    ReadOnly Property Key() As String

    'The default value of the paramter.
    ReadOnly Property DefaultValue() As Object

End Interface

You can then implement this interface to describe a query string parameter, such an implementation for your "Hello" param might look like this:

Public Class HelloParam
    Implements INamedParam

    Public ReadOnly Property DefaultValue() As Object Implements INamedParam.DefaultValue
        Get
            Return "0"
        End Get
    End Property

    Public ReadOnly Property Key() As String Implements INamedParam.Key
        Get
            Return "hello"
        End Get
    End Property
End Class

I developed a small (and very, very basic) class to help build URLs using these strongly typed parameters:

Public Class ParametrizedHttpUrlBuilder

    Private _RelativePath As String
    Private _QueryString As String

    Sub New(ByVal relativePath As String)
        _RelativePath = relativePath
        _QueryString = ""
    End Sub

    Public Sub AddQueryParameterValue(ByVal param As INamedParam, ByVal value As Object)
        Dim sb As New Text.StringBuilder(30)
        If _QueryString.Length > 0 Then
            sb.Append("&")
        End If
        sb.AppendFormat("{0}={1}", param.Key, value.ToString())
        _QueryString &= sb.ToString()
    End Sub

    Public Property RelativePath() As String
        Get
            Return _RelativePath
        End Get
        Set(ByVal value As String)
            If value Is Nothing Then
                _RelativePath = ""
            End If
            _RelativePath = value
        End Set
    End Property

    Public ReadOnly Property Query() As String
        Get
            Return _QueryString
        End Get
    End Property

    Public ReadOnly Property PathAndQuery() As String
        Get
            Return _RelativePath & "?" & _QueryString
        End Get
    End Property

End Class
影子的影子 2024-08-18 08:49:16

这是我的版本(需要在 Select 上调用 .NET4 或 ToArray() )

var items = new Dictionary<string,string> { { "Name", "Will" }, { "Age", "99" }};

String query = String.Join("&", items.Select(i => String.Concat(i.Key, "=", i.Value)));

我认为使用 Dictionary 可能意味着可以对项目进行重新排序,但这实际上似乎并没有在此处的实验中发生 - 不确定那是什么意思。

Here's my version (needs .NET4 or a ToArray() call on the Select)

var items = new Dictionary<string,string> { { "Name", "Will" }, { "Age", "99" }};

String query = String.Join("&", items.Select(i => String.Concat(i.Key, "=", i.Value)));

I thought the use of Dictionary might mean the items can get reordered, but that doesn't actually seem to be happening in experiments here - not sure what that's about.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文