3

.net で WebAPI を作成しました (初めて)。この API を使用して db からオブジェクトを取得したり、db をクエリしたりするのは簡単です。新しいものは何もありません

しかし、この webapi を使用してオブジェクトを保存する方法を知りたいですか?

webapi と通信するクリネット アプリケーション (タブレット、電話、PC) があります。私のアプリケーションから、ユーザー ニュースを保存する可能性があります。今度はそれを db に保存する必要があります。Azure SQL を使用しています。このオブジェクトを API に渡して保存するにはどうすればよいですか?

アプリケーションには C#/XAML を使用し、WebAPI には .NET を使用します

私はこのコードを試しています:

HttpClient httpClient = new HttpClient();
        String u = this.apiUrl + "sd/Localization/insert";
        Uri uri = new Uri(u);
        HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, uri);

しかし、オブジェクトを送信する方法がわかりませんか? シリアル化する必要がありますか?もしそうなら、郵送で送る方法を教えてください。

// アップデート

これを構築しました

        HttpClient httpClient = new HttpClient();
        String u = this.apiUrl + "sd/Localization/insert";
        Uri uri = new Uri(u);
        HttpRequestMessage httpRequestMessage = new HttpRequestMessage(HttpMethod.Post, uri);
        httpRequestMessage.Content = new StringContent("{'Name':'Foo', 'Surname':'Bar'}");
        await httpClient.PostAsync(uri, httpRequestMessage.Content);

しかし、私のAPIでは変数はnullです

これは私のAPIのコードです

    // POST sd/Localization/insert
    public void Post(string test)
    {
        Console.WriteLine(test);
    }

「テスト」変数がヌルです。私は何を間違っていますか?

// 更新 2

        using (HttpClient httpClient = new HttpClient())
        {
            String u = this.apiUrl + "sd/Localization/insert";
            Uri uri = new Uri(u);
            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uri)
            {
                Method = HttpMethod.Post,
                Content = new StringContent("my own test string")
            };

            await httpClient.PostAsync(uri, request.Content);
        }

ルーティング構成

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "sd/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

すべての回答の後、私はこれを作成しましたが、それでも API のパラメーターで null を取得します。間違いはどこですか?

4

8 に答える 8

6

WebAPI は、送信されたデータを解析して .NET オブジェクトに変換するのに非常に優れています

私は WebAPI で C# クライアントを使用することに慣れていませんが、次のことを試してみます。

var client = new HttpClient();
client.PostAsJsonAsync<YourObjectType>("uri", yourObject);

System.Net.Http注: これには、(同じ名前のアセンブリから) と (同じ名前のアセンブリから)を使用する必要がありますSystem.Net.Http.Formatting

于 2012-07-27T17:22:03.120 に答える
3

クラスには、 (抽象クラス) の型であるという名前のHttpRequestMessageプロパティがあります。そこにリクエストボディを設定できます。たとえば、JSON コンテンツをそこに設定してから、API に送信できます。ContentHttpContent

HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, uri) { 

    Content = new StringContent("{'Name':'Foo', 'Surname':'Bar'}")
};

フォーマット機能を使用して、CLR オブジェクトをObjectContentFormatter に提供し、シリアル化を委任することもできます。

HttpClient と Web API に関するサンプルが多数あります: http://blogs.msdn.com/b/henrikn/archive/2012/07/20/asp-net-web-api-sample-on-codeplex.aspx

于 2012-07-27T22:49:42.013 に答える
3

次のような POST 操作をサポートするアクション メソッドが Web API コントローラーにあるとします。

[HttpPost()]
public HttpResponseMessage Post(YourObjectType value)
{
    try
    {

        var result      = this.Repository.Add(value);

        var response = this.Request.CreateResponse<YourObjectType>(HttpStatusCode.Created, result);

        if (result != null)
        {
            var uriString               = this.Url.Route(null, new { id = result.Id });
            response.Headers.Location   = new Uri(this.Request.RequestUri, new Uri(uriString, UriKind.Relative));
        }

        return response;
    }
    catch (ArgumentNullException argumentNullException)
    {
        throw new HttpResponseException(
            new HttpResponseMessage(HttpStatusCode.BadRequest)
            {
                ReasonPhrase    = argumentNullException.Message.Replace(Environment.NewLine, String.Empty)
            }
        );
    }
}

HttpClient を使用して、オブジェクトを JSON にシリアル化し、コンテンツをコントローラー メソッドに POST できます。

using (var client = new HttpClient())
{
    client.BaseAddress  = baseAddress;
    client.Timeout      = timeout;

    using (var response = client.PostAsJsonAsync<YourObjectType>("controller_name", yourObject).Result)
    {
        if (!response.IsSuccessStatusCode)
        {
            // throw an appropriate exception
        }

        result  = response.Content.ReadAsAsync<YourObjectType>().Result;
    }
}

CRUD 操作をサポートする Web API の作成も参照することをお勧めします。これは、説明しているシナリオ、特にリソースの作成セクションをカバーしています。

于 2012-07-27T23:12:52.653 に答える
1

コメントではなく回答としてこれを投稿しているので、後で議論をグループ化できる解決策を見つけたと思います。

このようにリクエストを送信すると

using(HttpClient client = new HttpClient()) {
    await client.PostAsync(uri, new StringContent("my own string");
}

私のwebapiでそれを取得できるよりも

await Request.Content.ReadAsStringAsync();

IMOこれは完璧な解決策ではありませんが、少なくとも私は追跡しています。関数定義からのパラメータは、POSTリクエストを送信した場合でもURLに含まれている場合にのみ取得できることがわかります。

おそらく、このソリューションは、Stringよりも複雑なオブジェクトを使用する場合にも機能します(まだチェックしていません)。

誰かからの考え。これは良い解決策だと思いますか?

于 2012-07-29T14:39:34.543 に答える
1

これがあなたが探しているものであることを願っています。

任意のオブジェクトを受け入れてクライアント側に投稿する一般的な投稿を作成しました

public async Task<HttpResponseMessage> Post<T>(string requestUri, T newObject) where T : class
{
  using (var client = new HttpClient())
  {
     client.BaseAddress = this.HttpClientAddress;
     client.DefaultRequestHeaders.Accept.Clear();
     client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
     var content = JsonConvert.SerializeObject(newObject, this.JsonSerializerSettings);
     var clientAsync = await client.PostAsync(requestUri, new StringContent(content, Encoding.UTF8, "application/json"));
     clientAsync.EnsureSuccessStatusCode();

     return clientAsync;
   }
}

これへの呼び出しは次のように簡単になります

public async Task<int> PostPerson(Models.Person person)
{
  //call to the generic post 
  var response = await this.Post("People", person);

  //get the new id from Uri api/People/6 <-- this is generated in the response after successful post
  var st =  response.Headers.Location.Segments[3];

  //do whatever you want with the id
  return response.IsSuccessStatusCode ? JsonConvert.DeserializeObject<int>(st) : 0;
}

また、ユースケースで必要な場合は、ポスト後に ReadAsStringAsync() を使用してオブジェクトを読み取ることができます。


サーバ側

// POST: api/People
  public IHttpActionResult Post(Models.Person personDto)
    {

        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        var person = new Entities.Person
                     {
                             FirstName = personDto.FirstName,
                             LastName = personDto.LastName,
                             DateOfBirth = personDto.DateOfBirth,
                             PreferedLanguage = personDto.PreferedLanguage

                     };
        _db.Persons.Add(person);
        _db.SaveChanges();
        return CreatedAtRoute("DefaultApi", new { id = person.Id }, personDto);
    }
于 2014-10-20T18:05:53.730 に答える
0

これが私のやり方です。うまくいきました。お役に立てば幸いです。Fisrt:必要なライブラリはすべてです。nugetからダウンロードできます。

Newtonsoft.Json の使用; Newtonsoft.Json.Linq を使用します。

クライアント :

HttpClient client = new HttpClient();

//this is url to your API server.in local.You must change when u pushlish on real host
Uri uri = new Uri("http://localhost/");
client.BaseAddress = uri;

//declared a JArray to save object 
JArray listvideoFromUser = new JArray();

//sample is video object
VideoModels newvideo = new VideoModels();

//set info to new object..id/name...etc.
newvideo._videoId = txtID.Text.Trim();

//add to jArray
listvideoFromUser.Add(JsonConvert.SerializeObject(newvideo));

//Request to server
//"api/Video/AddNewVideo" is router of API .you must change with your router
HttpResponseMessage response =client.PostAsJsonAsync("api/Video/AddNewVideo", listvideoFromUser).Result;
if (response.IsSuccessStatusCode){
    //show status process
     txtstatus.Text=response.StatusCode.ToString();
}
else{
    //show status process
    txtstatus.Text=response.StatusCode.ToString();
}  

サーバ側:

[Route("api/Video/AddNewVideo")]
[System.Web.Http.HttpPost]
public HttpResponseMessage AddNewVideo(JArray listvideoFromUser){
    if (listvideoFromUser.Count > 0){
        //DeserializeObject: that object you sent from client to server side. 
        //Note:VideoModels is class object same as model of client side
        VideoModels video = JsonConvert.DeserializeObject<VideoModels>(listvideoFromUser[0].ToString());

        //that is just method to save database
        Datacommons.AddNewVideo(video);

        //show status for client
        HttpResponseMessage response = new HttpResponseMessage { StatusCode = HttpStatusCode.Created };
        return response;
    }
    else{
        HttpResponseMessage response = new HttpResponseMessage { StatusCode = HttpStatusCode.InternalServerError };
        return response;
    }
}

すべて完了 !

于 2014-06-30T04:13:54.343 に答える
0

私は HttpClient には詳しくありませんが (.NET 4.5 だと思います)、WebAPI の背後にある概念は標準的な RESTful 構造を使用しています。WebAPI 経由でオブジェクトを挿入する場合は、サービスに POST リクエストを送信する必要があります。オブジェクトのコンテンツをリクエストの BODY に入れる必要があります。

于 2012-07-27T17:27:36.543 に答える