上传图像asp.net MVC时出现Base64错误

时间:2014-02-22 03:02:48

标签: c# asp.net-mvc forms image-uploading

我正在尝试上传带有表单的图片,问题是大多数示例只是上传图片,但我想添加更多数据,比如名字,网址等。

这是我得到的错误......

The input is not a valid Base64 string that contains a character that is not Base 64, more than two padding characters, or an invalid character among the padding characters.
[FormatException: La entrada no es una cadena Base 64 válida porque contiene un carácter que no es Base 64, más de dos caracteres de relleno o un carácter no válido entre los caracteres de relleno. ]
     System.Convert.FromBase64_Decode(Char* startInputPtr, Int32 inputLength, Byte* startDestPtr, Int32 destLength) +10739609
     System.Convert.FromBase64CharPtr(Char* inputPtr, Int32 inputLength) +130
     System.Convert.FromBase64String(String s) +41
     System.Web.Mvc.ByteArrayModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +265
     System.Web.Mvc.DefaultModelBinder.GetPropertyValue(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor, IModelBinder propertyBinder) +59
     System.Web.Mvc.DefaultModelBinder.BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, PropertyDescriptor propertyDescriptor) +653
     System.Web.Mvc.DefaultModelBinder.BindProperties(ControllerContext controllerContext, ModelBindingContext bindingContext) +180
     System.Web.Mvc.DefaultModelBinder.BindComplexElementalModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Object model) +106
     System.Web.Mvc.DefaultModelBinder.BindComplexModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +2541
     System.Web.Mvc.DefaultModelBinder.BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext) +633
     System.Web.Mvc.ControllerActionInvoker.GetParameterValue(ControllerContext controllerContext, ParameterDescriptor parameterDescriptor) +494
     System.Web.Mvc.ControllerActionInvoker.GetParameterValues(ControllerContext controllerContext, ActionDescriptor actionDescriptor) +199
     System.Web.Mvc.Async.<>c__DisplayClass1e.<BeginInvokeAction>b__16(AsyncCallback asyncCallback, Object asyncState) +1680
     System.Web.Mvc.Async.WrappedAsyncResult`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +59
     System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
     System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object state, BeginInvokeDelegate beginDelegate, EndInvokeDelegate`1 endDelegate, Object tag, Int32 timeout) +94
     System.Web.Mvc.Async.AsyncControllerActionInvoker.BeginInvokeAction(ControllerContext controllerContext, String actionName, AsyncCallback callback, Object state) +525
     System.Web.Mvc.Controller.<BeginExecuteCore>b__1c(AsyncCallback asyncCallback, Object asyncState, ExecuteCoreState innerState) +82
     System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +73
     System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
     System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) +105
     System.Web.Mvc.Controller.BeginExecuteCore(AsyncCallback callback, Object state) +595
     System.Web.Mvc.Controller.<BeginExecute>b__14(AsyncCallback asyncCallback, Object callbackState, Controller controller) +47
     System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +65
     System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
     System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) +139
     System.Web.Mvc.Controller.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +484
     System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.BeginExecute(RequestContext requestContext, AsyncCallback callback, Object state) +50
     System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__3(AsyncCallback asyncCallback, Object asyncState, ProcessRequestState innerState) +98
     System.Web.Mvc.Async.WrappedAsyncVoid`1.CallBeginDelegate(AsyncCallback callback, Object callbackState) +73
     System.Web.Mvc.Async.WrappedAsyncResultBase`1.Begin(AsyncCallback callback, Object state, Int32 timeout) +151
     System.Web.Mvc.Async.AsyncResultWrapper.Begin(AsyncCallback callback, Object callbackState, BeginInvokeDelegate`1 beginDelegate, EndInvokeVoidDelegate`1 endDelegate, TState invokeState, Object tag, Int32 timeout, SynchronizationContext callbackSyncContext) +106
     System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +446
     System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +88
     System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +50
     System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +301
     System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

这是我在控制器中的代码......

[HttpPost]
    public ActionResult Create(Feed feed)
    {
        if (ModelState.IsValid)
        {
           feed.UserModelID = UserRepo.GetUser(User.Identity.Name).UserModelID;
            if (Repo.InserFeed(feed) != -1)
            {
                ViewBag.success = "success";
            }
            else
            {
                ViewBag.success = "error";
            }
        }
        return View(feed);
    }

这是我的模特......

public class Feed
{
    public Int32 FeedID { get; set; }

    [Required(ErrorMessage = "The name is required")]
    [StringLength(32, MinimumLength = 8, ErrorMessage = "The name must be at least 8 characters")]
    public String Name { get; set; }

    [Required(ErrorMessage = "The url is required")]
    [Url(ErrorMessage = "Invalid URL")]
    public String Url { get; set; }

    [Required(ErrorMessage = "A type must be selected")]
    public Boolean IsAtom { get; set; }

    public Byte[] Image { get; set; }
    public String ImageIcon { get; set; }
    public Int32 UserModelID { get; set; }

    public virtual ICollection<Article> Articles { get; set; }
}

这是我的表格......

using (Html.BeginForm("Create", "Feeds", FormMethod.Post, new { @class = "form-horizontal", role = "form", enctype = "multipart/form-data" }))
            {
                Html.AntiForgeryToken();
                Html.ValidationSummary(true);
                <fieldset>
                    <legend>Feed basic data</legend>
                    <div class="input-group">
                        <span class="input-group-addon glyphicon glyphicon-font"></span>
                        @Html.TextBoxFor(m => m.Name, new { @class = "form-control", placeholder = "Site name" })
                        @Html.ValidationMessageFor(m => m.Name)
                    </div>
                    <div class="input-group">
                        <span class="input-group-addon glyphicon glyphicon-link"></span>
                        @Html.TextBoxFor(m => m.Url, new { @class = "form-control", placeholder = "Feed URL" })
                        @Html.ValidationMessageFor(m => m.Url)
                    </div>
                    <div class="input-group">
                        <span class="input-group-addon glyphicon glyphicon-picture"></span>
                        @Html.TextBoxFor(m => m.Image, new { @class = "form-control", type = "file" })
                        @Html.ValidationMessageFor(m => m.Image)
                    </div>
                </fieldset>
                <fieldset>
                    <legend>Feed type</legend>
                    <label class="radio-inline">
                        @Html.RadioButtonFor(m => m.IsAtom, false, new { @checked = "checked", id = "rss" })
                        Rss
                    </label>
                    <label class="radio-inline">
                        @Html.RadioButtonFor(m => m.IsAtom, true, new { id = "atom" })
                        Atom
                    </label>
                    @Html.ValidationMessageFor(m => m.IsAtom)
                </fieldset>
                <br />
                <div class="input-group">
                    <button type="submit" class="btn btn-primary btn-sm">Add feed</button>
                </div>
                <br />
                if (ViewBag.Success != null)
                {
                    if (ViewBag.Success == "success")
                    {
                        <div class="alert alert-success"><strong>Great!</strong> you added a new feed.</div>
                    }
                    else
                    {
                        <div class="alert alert-danger"><strong>Sorry!</strong> but that is not a valid url.</div>
                    }
                }
            }

我认为当来自表单的图像数据绑定到Feed图像属性时会出现问题。如果你有一些例子可以展示,那就太好了。

2 个答案:

答案 0 :(得分:4)

这是我的解决方案,假设你有以下ViewModel -

public class FileViewModel
{
    public string Name { get; set; }
    public string Description { get; set; }
    public HttpPostedFileBase ThumbnailFile { get; set; }
}

然后你有一个控制器动作来渲染表格 -

    public ActionResult Index()
    {
        FileViewModel model = new FileViewModel();
        return View(model);
    }

在视图中,您将显示如下所示的所有字段 -

@model MVC.Controllers.FileViewModel

@{
    ViewBag.Title = "Index";
}

<h2>Index</h2>

@using (Html.BeginForm("Submit", "Person", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    @Html.AntiForgeryToken()
    @Html.ValidationSummary(true)

    @Html.LabelFor(model => model.Name)
    @Html.EditorFor(model => model.Name)
    @Html.ValidationMessageFor(model => model.Name)

    @Html.LabelFor(model => model.Description)
    @Html.EditorFor(model => model.Description)
    @Html.ValidationMessageFor(model => model.Description)

    <input type="file" name="ThumbnailFile" id="ThumbnailFile" />
    <input type="submit" value="Save" />
}

当您单击“提交”按钮时,您会遇到以下控制器操作 -

    public ActionResult Submit(FileViewModel model)
    {
        return View();
    }

Ans调试时,您将获得如下所示的所有值 -

enter image description here

答案 1 :(得分:0)

图像将采用HttpPostedFileBase而不是byte []的形式,并且将包含文件名,长度和内容类型等内容,您可以在存储之前将其转换为服务器上的byte []

您可以将其添加到您的模型中。

[NotMapped]
public HttpPostedFileBase ImageToUpload {get; set;}

和查看此属性的TextBoxFor

然后在服务器上:

var contentType = ImageToUpload.ContentType;
var ImageData = new byte[ImageToUpload.ContentLength];
ImageToUpload.InputStream.Read(ImageData, 0, ImageToUpload.ContentLength);