Web.Api接受参数表单值

本文关键字:表单 参数 Api Web | 更新日期: 2023-09-27 18:19:32

我使用的是web.api 2.2,客户端以这种方式发送数据:

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": "support@winnlotto.com", "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();
        }

编辑:我所做的是用字符串数据字段封装模型,它在字符串中检索json:

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

这是检索表单参数的正确方法吗?

Web.Api接受参数表单值

您想要做的是创建一个表示您期望的对象的模型。调用方将发送格式化为json的对象,Web API可以自动将其反序列化为c#对象。然后,在该对象中,您可以轻松地对模型进行验证,对数据进行处理,并返回一个结果,该结果也可以自动反序列化回json(如果调用方想要的话)。

我建议您学习/阅读Web 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

也许模型绑定器是最好的方法。

例如,假设我有一个控制器:

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

但是客户端以url编码格式向我发送数据,其中data参数中包含JSON数据,如您所示:

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

然后,我可以创建一个自定义模型绑定器,读取这样的属性,从JSON反序列化Product对象,并将正确的对象发送到控制器中的操作方法:

// 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; }
}