Web API中基类的自定义模型绑定器

时间:2015-04-01 14:27:12

标签: c# .net asp.net-web-api custom-model-binder

给出以下模型

public class RequestBase
{
    public DateTime TransactionTimestamp { get; set; }

    public Guid RequestMessageId { get; set; }

}

 [ModelBinder(typeof(RequestBaseModelBinder))]
public class StandardRequest : RequestBase
{

     public Guid MyGuidId { get; set; }

    public int MyIntId { get; set; }

}

RequestBase中的值是通过标题发送的,所以我正在尝试实现自定义模型绑定器以将它们绑定到模型

这是我到目前为止所得到的

 public class RequestBaseModelBinder :IModelBinder
{
    public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
    {
        var requestBase = bindingContext.Model as RequestBase;

        if (requestBase != null)
        {
            requestBase.RequestMessageId =
               Guid.Parse(actionContext.Request.Headers.GetValues("RequestMessageId").FirstOrDefault());

            requestBase.TransactionTimestamp =
               DateTime.Parse(actionContext.Request.Headers.GetValues("TransactionTimestamp").FirstOrDefault());

            return true;
        }

        return false;
    }
}

由于bindingContext.Model为空

,目前无法正常工作

1 个答案:

答案 0 :(得分:1)

不,bindingContext.Model是您将从action参数中获取的对象。

您应该从actionContext.Request获取标头,构建模型,并将模型设置为bindingContext.Model

代码应该像:

Dictionary<string, string> kvps = new Dictionary<string, string>();
        if (!string.IsNullOrEmpty(actionContext.Request.RequestUri.Query))
        {
            kvps = actionContext.Request.GetQueryNameValuePairs().ToDictionary(a=>a.Key,a=>a.Value);
        }
        //Check and get source data from body 
        else if (actionContext.Request.Content.IsFormData())
        {
            var bodyString = actionContext.Request.Content.ReadAsStringAsync().Result;
            try
            {
                kvps = ConvertToKvps(bodyString);
            }
            catch (Exception ex)
            {
                bindingContext.ModelState.AddModelError(bindingContext.ModelName, ex.Message);
                return false;
            }
        }
        else
        {
            bindingContext.ModelState.AddModelError(bindingContext.ModelName, "No input data");
            return false;
        }
        Object obj = null;

        try
        {
            obj = new Something(kvps);//build your object by key value pairs
        }
        catch (Exception ex)
        {
            bindingContext.ModelState.AddModelError(
                bindingContext.ModelName, ex.Message);
            return false;
        }

        bindingContext.Model = obj;
        return true;

看到这个例子: http://www.codeproject.com/Articles/701182/A-Custom-Model-Binder-for-Passing-Complex-Objects