【问题标题】:Post JSON with data AND file to Web Api - jQuery / MVC将带有数据和文件的 JSON 发布到 Web Api - jQuery / MVC
【发布时间】:2015-08-10 00:03:24
【问题描述】:

我需要通过一个请求发布到带有 JSON(最好)的 Api 控制器。

问题在于传递数据和文件(已上传图片)。我的财产空了(null)。

我查看了很多博客,但似乎无法通过图像的数据。

public class SomeModel
{
    public string Name { get; set; }
    public string Email { get; set; }
    public string City { get; set; }
    public HttpPostedFileBase Image { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public string CountryCode { get; set; }
}


    [HttpPost]
    public void CreateContestEntry(SomeModel model)
    {
        // model.Image is always null
        // .. get image here - the other properties no issues
    }

jQuery

    // create model for controller
    var model = {
        Name: $.trim($contestForm.find('[name="nombre"]').val()) + ' ' + $.trim($contestForm.find('[name="apellido"]').val()),
        Email: $.trim($contestForm.find('[name="email"]').val().toLowerCase()),
        City: $.trim($contestForm.find('[name="cuidad"]').val()),
        Title: $.trim($contestForm.find('[name="title"]').val()),
        Description: $.trim($contestForm.find('[name="description"]').val()),
        CountryCode: 'co',
        Image: $contestForm.find('[name="file-es"]')[0].files[0]  // this has the file for sure
    };

    $.ajax({
        url: '/Umbraco/api/ControllerName/CreateContestEntry',
        type: 'POST',
        dataType: 'json',
        data: JSON.stringify(model),
        //data: $('#test-form').serialize(),  // tried this and using FormData()
        processData: false,
        async: false,
        contentType: 'application/json; charset=utf-8',
        complete: function (data) {

        },
        error: function (response) {
            console.log(response.responseText);
        }
    });

我看过的博客:


当我尝试FormData$('#form1').serialize() 方法时,我的provider.FileDataprovider.FormData 也总是空的。我从方法中删除了model 参数,当我打开它时断点正在命中。

    [HttpPost]
    public void CreateContestEntry()
    {
        string root = HttpContext.Current.Server.MapPath("~/App_Data");
        var provider = new MultipartFormDataStreamProvider(root);

        try
        {
            // Read the form data.
            Request.Content.ReadAsMultipartAsync(provider);

            // This illustrates how to get the file names.
            foreach (MultipartFileData file in provider.FileData)
            {
                // empty
            }

            foreach (var key in provider.FormData.AllKeys)
            {
                foreach (var val in provider.FormData.GetValues(key))
                {
                    // empty
                }
            }
            //return Request.CreateResponse(HttpStatusCode.OK);
        }
        catch(Exception ex)
        {

        }
    }

解决方案:

离开@Musa 的回答,这里是 Api 控制器代码。我将 NameValueCollection 映射到我的模型。

    [HttpPost]
    public void CreateContestEntry()
    {
        try
        {
            // get variables first
            NameValueCollection nvc = HttpContext.Current.Request.Form;
            var model = new WAR2015ContestModel();

            // iterate through and map to strongly typed model
            foreach (string kvp in nvc.AllKeys)
            {
                PropertyInfo pi = model.GetType().GetProperty(kvp, BindingFlags.Public | BindingFlags.Instance);
                if (pi != null)
                {
                    pi.SetValue(model, nvc[kvp], null);
                }
            }

            model.Image = HttpContext.Current.Request.Files["Image"];
        }
        catch(Exception ex)
        {

        }
    }

【问题讨论】:

    标签: c# jquery ajax json asp.net-mvc


    【解决方案1】:

    您不能使用 JSON 上传文件(即任意二进制数据),因为 JSON 是一种文本格式。您必须使用多部分表单数据。

    // create model for controller
    var model = new FormData();
    model.append('Name', $.trim($contestForm.find('[name="nombre"]').val()) + ' ' + $.trim($contestForm.find('[name="apellido"]').val()));
    model.append('Email', $.trim($contestForm.find('[name="email"]').val().toLowerCase()));
    model.append('City', $.trim($contestForm.find('[name="cuidad"]').val()));
    model.append('Title', $.trim($contestForm.find('[name="title"]').val()));
    model.append('Description', $.trim($contestForm.find('[name="description"]').val()));
    model.append('CountryCode', 'co');
    model.append('Image', $contestForm.find('[name="file-es"]')[0].files[0]);  // this has the file for sure
    
    $.ajax({
        url: '/Umbraco/api/ControllerName/CreateContestEntry',
        type: 'POST',
        dataType: 'json',
        data: model,
        processData: false,
        contentType: false,// not json
        complete: function (data) {
            var mediaId = $.parseJSON(data.responseText); //?
    
        },
        error: function (response) {
            console.log(response.responseText);
        }
    });
    

    【讨论】:

    • 继续收到var model = new FormData(); 上的错误未捕获的类型错误:对象不是函数。是的,我注释掉了我以前的模型对象,所以我没有复制变量。
    • 你用的是什么浏览器?您是否在代码中的其他地方定义了 FormData?
    • Chrome - 添加这个 js 文件很大 - 搜索 FormData() 并弹出几次,但其他地方定义的其他变量。没有任何方法被命名
    • 所以你在任何地方都找不到FormData = ...console.log(typeof FormData); 带给你什么?
    • 我找到了 - 但是,方法 hit 和 provider.FormDataprovider.FileData 是空的。我更新了底部方法以显示我拥有的所有代码
    猜你喜欢
    • 2020-04-16
    • 2014-06-08
    • 2016-09-12
    • 2013-05-30
    • 1970-01-01
    • 2015-02-18
    • 1970-01-01
    • 2016-12-19
    • 1970-01-01
    相关资源
    最近更新 更多