微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

HttpPostedFileBase 仅在 Edit() 表单 Post 上返回 null?

如何解决HttpPostedFileBase 仅在 Edit() 表单 Post 上返回 null?

我将 ASP.NET MVC 5 与实体框架和 Owin/Identity 一起用于用户帐户身份验证。 将各种表单属性与 HttpPostedFileBase 文件组合到数据库时,我的控制器的 Create() 方法似乎按预期工作。但是,每次我尝试在 Edit() 方法修改同一实体时,HttpPostedFileBase 文件都会返回 null。表单数据的其余部分在编辑中发布并持久保存到数据库中,但我似乎永远无法在编辑方法中将文件发布到控制器。可能与我缺少的某种授权配置有关?

我还可以在 DevTools 中的“请求标题 > 表单数据”下看到正确的文件名和数据至少正在尝试加载到“编辑”帖子中,但它似乎在两者之间的某个地方丢失了。

任何帮助都是超级笨蛋!

(创建.cshtml)


@model GivingTree.Web.Models.FruitTree

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>


@using (Html.BeginForm("Create","FruitTree",null,FormMethod.Post,new { enctype = "multipart/form-data",role="form",@class = ""}))
{
    @Html.AntiForgeryToken()

    <div>

        @Html.ValidationSummary(true,"",new { @class = "text-danger" })

        <div class="form-group">
            @Html.LabelFor(model => model.Name,htmlAttributes: new { @class = "col col-form-label" })
            <div class="col">
                @Html.EditorFor(model => model.Name,new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Name,new { @class = "text-danger" })
            </div>
        </div>

...

        <div class="form-group">
            @Html.Label("fileUpload",new {@class = "col col-form-label"})
            <div class="col">
                <input type="file" name="fileUpload" id="fileUpload" />
            </div>
        </div>

        @Html.Partial("_GoogleMapsBlock")

        <div class="form-group">
            <div class="col">
                <input id="submit" type="submit" name="submit" value="Create" class="btn btn-dark"  />
            </div>
        </div>
    </div>
}

(编辑.cshtml)


    @model GivingTree.Web.Models.FruitTree
    
    @{
        ViewBag.Title = "Edit";
    }
    
    <h2>Edit</h2>
    
    
    @using (Html.BeginForm("Edit",new { encytype = "multipart/from-data",role = "form",@class = ""}))
    {
        @Html.AntiForgeryToken()
    
        <div>
            @Html.ValidationSummary(true,new { @class = "text-danger" })
            @Html.HiddenFor(model => model.Id)
    
    ...
    
            <div class="form-group">
                @Html.Label("fileUpload",new {@class = "col col-form-label"})
                <div class="col">
                    <input type="file" name="fileUpload" id="fileUpload" />
                </div>
            </div>
            <div class="form-group">
                <div class="col">
                    <input id="submit" type="submit" name="submit" value="Create" class="btn btn-dark"  />
                </div>
            </div>
        </div>

(FileUpload.cs)


    using System.ComponentModel.DataAnnotations;
    
    namespace GivingTree.Web.Models
    {
        public class FileUpload
        {
            public int FileUploadId { get; set; }
    
            [StringLength(255)]
            public string FileUploadName { get; set; }
    
            [StringLength(100)]
            public string ContentType { get; set; }
    
            public byte[] Content { get; set; }
    
            public FileUploadType FileUploadType { get; set; }
    
            public int FruitTreeId { get; set; }
    
            // using virtual to establish the one-to-many relationship with the FruitTree class
            public virtual FruitTree FruitTree { get; set; }
        }
    }

(FileUploadType.cs)


    namespace GivingTree.Web.Models
    {
        public enum FileUploadType
        {
            Avatar = 1,Photo
        }
    }

(FileUploadController.cs)


    using System.Web.Mvc;
    using GivingTree.Web.DAL;
    using GivingTree.Web.Models;
    
    namespace GivingTree.Web.Controllers
    {
        public class FileUploadController : Controller
        {
             private GivingTreeDbContext _db = new GivingTreeDbContext();
    
            // This obtains the file based on the id value passed in the query string,then it returns the image to the browser as a FileResult
            // GET: /FileUpload/
            public ActionResult Index(int? id)
            {
                FileUpload filetoRetrieve = _db.FileUploads.Find(id);
    
                return File(filetoRetrieve.Content,filetoRetrieve.ContentType);
            }
        }
    }

(果树.cs)


    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    
    namespace GivingTree.Web.Models
    {
        public class FruitTree
        {
            public int Id { get; set; }
    
            [required]
            [display(Name="Post Title")]
            public string Name { get; set; }
    
            [required]
            [display(Name="Type of Fruit")]
            public FruitType Fruit { get; set; }
    
            [required]
            [DataType(DataType.Text)]
            [display(Name="Post Description")]
            public string Description { get; set; }
    
            [required]
            [display(Name="Latitude")]
            public double Latitude { get; set; }
    
            [required]
            [display(Name="Longitude")]
            public double Longitude { get; set; }
    
            // completes the association of the one-to-many relationship with the FileUpload entity
            [displayFormat(ConvertEmptyStringToNull=false)]
            [display(Name="Upload a Photo")]
            public virtual ICollection<FileUpload> FileUploads { get; set; }
        }
    }

(FruitTreeController.cs)


   [Authorize]
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Create([Bind(Include = "Name,Fruit,Description,Latitude,Longitude")]FruitTree tree,HttpPostedFileBase fileUpload)
    {
        try
        {
            if (ModelState.IsValid)
            {
                // Extracts the binary data from the request and populates a new File entity instance which is ready to be added to the FruitTree's File collection.
                if (fileUpload?.ContentLength > 0)
                {
                    // create the new File object and assign the properties given by the upload parameter
                    FileUpload photo = new()
                    {
                        FileUploadName = Path.GetFileName(fileUpload.FileName),FileUploadType = FileUploadType.Photo,ContentType = fileUpload.ContentType
                    };

                    // the binary data is obtained from the InputStream prop,and a BinaryReader object is used to read that data into the Content property of the File object. 
                    using (var reader = new BinaryReader(fileUpload.InputStream))
                    {
                        photo.Content = reader.ReadBytes(fileUpload.ContentLength);
                    }

                    // add the new file object to the tree object
                    tree.FileUploads = new List<FileUpload> { photo };
                }

                // save to database
                _db.FruitTrees.Add(tree); 
                _db.SaveChanges();
                return RedirectToAction("Index");
            }
        }
        catch (RetryLimitExceededException  dex )
        {
            ModelState.AddModelError("Unable to save changes",dex);
        }

        return View(tree);
    }


   // GET: FruitTrees/Edit/5
    [HttpGet]
    public ActionResult Edit(int? id)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }

        // Returns all of the file types associated with the given id
        FruitTree tree = _db.FruitTrees.Include(s => s.FileUploads).SingleOrDefault(s => s.Id == id);

        if (tree == null)
        {
            return HttpNotFound();
        }
        return View(tree);
    }

    // POST: FruitTrees/Edit/5
    [Authorize]
    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Edit(int? id,HttpPostedFileBase fileUpload)
    {
        if (id == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
        }

        var treetoUpdate = _db.FruitTrees.Find(id);

        if (ModelState.IsValid)
        {
            if (TryUpdateModel(treetoUpdate,new string[] {"Name","Fruit","Description","Latitude","Longitude"}))
            {
                try
                {
                    if (fileUpload != null && fileUpload.ContentLength > 0)
                    {
                        if (treetoUpdate.FileUploads.Any(f => f.FileUploadType == FileUploadType.Photo))
                        {
                            _db.FileUploads.Remove(treetoUpdate.FileUploads.First(f =>
                                f.FileUploadType == FileUploadType.Photo));
                        }

                        var photo = new FileUpload
                        {
                            FileUploadName = System.IO.Path.GetFileName(fileUpload.FileName),ContentType = fileUpload.ContentType
                        };
                        using (var reader = new System.IO.BinaryReader(fileUpload.InputStream))
                        {
                            photo.Content = reader.ReadBytes(fileUpload.ContentLength);
                        }

                        treetoUpdate.FileUploads = new List<FileUpload> {photo};
                    }

                    _db.Entry(treetoUpdate).State = EntityState.Modified;
                    _db.SaveChanges();

                    return RedirectToAction("Index");
                }
                catch (RetryLimitExceededException dex)
                {
                    ModelState.AddModelError(
                        "Unable to save changes.",dex);
                }
            }
        }

        return View(treetoUpdate);
    }

(GivingTreeDbContext.cs)


    using GivingTree.Web.Models;
    using System.Data.Entity;
    using System.Data.Entity.ModelConfiguration.Conventions;
    
    namespace GivingTree.Web.DAL
    {
        public class GivingTreeDbContext : DbContext
        {
        
            public DbSet<FruitTree> FruitTrees { get; set; }
            public DbSet<FileUpload> FileUploads { get; set; }
    
            protected override void OnModelCreating(DbModelBuilder modelBuilder)
            {
                modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
            }
        }
    }
    
    
    ```
    (Startup.Auth.cs)
    
    ```
    using System;
    using System.Configuration;
    
    using GivingTree.Web.Models;
    
    using Microsoft.AspNet.Identity;
    using Microsoft.AspNet.Identity.Owin;
    using Microsoft.Owin;
    using Microsoft.Owin.Security.Cookies;
    using Microsoft.Owin.Security.Google;
    
    using Owin;
    
    namespace GivingTree.Web
    {
        public partial class Startup
        {
            public void ConfigureAuth(IAppBuilder app)
            {
                // Configure the db context,user manager and signin manager to use a single instance per request
                app.CreatePerOwinContext(ApplicationDbContext.Create);
                app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
                app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
    
                // Enable the application to use a cookie to store information for the signed in user
                // and to use a cookie to temporarily store information about a user logging in with a third party login provider
                // Configure the sign in cookie
                app.UseCookieAuthentication(new CookieAuthenticationoptions
                {
                    AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,CookieName = "GivingTreeApplicationCookie",LoginPath = new PathString("/Account/Login"),Provider = new CookieAuthenticationProvider
                    {
                        // Enables the application to validate the security stamp when the user logs in.
                        // This is a security feature which is used when you change a password or add an external login to your account.  
                        OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager,ApplicationUser>(
                            validateInterval: TimeSpan.FromMinutes(30),regenerateIdentity: (manager,user) => user.GenerateUserIdentityAsync(manager))
                    }
                });            
                app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
    
                // Enables the application to temporarily store user information when they are verifying the second factor in the two-factor authentication process.
                app.UseTwoFactorSignInCookie(DefaultAuthenticationTypes.TwoFactorCookie,TimeSpan.FromMinutes(5));
    
                // Enables the application to remember the second login verification factor such as phone or email.
                // Once you check this option,your second step of verification during the login process will be remembered on the device where you logged in from.
                // This is similar to the RememberMe option when you log in.
                app.UseTwoFactorRememberbrowserCookie(DefaultAuthenticationTypes.TwoFactorRememberbrowserCookie);
    
                app.UseFacebookAuthentication(
                   appId: ConfigurationManager.AppSettings["Authentication:Facebook:AppId"],appSecret: ConfigurationManager.AppSettings["Authentication:Facebook:AppSecret"]);
    
                app.UseGoogleAuthentication(new GoogleOAuth2Authenticationoptions()
                {
                    ClientId = ConfigurationManager.AppSettings["Googleoauth2clientId"],ClientSecret = ConfigurationManager.AppSettings["Googleoauth2clientSecret"]
                });
            }
        }
    }

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。