2016-09-30 62 views
1

我創建簡單的模型JsonConverter屬性:的WebAPI JsonConverter的X WWW的形式,進行了urlencoded不工作

public class MyModel 
{ 
    [JsonProperty(PropertyName = "my_to")] 
    public string To { get; set; } 

    [JsonProperty(PropertyName = "my_from")] 
    public string From { get; set; } 

    [JsonProperty(PropertyName = "my_date")] 
    [JsonConverter(typeof(UnixDateConverter))] 
    public DateTime Date { get; set; } 
} 

和我的轉換器:

public sealed class UnixDateConverter : JsonConverter 
{ 
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     if (!CanConvert(reader.ValueType)) 
     { 
      throw new JsonSerializationException(); 
     } 

     return DateTimeOffset.FromUnixTimeSeconds((long)reader.Value).ToUniversalTime().LocalDateTime; 
    } 

    public override bool CanConvert(Type objectType) 
    { 
     return Type.GetTypeCode(objectType) == TypeCode.Int64; 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     var datetime = (DateTime) value; 
     var dateTimeOffset = new DateTimeOffset(datetime.ToUniversalTime()); 
     var unixDateTime = dateTimeOffset.ToUnixTimeSeconds(); 
     writer.WriteValue(unixDateTime); 
    } 
} 

當我從郵遞員發送請求我設置內容類型爲application/json一切工作正常 - 我的轉換器工作正常,調試器停在我的轉換器斷點,但我必須使用x-www-form-urlencoded

當發送數據爲x-www-form-urlencoded時,是否可以選擇使用JsonConverter屬性?

+0

爲什麼你使用x-www-form-urlencoded時甚至會有json轉換器? –

+0

@MarcusH我已經使用'application/json'測試了我的API,但現在我必須處理'x-www-form-urlencoded'。我認爲這應該工作,問題是不是。那麼有什麼其他選擇可以做到這一點?我需要支持自定義名稱映射(請求中的不同名稱和我的模型中的不同名稱,如PropertyName屬性)和日期時間轉換器 – Misiu

+0

您是否使用Content-Type:x-www-form-urlencoded請求發送JSON數據或者您是否發送表單數據? – spender

回答

0

我設法通過創建實現IModelBinder

這裏是我的粘結劑的通用版本自定義模型粘結劑做到這一點:

internal class GenericModelBinder<T> : IModelBinder where T : class, new() 
{ 
    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext) 
    { 
     if (bindingContext.ModelType != typeof (T)) 
     { 
      return false; 
     } 

     var model = (T) bindingContext.Model ?? new T(); 

     JObject @object = null; 

     var task = actionContext.Request.Content.ReadAsAsync<JObject>().ContinueWith(t => { @object = t.Result; }); 
     task.Wait(); 

     var jsonString = @object.ToString(Formatting.None); 
     JsonConvert.PopulateObject(jsonString, model); 
     bindingContext.Model = model; 

     return true; 
    } 
} 

這裏是示例用法:

[Route("save")] 
[HttpPost] 
public async Task<IHttpActionResult> Save([ModelBinder(typeof (GenericModelBinder<MyModel>))] MyModel model) 
{ 
    try 
    { 
     //do some stuff with model (validate it, etc) 
     await Task.CompletedTask; 
     DbContext.SaveResult(model.my_to, model.my_from, model.my_date); 
     return Content(HttpStatusCode.OK, "OK", new TextMediaTypeFormatter(), "text/plain"); 
    } 
    catch (Exception e) 
    { 
     Debug.WriteLine(e); 
     Logger.Error(e, "Error saving to DB"); 
     return InternalServerError(); 
    } 
} 

我我不確定JsonProperty和JsonConverter屬性是否工作,但他們應該。

我知道這可能不是最好的辦法,但是這段代碼對我很有用。任何建議都是值得歡迎的。

相關問題