MVC 使用BeginForm + 文件上传

form使用Controller MVCd的BeginForm生产

        public static MvcForm ExBeginForm(this AjaxHelper ajaxHelper, string areaName, string controllerName, string actionName, string onSuccess, string onBegin, object htmlAttributes)
        {
            string url = "/{0}/{1}/{2}";
            url = string.Format(url, areaName, controllerName, actionName);

            return ajaxHelper.BeginForm(actionName, controllerName, new { area = areaName },
                                        new AjaxOptions
                                        {
                                            HttpMethod = "Post",
                                            Url = url,
                                            OnSuccess = onSuccess,
                                            OnFailure = "onAjaxFailure",
                                            OnBegin = onBegin
                                        }, htmlAttributes
    );
        }

model 定义接受属性

    public partial class PPF_Biz_NInvoice_Mod
    {
        public virtual HttpPostedFileBase FileImg { get; set; }
    }

view 中使用OnBegin结合 jquery.unobtrusive-ajax.min.js 文件进行提交处理,在生成的form标签中默认加上data-ajax="true",但该属性会导致页面提交后台获取的FileImg始终是null,所以需要重写该属性.

同时要加上enctype = "multipart/form-data"属性。Mvc不识别 连接符“-” 使用“_”替代即可.

@using (Ajax.ExBeginForm("Business/ChangShaZJ", "NInvoice", "Save", "onSaved", "onBegin", new { data_ajax = "false", enctype = "multipart/form-data" }))
{   
    @Html.HiddenFor(m => m.CustomerID)
    <div class="weui-cells weui-cells_form">
        <div class="weui-cell">
            <div class="weui-cell__hd">
                <label class="weui-label">标题</label>
            </div>
            <div class="weui-cell__bd">
                @Html.TextBoxFor(m => m.Title,
                            new Dictionary<string, object>() 
                            {
                            { "class", "weui-input" } ,
                            })
            </div>
        </div>
        <div class="weui-cell">
            <div class="weui-cell__hd">
                <label class="weui-label">发票编号</label>
            </div>
            <div class="weui-cell__bd">
                @Html.TextBoxFor(m => m.No,
                            new Dictionary<string, object>() 
                            {
                            { "class", "weui-input" } ,
                            })
            </div>
        </div>
        <div class="weui-cell">
            <div class="weui-cell__hd">
                <label class="weui-label">供应金额</label>
            </div>
            <div class="weui-cell__bd">
                @Html.TextBoxFor(m => m.Account,
                            new Dictionary<string, object>() 
                            {
                            { "class", "weui-input" } ,
                            { "type", "number" } ,
                            { "pattern", "[0-9]*" } 
                            })
            </div>
        </div>
        <div class="weui-cell">
            <div class="weui-cell__bd">
                <div class="weui-uploader">
                    <div class="weui-uploader__hd">
                        <p class="weui-uploader__title">图片上传</p>
                    </div>
                    <div class="weui-uploader__bd">
                        <ul class="weui-uploader__files" id="uploaderFiles">
                        </ul>
                        <div class="weui-uploader__input-box" id="uploaderAdd">
                            <input id="uploaderInput" class="weui-uploader__input" type="file" name="FileImg" accept="image/*" multiple />
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <br />
            
    <a id="btnSave" class="weui-btn weui-btn_primary" href="#" data-ajax="false" style="color: #fff; text-shadow: none; margin: 10px">保存</a>
          
}

Bll 上传文件

        public OperateResult UploadFile(string staticPath, HttpPostedFileBase file)
        {
            OperateResult rlt = new OperateResult();
            rlt.isSuccess = true;
            try
            {
                var dateDir = DateTime.Now.ToString("yyyy-MM-dd");
                var spath = staticPath + "/" + dateDir;
                rlt.model = spath + "/" + file.FileName;
                var path = HttpContext.Current.Server.MapPath(StaticPathEnum.UserResRoot + spath);
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }

                string strPath = Path.Combine(path, file.FileName);
                file.SaveAs(strPath);
            }
            catch (Exception ex)
            {
                rlt.errorMesg = ex.ToString();
            }

            return rlt;
        }

 但是这里又回衍生一个新的问题,设置data_ajax = "false" 之后,form提交的onBegin以及onSuccess事件就无效了,所以提交的时候不能使用submit()方法提交,要使用ajaxSubmit()来提交.

同时页面上面需要引用Jquery.form.js 文件

$(function () {
    $.WY.bindMobileClick("#btnSave", function (sender) {
        var frm = $("#form0");
        $.WY.formSubmitByFile(frm);
    });
});

文件提交通用方法,这里的方法是写在扩展中的通过扩展进行调用

getFunction: function (code) {
        var fn = window, parts = (code || "").split(".");
        while (fn && parts.length) {
            fn = fn[parts.shift()];
        }
        if (typeof (fn) === "function") {
            return fn;
        }
        else {
            return null;
        }
        argNames.push(code);
        return Function.constructor.apply(null);
    },
    formSubmitByFile: function (frm) {
        var data_ajax_begin = frm.attr("data-ajax-begin");
        if (data_ajax_begin != "") {
            var fn = jQuery.WY.getFunction(data_ajax_begin);
            if (fn) {
                if (!fn.call(this, frm)) {
                    return;
                }
            }
        }
        var action = frm.attr("data-ajax-url");
        var method = frm.attr("data-ajax-method");
        var onSaved = frm.attr("data-ajax-success");
        var onAjaxFailure = frm.attr("data-ajax-failure");
        frm.ajaxSubmit({
            url: action,
            type: method,
            success: function (data) {
                var reg = /<pre.+?>(.+)<\/pre>/g;
                var result = data.match(reg);
                data = jQuery.parseJSON(RegExp.$1);

                var fn = jQuery.WY.getFunction(onSaved);
                fn.call(null, data);
            },
            error: jQuery.WY.getFunction(onAjaxFailure)
        });
    },

提交返回时还会出现序列化格式不对的问题,当后台获取到前台传来的文件时(例如上传功能, 导入功能), 返回类型为application/json, 这个时候响应到前端的JSON格式的数据格式可能是:

<pre style="word-wrap: break-word; white-space: pre-wrap;">{"JsonKey":"JsonValue"}</pre>

这个是不同浏览器对返回数据处理的问题。可在前台进行匹配取值,也可以在后台转类型

 

posted @ 2018-02-01 15:32  竹殇  阅读(585)  评论(0编辑  收藏  举报