为什么此模型的属性初始化为null?

时间:2017-09-19 09:12:07

标签: c# asp.net-web-api

这是对问题Custom form data with multiple files to Web API controllerFilling Parameter with Attribute [FromForm] with Fiddler的跟进,这两个问题都是通过引用A MediaTypeFormatter for WebApi for multipart/form-data including file uploads来回答的。

基本上这与Tocana之前在最后一个链接中提出的问题相同。

我复制了后者的代码,注册了媒体类型格式化程序并尝试使用fiddler,但是当它进入UploadController.Post(UploadRequestViewModel model)时,模型是实例化的,但其属性都等于null

我调试了它,发现FormMultipartEncodedMediaTypeFormatter.BindToModel(IDictionary<string, object> data, Type type, IFormatterLogger formatterLogger)被一个正确的data字典调用,但从那时起,我无法从尾巴开始。用于绑定模型的绑定器是CompositeModelBinder,但是这个绑定是否正确我无法分辨。

fiddler请求如下所示:

标题

Content-Type: multipart/form-data; boundary=-------------------------acebdf13572468
User-Agent: Fiddler
Host: localhost:49473
Content-Length: 13192

---------------------------acebdf13572468
Content-Disposition: form-data; name="SiteId"
Content-Type: text/plain

987654321
---------------------------acebdf13572468
Content-Disposition: form-data; name="StartDate"
Content-Type: text/plain

24.08.1979
---------------------------acebdf13572468
Content-Disposition: form-data; name="Zulu"; filename="ExifTest.tif"
Content-Type: image/tiff

<@INCLUDE *C:\...\ExifTest.tif*@>
---------------------------acebdf13572468--

我需要做些什么来正确初始化我的模型,即它的值不是null

修改
所有模型和控制器都是A MediaTypeFormatter for WebApi for multipart/form-data including file uploads的那些,即

型号:

public class UploadRequestViewModel
{
    [Required]
    public string Title { get; set; }

    [Required]
    public string Description { get; set; }

    [Required]
    public HttpPostedFileBase File { get; set; }
}

控制器:

[Route("UploadTest")]
[HttpPost]
public IHttpActionResult Post(UploadRequestViewModel model)
{
}

FormMultipartEncodedMediaTypeFormatter.BindToModel

private object BindToModel(IDictionary<string, object> data, Type type, IFormatterLogger formatterLogger)
{
    if (data == null) throw new ArgumentNullException(nameof(data));
    if (type == null) throw new ArgumentNullException(nameof(type));

    using (var config = new HttpConfiguration())
    {
        // if there is a requiredMemberSelector set, use this one by replacing the validator provider
        var validateRequiredMembers = RequiredMemberSelector != null && formatterLogger != null;
        if (validateRequiredMembers)
        {
            config.Services.Replace(typeof(ModelValidatorProvider), new RequiredMemberModelValidatorProvider(RequiredMemberSelector));
        }

        // create a action context for model binding
        var actionContext = new HttpActionContext
        {
            ControllerContext = new HttpControllerContext
            {
                Configuration = config,
                ControllerDescriptor = new HttpControllerDescriptor
                {
                    Configuration = config
                }
            }
        };

        // create model binder context 
        var valueProvider = new NameValuePairsValueProvider(data, CultureInfo.InvariantCulture);
        var metadataProvider = actionContext.ControllerContext.Configuration.Services.GetModelMetadataProvider();
        var metadata = metadataProvider.GetMetadataForType(null, type);
        var modelBindingContext = new ModelBindingContext
        {
            ModelName = string.Empty,
            FallbackToEmptyPrefix = false,
            ModelMetadata = metadata,
            ModelState = actionContext.ModelState,
            ValueProvider = valueProvider
        };

        // bind model 
        var modelBinderProvider = new CompositeModelBinderProvider(config.Services.GetModelBinderProviders());
        var binder = modelBinderProvider.GetBinder(config, type);
        var haveResult = binder.BindModel(actionContext, modelBindingContext);

        // log validation errors 
        if (formatterLogger != null)
        {
            foreach (var modelStatePair in actionContext.ModelState)
            {
                foreach (var modelError in modelStatePair.Value.Errors)
                {
                    if (modelError.Exception != null)
                    {
                        formatterLogger.LogError(modelStatePair.Key, modelError.Exception);
                    }
                    else
                    {
                        formatterLogger.LogError(modelStatePair.Key, modelError.ErrorMessage);
                    }
                }
            }
        }

        return haveResult ? modelBindingContext.Model : GetDefaultValueForType(type);
    }
}

0 个答案:

没有答案