简体   繁体   English

上载图片asp.net MVC时出现Base64错误

[英]Getting Base64 error when uploading an image asp.net MVC

I'm trying to upload an image with a form, the problem is that most of examples are just to upload an image, but I want to add more data too, like name, url, etc. 我正在尝试使用表单上传图像,问题是大多数示例仅是上传图像,但我也想添加更多数据,例如名称,URL等。

This is the error I'm getting... 这是我得到的错误...

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

This is my code in the controller... 这是我在控制器中的代码...

[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);
    }

This is my model... 这是我的模特

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; }
}

And this is my form... 这是我的表格

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>
                    }
                }
            }

I think the problem comes when the image data that comes from the form is being bind to the Feed image property. 我认为问题出在来自表单的图像数据绑定到Feed图像属性时。 It would be nice if you have some examples to show. 如果您要显示一些示例,那就太好了。

Here goes my solution, say you have following ViewModel - 这是我的解决方案,说您有以下ViewModel-

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

Then you have a controller action to render a form - 然后,您可以执行控制器操作来呈现表单-

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

And in the View, you display all fields as shown below - 在“视图”中,显示所有字段,如下所示-

@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" />
}

And when you click Submit button, you get hit to following controller action - 然后,当您点击Submit按钮时,您会被以下控制器操作击中-

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

Ans when you debug, you get all the values as shown below - 回答时,您将获得所有值,如下所示-

在此处输入图片说明

the image will be in the form of HttpPostedFileBase not byte[], and will contain stuff like filename, length and content type, you can convert into a byte[] on the server before you store it 该图像将采用HttpPostedFileBase的形式而不是byte [],并将包含诸如文件名,长度和内容类型之类的内容,您可以在存储之前在服务器上将其转换为byte []

you could add this to your model. 您可以将其添加到模型中。

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

and TextBoxFor in the View to this property 和TextBoxFor在该属性的视图中

then on the sever: 然后在服务器上:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM