2015-10-27 2 views
2

Я использую web.api 2.2, клиент посылает данные в этом стиле:Web.Api принимает форму параметра значение

data={"kind": "Conversation", "tags": [], "items": [{"body": "hi there", "timestamp": "1445958749.284379", "kind": "MessageToOperator", "nickname": "United Kingdom (Rickmansworth) #5043", "visitor_nickname": "United Kingdom (Rickmansworth) #5043"}, {"body": "my name is amel and i am testing olark", "timestamp": "1445958753.320339", "kind": "MessageToOperator", "nickname": "United Kingdom (Rickmansworth) #5043", "visitor_nickname": "United Kingdom (Rickmansworth) #5043"}, {"body": "hi amel i am jessica", "timestamp": "1445958763.486881", "kind": "MessageToVisitor", "nickname": "Jessica Wood ", "operatorId": "744399"}, {"body": "ok im back", "timestamp": "1445959002.452643", "kind": "MessageToOperator", "nickname": "United Kingdom (Rickmansworth) #5043", "visitor_nickname": "United Kingdom (Rickmansworth) #5043"}, {"body": "hello there", "timestamp": "1445959059.642775", "kind": "MessageToVisitor", "nickname": "Jessica Wood ", "operatorId": "744399"}, {"body": "i ma here", "timestamp": "1445959066.829973", "kind": "MessageToOperator", "nickname": "United Kingdom (Rickmansworth) #5043", "visitor_nickname": "United Kingdom (Rickmansworth) #5043"}, {"body": "test", "timestamp": "1445959885.173931", "kind": "MessageToOperator", "nickname": "United Kingdom (Rickmansworth) #5043", "visitor_nickname": "United Kingdom (Rickmansworth) #5043"}, {"body": "hi there", "timestamp": "1445959894.323173", "kind": "MessageToVisitor", "nickname": "Jessica Wood ", "operatorId": "744399"}, {"body": "how are you doing", "timestamp": "1445959900.186131", "kind": "MessageToVisitor", "nickname": "Jessica Wood ", "operatorId": "744399"}, {"body": "Testing olark", "timestamp": "1445960829.592606", "kind": "MessageToOperator", "nickname": "United Kingdom (Rickmansworth) 
#5043", "visitor_nickname": "United Kingdom (Rickmansworth) #5043"}, {"body": "Hello there", "timestamp": "1445960834.471775", "kind": "MessageToVisitor", "nickname": "Jessica Wood ", "operatorId": "744399"}], "operators": {"744399": {"username": "winlotto.com", "emailAddress": "[email protected]", "kind": "Operator", "nickname": "Jessica Wood ", "id": "744399"}}, "visitor": {"city": "Rickmansworth", "kind": "Visitor", "conversationBeginPage": "http://www.winnlotto.com/", "countryCode": "GB", "ip": "195.110.84.183", "chat_feedback": {}, "operatingSystem": "Windows", "emailAddress": "", "country": "United Kingdom", "organization": "COLT Technology Services Group Limited", "fullName": "United Kingdom (Rickmansworth) #5043", "id": "tTOFv5oa0muGA16s7281C5P1GOAsjJA4", "browser": "Firefox 41.0"}, "isLead": "true", "id": "rWpAfF48ITi4y6DU7281C2R1GP0FHVJ3"} 

Смотреть это данные = в начале. Они отправляют json в качестве параметра данных в значение, что смешно, но я не знаю, как принять его в web.api-контроллере. Я попробовал строковые данные [FromBody], он, похоже, не работает.

Это мое действие, которое принимает это:

[Route("Index")] 
     [HttpPost] 
     public IHttpActionResult Index([FromBody] string data) 
     { 
      var body = string.Empty; 
      using (var reader = new StreamReader(Request.Content.ReadAsStreamAsync().Result)) 
      { 
       reader.BaseStream.Seek(0, SeekOrigin.Begin); 
       body = reader.ReadToEnd(); 
      } 

      return Ok(); 
     } 

Edit: То, что я это упаковали модель с полем данных строки и возвращает JSON в строке:

public class ServiceModel 
{ 
    public string data { get; set; } 
} 

Является ли это правильный путь для получения параметров формы?

+1

делает запрос достигнет сервера? или нет ? проверьте с помощью скрипача –

+0

Хотя вы не упомянули, что вы получаете в «тело» с чтением Стрим? –

+0

он достигает сервера. поэтому они в основном не отправляют json, а форму. поэтому на данный момент я создал модель с 3 –

ответ

0

Что вы хотите сделать, это создать модель, представляющую объект, который вы ожидаете. Вызывающий вызовет объект, отформатированный как json, Web API может автоматически десериализовать это на объект C#. В этом объекте вы можете легко сделать валидацию на модели, сделать что-то с этими данными и вернуть результат, который также можно автоматически десериализовать обратно в json (если это то, чего хочет вызывающий).

Я рекомендую вам изучать/читать основные концепции веб-API, поскольку это довольно простой. То, что вы не хотите, - это начать реализацию и поддержку решения, которое вы не полностью понимаете. Там есть много отличных ресурсов, если вы предпочитаете руки, а затем ищите некоторые учебные пособия, если вы предпочитаете более тонкие детали, тогда начните с книги или углубленного объяснения.

Вот несколько кодов, которые помогут вам начать работу. Классы основаны на JSON, который вы предоставили.

public class Item { 
    public string Body {get;set;} 
    public string TimeStamp {get;set;} 
    // rest of properties 
} 
public class SomeObject { 
    public string Kind {get;set;} 
    public string[] Tags {get;set;} 
    public Item[] Items {get;set;} 
    // rest of properties 
} 


// your method in the web api controller 
public IHttpActionResult Index([FromBody] SomeObject myObject) { 
// your validation and action code here and then return some result 
} 

// update your web api configuration registration to convert camel case json to pascal cased c# and back again 
public static class WebApiConfig { 
     public static void Register(HttpConfiguration config) 
     { 
      // makes all WebAPI json results lower case 
      var json = GlobalConfiguration.Configuration.Formatters.JsonFormatter; 
      json.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 
// rest of code 
0

Возможно, model binder - лучший способ пойти.

Например, предположим, давайте у меня есть этот контроллер:

[RoutePrefix("bindingTest")] 
public class BindingTestController : ApiController 
{ 
    [Route("")] 
    [HttpPost] 
    public HttpResponseMessage Post([FromBody]Product data) 
    { 
     return Request.CreateResponse(); 
    } 
} 

Но клиент посылает мне данные в виде-urlencoded формате с данными JSON в параметре data, как вы указали:

client.PostAsync(url, new FormUrlEncodedContent(new[] 
{ 
    new KeyValuePair<String, String>("data", "{'Id': 0,'Name': 'string'}") 
})); 

Тогда я могу создать пользовательскую модель связующего, которая считывает такие свойства, десериализуется Product объект из JSON и отправляет правильный объект моего метода действия в контроллере:

// Raw prototype code 
public class JsonFromDataVariable : IModelBinder 
{ 
    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) 
    { 
     if (bindingContext.ModelType != typeof(Product)) 
     { 
      return false; 
     } 

     var value = bindingContext.ValueProvider.GetValue("data"); 
     if (value != null && value.RawValue != null) 
     { 
      var serializer = new JsonSerializer(); 
      var product = JsonSerializer 
           .Create() 
           .Deserialize<Product>(new JsonTextReader(new StringReader(value.RawValue.ToString()))); 
      bindingContext.Model = product; 
      return true; 
     } 

     return false; 
    } 
} 

public class JsonFromDataVariableProvider : ModelBinderProvider 
{ 
    public override IModelBinder GetBinder(System.Web.Http.HttpConfiguration configuration, Type modelType) 
    { 
     return new JsonFromDataVariable(); 
    } 
} 

Не забудьте указать вяжущего в модели:

[ModelBinder(typeof(JsonFromDataVariableProvider))] 
public class Product 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
}