C# 如何将文件与其他数据同时上载

C# 如何将文件与其他数据同时上载,c#,entity-framework,file-upload,asp.net-mvc-5,C#,Entity Framework,File Upload,Asp.net Mvc 5,我有一个文件上传的形式,但我不能保存它与其他元素在同一个模型或两个单独的模型在同一时间。我知道我的第一个问题是我不能有嵌套的表单,例如 @using (Html.BeginForm("Create", "Home", FormMethod.Post, new { enctype = "multipart/form-data" })) { <form class="form-horizontal"> <input /> <input

我有一个文件上传的形式,但我不能保存它与其他元素在同一个模型或两个单独的模型在同一时间。我知道我的第一个问题是我不能有嵌套的表单,例如

@using (Html.BeginForm("Create", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <form class="form-horizontal">
       <input />
       <input />
           @using (Html.BeginForm("Create", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
           {
              <form class="form-horizontal">
              <input image upload/>
              <input />

             </form>
           }
    </form>
}
我希望这将有助于处于相同情况下的任何人(即学习者!)。在四处搜寻之后,我意识到,如果(我可能错了!)处理图像等复杂对象,文本将与.Add和.Save一起串在一起,只要它们是模型的一部分,如下所示:
名称空间客户端.Models
{
使用制度;
使用System.Collections.Generic;
公共部分职业
{
公共int id{get;set;}
公共字符串名称{get;set;}
公共可空iscomplete{get;set;}
公共可为空的jobbyuserid{get;set;}
公共可为空的responsibletradesmanid{get;set;}
公共字符串jobmessage{get;set;}
公共字符串阶段{get;set;}
公共字符串startjob{get;set;}
公共int-ImageId{get;set;}
公共字符串ImageName{get;set;}
公共字符串ImageAlt{get;set;}
公共字节[]图像数据{get;set;}
公共字符串ContentType{get;set;}
公共字符串预算{get;set;}
}
}
然后切碎操作以创建、保存、保存图像数据等,但最重要的是,您不需要从表单中定义任何字段
`(字符串quoteSearch=Request[“quoteSearch”];等)`因为它们将随模型更新。所以这里唯一的区别是,我删除了表单请求和保存单个项目,如
//将模型对象保存到数据库
db.jobs.Add(新作业
{
name=jobname,
然后只对图像和表单数据使用一个操作,所有操作都很好地组合在一起,如下所示:
[接受动词(HttpVerbs.Post)]
公共操作结果创建(作业pic、HttpPostedFileBase映像)
{
var context=System.Web.HttpContext.Current;
var contextBase=新的HttpContextWrapper(上下文);
////将当前用户名从cookie拉出到var中
//usernameCookie=新的HttpCookie(“当前用户名”);
//usernameCookie=contextBase.User.Request.Cookies[“CurrentUsername”];
//从OWIN获取电子邮件
字符串usernamecokie=contextBase.User.Identity.Name.ToString();
if(ModelState.IsValid)
{
如果(图像!=null)
{
//在保存到之前,将上载的图像附加到对象
数据库
pic.ContentType=Convert.ToString(image.ContentLength);
pic.ImageData=新字节[image.ContentLength];
image.InputStream.Read(pic.ImageData,0,
图像长度);
//将图像保存到文件
var filename=image.filename;
变量filePathOriginal=
Server.MapPath(“/Content/Uploads/Originals”);
var filepath缩略图=
Server.MapPath(“/Content/Uploads/Thumbs”);
string savedFileName=Path.Combine(filePathOriginal,
文件名);
image.SaveAs(savedFileName);
//从文件中读回图像并从中创建缩略图
var imageFile=
Combine(Server.MapPath(“~/Content/Uploads/Originals”),文件名);
使用(var srcImage=Image.FromFile(imageFile))
使用(var newImage=新位图(100100))
使用(var graphics=graphics.FromImage(newImage))
使用(var stream=new MemoryStream())
{
graphics.SmoothingMode=SmoothingMode.AntiAlias;
graphics.InterpolationMode=
插值模式。高质量双三次;
graphics.PixelOffsetMode=PixelOffsetMode.HighQuality;
graphics.DrawImage(srcImage,新矩形(0,0,100,
100));
保存(流,ImageFormat.Png);
var thumbNew=File(stream.ToArray(),“image/png”);
pic.ImageData=thumbNew.FileContents;
pic.ImageName=文件名;
}
}
//将模型对象保存到数据库
db.jobs.Add(pic);
ViewBag.Message=“图像上传成功!!”;
int newJobID=0;
尝试
{
//这将使用图像保存模型
db.SaveChanges();
//获取最后插入的行ID
newJobID=pic.id;
//根据上次插入的行获取行,以便根据需要更新imageID
//确保此处使用的列/变量正确
var rowToUpdate=db.jobs.FirstOrDefault(x=>x.id==newJobID);
if(rowToUpdate==null)抛出新异常(“无效id:+newJobID”);
//此变量由数据库上下文跟踪
rowToUpdate.ImageId=newJobID;
var addLoggedInUserToTable=db.tradesusers.FirstOrDefault(e=>e.email==usernameCookie);
如果(addLoggedInUserToTable==null)抛出新异常(“无效id:+usernameCookie”);
addLoggedInUserToTable.lastpostedjobid=newJobID;
如果(addLoggedInUserToTable.email==usernameCookie){
rowToUpdate.jobbyuserid=addLoggedInUserToTable.id;
}
//使用更新的ID重新保存模型
db.SaveChanges();
}
捕获(DbEntityValidationException e)
{
foreach(e.EntityValidationErrors中的变量eve)
{
WriteLine(“状态为“{1}\”的类型为“{0}\”的实体”存在以下验证错误:“,
 @model client.Models.jobs

@{
    ViewBag.Title = "Create Job Details";
}

<br /><br /><br />
@using (Html.BeginForm("Create", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <form class="form-horizontal">
        <fieldset>
            <legend>Job Details</legend>

            <!--Postcode search--><label for="inputEmail" class="col-lg-2 control-label">Job's Name</label>
            <input name="jobname" type="text" placeholder="Job Name" /><br /><br />


            <label for="jobdescription" class="col-lg-2 control-label">Job Description</label>
            <br /><br />
            <div class="col-lg-10">
                <textarea class="form-control" rows="3" name="textArea" placeholder="Write here..."></textarea>
                <span class="help-block">The more details you enter the easier the Tradesmen can work</span>
            </div>

            <br /><br /><br /><br /><br /><br />
            <label for="uploadphotos" class="col-lg-2 control-label">
                Add PHOTOS (Optional)

                @Html.LabelFor(model => model.ImageData, new { @class = "control-label col-md-2" })
                <input name="Image" type="file" />
                @Html.ValidationMessageFor(model => model.ImageData)

                <button type="submit" value="Upload" onclick="location.href='@Url.Action("Create", "Home")'">Upload</button>
                @ViewBag.Message

            </label>


            <br /><br />
            <label for="select" class="col-lg-2 control-label">Tell us which stage you’re at</label>
            <div class="col-lg-10">
                <select class="form-control" name="stage">
                    <option>Preplan</option>
                    <option>already started</option>
                    <option>Almost finished</option>
                    <option>Needs redone fully</option>
                </select>
            </div>
            <br /><br /><br /><br />

            <label for="select" class="col-lg-2 control-label"> When would you like the job to start?*</label>
            <div class="col-lg-10">
                <select class="form-control" name="startjob">
                    <option>ASAP</option>
                    <option>1-2 weeks</option>
                    <option>1 month</option>
                    <option>1+</option>
                </select>
            </div>
            <br /><br /><br /><br />
            <label for="select" class="col-lg-2 control-label">What's your approximate budget?</label>
            <div class="col-lg-10">
                <select class="form-control" name="budget">
                    <option>£0-500</option>
                    <option>£500-100</option>
                    <option>£1000-2000</option>
                    <option>£2000+</option>
                </select>
            </div>


            <br /><br /><br /><br />





    </form>
}


@using (Html.BeginForm("getJobFormValues", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <form class="form-horizontal">
        <input name="jobname" type="text" placeholder="Job Name" /><br /><br />
            <button type="submit" class="btn btn-success btn-lg">Next</button>

     </form>

}

@section Scripts{
   <script>
      debugger
   </script>
}
[AcceptVerbs(HttpVerbs.Post)]
        public ActionResult Create(uploadedfiles pic, HttpPostedFileBase image)
        {
            if (ModelState.IsValid)
            {
                if (image != null)
                {
                    //attach the uploaded image to the object before saving to Database
                    pic.ContentType = Convert.ToString(image.ContentLength);
                    pic.ImageData = new byte[image.ContentLength];
                    image.InputStream.Read(pic.ImageData, 0, image.ContentLength);

                    //Save image to file
                    var filename = image.FileName;
                    var filePathOriginal = Server.MapPath("/Content/Uploads/Originals");
                    var filePathThumbnail = Server.MapPath("/Content/Uploads/Thumbs");
                    string savedFileName = Path.Combine(filePathOriginal, filename);
                    image.SaveAs(savedFileName);

                    //Read image back from file and create thumbnail from it
                    var imageFile = Path.Combine(Server.MapPath("~/Content/Uploads/Originals"), filename);
                    using (var srcImage = Image.FromFile(imageFile))
                    using (var newImage = new Bitmap(100, 100))
                    using (var graphics = Graphics.FromImage(newImage))
                    using (var stream = new MemoryStream())
                    {
                        graphics.SmoothingMode = SmoothingMode.AntiAlias;
                        graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                        graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
                        graphics.DrawImage(srcImage, new Rectangle(0, 0, 100, 100));
                        newImage.Save(stream, ImageFormat.Png);
                        var thumbNew = File(stream.ToArray(), "image/png");
                        pic.ImageData = thumbNew.FileContents;
                        pic.ImageName = filename;
                    }
                }

                //Save model object to database
                db.uploadedfiles.Add(pic);

                ViewBag.Message = "Image Uploaded Successfully!!";

                try
                {
                    db.SaveChanges();

                }
                catch (DbEntityValidationException e)
                {
                    foreach (var eve in e.EntityValidationErrors)
                    {
                        Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
                            eve.Entry.Entity.GetType().Name, eve.Entry.State);
                        foreach (var ve in eve.ValidationErrors)
                        {
                            Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
                                ve.PropertyName, ve.ErrorMessage);
                        }
                    }
                    throw;
                }

                ViewBag.Message = "Image Uploaded Successfully!!";

                return View("JobDetails");
               //return RedirectToAction("getJobFormValues");

            }

            return View("JobDetails");
        }

 [HttpPost]
        public ActionResult getJobFormValues(jobs job)
        {
            string quoteSearch = Request["quoteSearch"];
            string jobname = Request["jobname"];
            string jobmessage = Request["textArea"];
            string uploadedphoto = Request["uploadphotos"];
            string stage = Request["stage"];
            string startjob = Request["startjob"];
            string budget = Request["budget"];
            int imgid = 2;



            //Save model object to database
            //Save personal details model object to database
            if (ModelState.IsValid)
            {

                //Save model object to database
                db.jobs.Add(new jobs
                {
                    name = jobname,
                    jobmessage = jobmessage,
                    //iscomplete
                    //jobbyuserid
                    //responsibletradesmanid
                    //jobmessage
                    stage = stage,
                    startjob = startjob,
                    budget = Convert.ToInt32(budget),
                    ImageId = imgid
                    //ImageName
                    //ImageAlt
                    //ImageData
                    //ContentType
                });

                try
                {
                    db.SaveChanges();
                }
                catch (DbEntityValidationException e)
                {
                    foreach (var eve in e.EntityValidationErrors)
                    {
                        Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
                            eve.Entry.Entity.GetType().Name, eve.Entry.State);
                        foreach (var ve in eve.ValidationErrors)
                        {
                            Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
                                ve.PropertyName, ve.ErrorMessage);
                        }
                    }
                    throw;
                }




            return RedirectToAction("PersonalDetails", new
                {
                    quoteSearch = quoteSearch,
                    jobname = jobname,
                    jobmessage = jobmessage,
                    uploadedphoto = uploadedphoto,
                    stage = stage,
                    startjob = startjob,
                    budget = budget
                });
            }//model state

            return View("JobDetails");

        }
I hope this will help anyone in same situation(i.e. learners!). After hunting around I realised that if (I could be wrong!) working with complex objects such as images text will just be strung along anyway with the .Add and .Save as long as they're part of the Model like so:
namespace client.Models
{
    using System;
    using System.Collections.Generic;

    public partial class jobs
    {
        public int id { get; set; }
        public string name { get; set; }
        public Nullable<bool> iscomplete { get; set; }
        public Nullable<int> jobbyuserid { get; set; }
        public Nullable<int> responsibletradesmanid { get; set; }
        public string jobmessage { get; set; }
        public string stage { get; set; }
        public string startjob { get; set; }
        public int ImageId { get; set; }
        public string ImageName { get; set; }
        public string ImageAlt { get; set; }
        public byte[] ImageData { get; set; }
        public string ContentType { get; set; }
        public string Budget { get; set; }
    }
    }

Then chop up the Action to create,hold,save,image data etc but MOST IMPORTANTLY you do not need to define any fields from the form 
   `(string quoteSearch = Request["quoteSearch"]; etc.)` as they will be updated with the model. So the only difference here is that I have removed the form requests and removed saving single items like  

      //Save model object to database
                    db.jobs.Add(new jobs
                    {
                        name = jobname,

and then only used one action for both image and form data all put together nicely like so:




     [AcceptVerbs(HttpVerbs.Post)]
     public ActionResult Create(jobs pic, HttpPostedFileBase image)
     {
     var context = System.Web.HttpContext.Current;
    var contextBase = new HttpContextWrapper(context);
    ////Pull out the current username from cookie into var
    //usernameCookie = new HttpCookie("CurrentUsername");
    //usernameCookie = contextBase.User.Request.Cookies["CurrentUsername"];

        //Get email from OWIN
        string usernameCookie = contextBase.User.Identity.Name.ToString();

        if (ModelState.IsValid)
        {
            if (image != null)
            {
                //attach the uploaded image to the object before saving to 


        Database
                    pic.ContentType = Convert.ToString(image.ContentLength);
                    pic.ImageData = new byte[image.ContentLength];
                    image.InputStream.Read(pic.ImageData, 0, 
       image.ContentLength);

                    //Save image to file
                    var filename = image.FileName;
                    var filePathOriginal = 
       Server.MapPath("/Content/Uploads/Originals");
                    var filePathThumbnail = 
       Server.MapPath("/Content/Uploads/Thumbs");
                    string savedFileName = Path.Combine(filePathOriginal, 
       filename);
                    image.SaveAs(savedFileName);

                    //Read image back from file and create thumbnail from it
                    var imageFile = 
        Path.Combine(Server.MapPath("~/Content/Uploads/Originals"), filename);
                    using (var srcImage = Image.FromFile(imageFile))
                    using (var newImage = new Bitmap(100, 100))
                    using (var graphics = Graphics.FromImage(newImage))
                    using (var stream = new MemoryStream())
                    {
                        graphics.SmoothingMode = SmoothingMode.AntiAlias;
                        graphics.InterpolationMode = 
        InterpolationMode.HighQualityBicubic;
                        graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
                        graphics.DrawImage(srcImage, new Rectangle(0, 0, 100, 
         100));
                        newImage.Save(stream, ImageFormat.Png);
                        var thumbNew = File(stream.ToArray(), "image/png");
                        pic.ImageData = thumbNew.FileContents;
                        pic.ImageName = filename;
                    }
                }

                //Save model object to database
                db.jobs.Add(pic);

                ViewBag.Message = "Image Uploaded Successfully!!";

                int newJobID = 0;

                try
            {
                //this saves model with image
                db.SaveChanges();

                //get last inserted row ID
                newJobID = pic.id;

                //get row based on last inserted for updating the imageID as we want them correlate
                // make sure you have the right column/variable used here
                var rowToUpdate = db.jobs.FirstOrDefault(x => x.id == newJobID);
                if (rowToUpdate == null) throw new Exception("Invalid id: " + newJobID);
                // this variable is tracked by the db context
                rowToUpdate.ImageId = newJobID;

                var addLoggedInUserToTable = db.tradesusers.FirstOrDefault(e => e.email == usernameCookie);
                if (addLoggedInUserToTable == null) throw new Exception("Invalid id: " + usernameCookie);
                addLoggedInUserToTable.lastpostedjobid = newJobID;

                if (addLoggedInUserToTable.email == usernameCookie) { 
                rowToUpdate.jobbyuserid = addLoggedInUserToTable.id;
            }

                //reasave Model with updated ID
                db.SaveChanges();

            }
            catch (DbEntityValidationException e)
            {
                foreach (var eve in e.EntityValidationErrors)
                {
                    Console.WriteLine("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:",
                        eve.Entry.Entity.GetType().Name, eve.Entry.State);
                    foreach (var ve in eve.ValidationErrors)
                    {
                        Console.WriteLine("- Property: \"{0}\", Error: \"{1}\"",
                            ve.PropertyName, ve.ErrorMessage);
                    }
                }
                throw;
            }

            ViewBag.Message = "Image Uploaded Successfully!!";

            //return View("JobDetails");
            return RedirectToAction("PersonalDetails", new { usernameCookie = usernameCookie });

        }

        return View("JobDetails");
    }`enter code here`

I believe retrieving the images is a bit more straight forward! ;-)