Web API サービスを作成しました。私がやろうとしているのは、その API 関数、つまり SaveSession(string data) をコード ビハインド ボタン クリックから呼び出し、フォーム コレクション データ全体をパラメーターとして文字列形式で渡すことです。webclient.uploadstring(url,string); を介して API の uri を呼び出すと、Web サービスを呼び出していますが、パラメーターが渡されていません。助けてください。
質問する
3999 次
1 に答える
3
文字列を受け入れるコントローラー アクション メソッドを使用する代わりに、コントローラーに投稿されたフォーム URL エンコードされたコンテンツを読み取ることができます。
以下の例では、SessionController は、form-url でエンコードされたコンテンツの POST を受け入れる SaveSession() メソッドを公開し、セッション データを KeyValuePair インスタンスのコレクションとして読み取ります。
サンプル クライアントは、キーと値のペアのリストを作成し、HttpClient インスタンスを使用して FormUrlEncodedContent を Web API コントローラー メソッドにポストします。
セッションコントローラーの例:
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
namespace MvcApplication1.Controllers
{
public class SessionController : ApiController
{
/// <summary>
/// Saves specified the session data.
/// </summary>
/// <returns>
/// A <see cref="HttpResponseMessage"/> that represents the response to the requested operation.
/// </returns>
[HttpPost()]
public HttpResponseMessage SaveSession()
{
// Ensure content is form-url-encoded
if(!IsFormUrlEncodedContent(this.Request.Content))
{
return this.Request.CreateResponse(HttpStatusCode.BadRequest);
}
// Read content as a collection of key value pairs
foreach (var parameter in ReadAsFormUrlEncodedContentAsync(this.Request.Content).Result)
{
var key = parameter.Key;
var value = parameter.Value;
if(!String.IsNullOrEmpty(key))
{
// Do some work to persist session data here
}
}
return this.Request.CreateResponse(HttpStatusCode.OK);
}
/// <summary>
/// Determines whether the specified content is form URL encoded content.
/// </summary>
/// <param name="content">
/// The type that the <see cref="IsFormUrlEncodedContent(HttpContent)"/> method operates on.
/// </param>
/// <returns>
/// <see langword="true"/> if the specified content is form URL encoded content; otherwise, <see langword="false"/>.
/// </returns>
public static bool IsFormUrlEncodedContent(HttpContent content)
{
if (content == null || content.Headers == null)
{
return false;
}
return String.Equals(
content.Headers.ContentType.MediaType,
FormUrlEncodedMediaTypeFormatter.DefaultMediaType.MediaType,
StringComparison.OrdinalIgnoreCase
);
}
/// <summary>
/// Write the HTTP content to a collection of name/value pairs as an asynchronous operation.
/// </summary>
/// <param name="content">
/// The type that the <see cref="ReadAsFormUrlEncodedContentAsync(HttpContent)"/> method operates on.
/// </param>
/// <returns>The <see cref="Task"/> object representing the asynchronous operation.</returns>
/// <remarks>
/// The <see cref="ReadAsFormUrlEncodedContentAsync(HttpContent, CancellationToken)"/> method
/// uses the <see cref="Encoding.UTF8"/> format (or the character encoding of the document, if specified)
/// to parse the content. URL-encoded characters are decoded and multiple occurrences of the same form
/// parameter are listed as a single entry with a comma separating each value.
/// </remarks>
public static Task<IEnumerable<KeyValuePair<string, string>>> ReadAsFormUrlEncodedContentAsync(HttpContent content)
{
return ReadAsFormUrlEncodedContentAsync(content, CancellationToken.None);
}
/// <summary>
/// Write the HTTP content to a collection of name/value pairs as an asynchronous operation.
/// </summary>
/// <param name="content">
/// The type that the <see cref="ReadAsFormUrlEncodedContentAsync(HttpContent, CancellationToken)"/> method operates on.
/// </param>
/// <param name="cancellationToken">
/// The cancellation token used to propagate notification that the operation should be canceled.
/// </param>
/// <returns>The <see cref="Task"/> object representing the asynchronous operation.</returns>
/// <remarks>
/// The <see cref="ReadAsFormUrlEncodedContentAsync(HttpContent, CancellationToken)"/> method
/// uses the <see cref="Encoding.UTF8"/> format (or the character encoding of the document, if specified)
/// to parse the content. URL-encoded characters are decoded and multiple occurrences of the same form
/// parameter are listed as a single entry with a comma separating each value.
/// </remarks>
public static Task<IEnumerable<KeyValuePair<string, string>>> ReadAsFormUrlEncodedContentAsync(HttpContent content, CancellationToken cancellationToken)
{
return Task.Factory.StartNew<IEnumerable<KeyValuePair<string, string>>>(
(object state) =>
{
var result = new List<KeyValuePair<string, string>>();
var httpContent = state as HttpContent;
if (httpContent != null)
{
var encoding = Encoding.UTF8;
var charSet = httpContent.Headers.ContentType.CharSet;
if (!String.IsNullOrEmpty(charSet))
{
try
{
encoding = Encoding.GetEncoding(charSet);
}
catch (ArgumentException)
{
encoding = Encoding.UTF8;
}
}
NameValueCollection parameters = null;
using (var reader = new StreamReader(httpContent.ReadAsStreamAsync().Result, encoding))
{
parameters = HttpUtility.ParseQueryString(reader.ReadToEnd(), encoding);
}
if (parameters != null)
{
foreach(var key in parameters.AllKeys)
{
result.Add(
new KeyValuePair<string, string>(key, parameters[key])
);
}
}
}
return result;
},
content,
cancellationToken
);
}
}
}
呼び出し元クライアントの例:
using System;
using System.Collections.Generic;
using System.Net.Http;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
using (var client = new HttpClient())
{
// Initialize HTTP client
client.BaseAddress = new Uri("http://localhost:26242/api/", UriKind.Absolute);
client.Timeout = TimeSpan.FromSeconds(10);
// Build session data to send
var values = new List<KeyValuePair<string, string>>();
values.Add(new KeyValuePair<string, string>("Item1", "Value1"));
values.Add(new KeyValuePair<string, string>("Item2", "Value2"));
values.Add(new KeyValuePair<string, string>("Item3", "Value3"));
// Send session data via POST using form-url-encoded content
using (var content = new FormUrlEncodedContent(values))
{
using (var response = client.PostAsync("session", content).Result)
{
Console.WriteLine(response.StatusCode);
}
}
}
}
}
}
通常、IsFormUrlEncodedContentおよびReadAsFormUrlEncodedContentAsyncメソッドを HttpContent の拡張メソッドとして使用しますが、この例の目的のためにそれらをコントローラーに配置しました。
于 2012-10-18T16:54:04.993 に答える