为什么不能用这种方式将图像保存到数据库?

时间:2022-08-08 13:18:35

I want to save Image and some other information to databse in my asp.net mc3 project. I've saved Image to database before and it worked. my code in my controller was this:

我想在我的asp.net mc3项目中将图像和其他一些信息保存到数据库中。我之前已将Image保存到数据库并且工作正常。我的控制器中的代码是这样的:

public ActionResult savetodb()
{
    if (Request.Files.Count > 0 && Request.Files[0] != null)
        {
             HttpPostedFileBase file = Request.Files[0];
             var path = Path.Combine(Server.MapPath("~/Content/Image"), file.FileName); 
             file.SaveAs(path);
             byte[] buffer = System.IO.File.ReadAllBytes(path);
             myAd.AdImage = buffer;
             StoreDb.AddToAds(myAd);
             StoreDb.SaveChanges();
        }
        return View();      
    }
}

Now I changed the table and want to save other information more than Image to database. Now my code is like this:

现在我更改了表,并希望将除Image之外的其他信息保存到数据库。现在我的代码是这样的:

 public ActionResult savetodb(AdvertiseView model)
 {
     if (Request.Files.Count > 0 && Request.Files[0] != null)
     {
         HttpPostedFileBase file = Request.Files[0];
         var path = Path.Combine(Server.MapPath("~/Content/Image"), file.FileName);
         file.SaveAs(path);
         byte[] buffer = System.IO.File.ReadAllBytes(path);
         myAd.AdImage = buffer;
     }
     myAd.AdTitle = model.AdTitle;
     myAd.AdContext = model.context;
     myAd.AdScope = model.Scope;
     storedb.AddToAds(myAd);
     storedb.SaveChanges();
     return View();
}

there isn't any problem with other infos but image cant be saved. I understand that

其他信息没有任何问题,但图像无法保存。我明白那个

Request.Files.Count

return 0. I don't know what should I do now. Can anybody help me please? Thanks alot.

返回0.我不知道现在该怎么办。有人可以帮帮我吗?非常感谢。

3 个解决方案

#1


3  

I'd use a view model.

我会使用视图模型。

Let's suppose that you have a domain model first:

我们假设您首先拥有域模型:

public class MyDomainModel
{
    public byte[] AdImage { get; set; }
    public string Description { get; set; }
}

then define a view model:

然后定义一个视图模型:

public class MyViewModel
{
    [Required]
    public HttpPostedFileBase File { get; set; }

    [DataType(DataType.MultilineText)]
    public string Description { get; set; }
}

a controller:

控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new MyViewModel());
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        // TODO: move this mapping logic into a 
        // mapping layer to avoid polluting the controller
        // I would recommend AutoMapper for this purpose
        // http://automapper.org/
        using (var stream = new MemoryStream())
        {
            model.File.InputStream.CopyTo(stream);
            var image = stream.ToArray();
            var domainModel = new MyDomainModel
            {
                AdImage = image,
                Description = model.Description
            };

            // TODO: persist the domain model by passing it to a method
            // on your DAL layer
        }

        return Content("Thanks for submitting");
    }
}

and once the recommended refactoring is complete:

一旦推荐的重构完成:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new MyViewModel());
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        MyDomainModel domainModel = Mapper.Map<MyViewModel, MyDomainModel>(model);

        // TODO: persist the domain model by passing it to a method
        // on your DAL layer

        return Content("Thanks for submitting");
    }
}

and finally a view to allow the user upload the file:

最后一个允许用户上传文件的视图:

@using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <div>
        @Html.LabelFor(x => x.Description)
        @Html.EditorFor(x => x.Description)
    </div>

    <div>
        @Html.LabelFor(x => x.File)
        @Html.TextBoxFor(x => x.File, new { type = "file" })
        @Html.ValidationMessageFor(x => x.File)
    </div>    
    <button type="submit">OK</button>
}

#2


2  

Use HttpPostedFileBase as a parameter on the action.

使用HttpPostedFileBase作为操作的参数。

Use this if you are sending only one file. If you are allowing multiple then you have to use IEnumerable<HttpPostedFileBase> files as the param.

如果您只发送一个文件,请使用此选项。如果你允许多个,那么你必须使用IEnumerable 文件作为参数。

public ActionResult savetodb(HttpPostedFileBase file)
{
    if(file != null)
    {
        var path = Path.Combine(Server.MapPath("~/Content/Image"), file.FileName);
        file.SaveAs(path);
        byte[] buffer = System.IO.File.ReadAllBytes(path);
        myAd.AdImage = buffer;
        StoreDb.AddToAds(myAd);
        StoreDb.SaveChanges();
    }
    return View();      
}

You must also make sure your Form is properly built in your View

您还必须确保在您的视图中正确构建了表单

@using (Html.BeginForm("ActionName", "ControllerName", FormMethod.Post, new { enctype = "multipart/form-data" })) {
....
}

Also be aware that by default, the browser filesize upload limit is 4MB, if you want to upload anything larger than that you will need to configure your settings in the web.config file

另请注意,默认情况下,浏览器文件大小上传限制为4MB,如果您要上传任何大于您在web.config文件中配置设置所需的内容

#3


1  

Add a property to your view model to get this file:

在视图模型中添加属性以获取此文件:

public class AdvertiseView
{
    ...    
    public HttpPostedFileBase NameOfFileInput;
    ....
}

So you can grab the file as a property of the model:

因此,您可以将文件作为模型的属性获取:

if (myAd.NameOfFileInput != null)
{
    var path = Path.Combine(Server.MapPath("~/Content/Image"), myAd.NameOfFileInput.FileName);
    myAd.NameOfFileInput.SaveAs(path);
    byte[] buffer = System.IO.File.ReadAllBytes(path);
    myAd.AdImage = buffer;
}

Of course you can use the same property AdImage and just save it to the right place, without copying the buffer if its of the same type.

当然,您可以使用相同的属性AdImage并将其保存到正确的位置,而不是复制缓冲区(如果它的类型相同)。

#1


3  

I'd use a view model.

我会使用视图模型。

Let's suppose that you have a domain model first:

我们假设您首先拥有域模型:

public class MyDomainModel
{
    public byte[] AdImage { get; set; }
    public string Description { get; set; }
}

then define a view model:

然后定义一个视图模型:

public class MyViewModel
{
    [Required]
    public HttpPostedFileBase File { get; set; }

    [DataType(DataType.MultilineText)]
    public string Description { get; set; }
}

a controller:

控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new MyViewModel());
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        // TODO: move this mapping logic into a 
        // mapping layer to avoid polluting the controller
        // I would recommend AutoMapper for this purpose
        // http://automapper.org/
        using (var stream = new MemoryStream())
        {
            model.File.InputStream.CopyTo(stream);
            var image = stream.ToArray();
            var domainModel = new MyDomainModel
            {
                AdImage = image,
                Description = model.Description
            };

            // TODO: persist the domain model by passing it to a method
            // on your DAL layer
        }

        return Content("Thanks for submitting");
    }
}

and once the recommended refactoring is complete:

一旦推荐的重构完成:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new MyViewModel());
    }

    [HttpPost]
    public ActionResult Index(MyViewModel model)
    {
        if (!ModelState.IsValid)
        {
            return View(model);
        }

        MyDomainModel domainModel = Mapper.Map<MyViewModel, MyDomainModel>(model);

        // TODO: persist the domain model by passing it to a method
        // on your DAL layer

        return Content("Thanks for submitting");
    }
}

and finally a view to allow the user upload the file:

最后一个允许用户上传文件的视图:

@using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
    <div>
        @Html.LabelFor(x => x.Description)
        @Html.EditorFor(x => x.Description)
    </div>

    <div>
        @Html.LabelFor(x => x.File)
        @Html.TextBoxFor(x => x.File, new { type = "file" })
        @Html.ValidationMessageFor(x => x.File)
    </div>    
    <button type="submit">OK</button>
}

#2


2  

Use HttpPostedFileBase as a parameter on the action.

使用HttpPostedFileBase作为操作的参数。

Use this if you are sending only one file. If you are allowing multiple then you have to use IEnumerable<HttpPostedFileBase> files as the param.

如果您只发送一个文件,请使用此选项。如果你允许多个,那么你必须使用IEnumerable 文件作为参数。

public ActionResult savetodb(HttpPostedFileBase file)
{
    if(file != null)
    {
        var path = Path.Combine(Server.MapPath("~/Content/Image"), file.FileName);
        file.SaveAs(path);
        byte[] buffer = System.IO.File.ReadAllBytes(path);
        myAd.AdImage = buffer;
        StoreDb.AddToAds(myAd);
        StoreDb.SaveChanges();
    }
    return View();      
}

You must also make sure your Form is properly built in your View

您还必须确保在您的视图中正确构建了表单

@using (Html.BeginForm("ActionName", "ControllerName", FormMethod.Post, new { enctype = "multipart/form-data" })) {
....
}

Also be aware that by default, the browser filesize upload limit is 4MB, if you want to upload anything larger than that you will need to configure your settings in the web.config file

另请注意,默认情况下,浏览器文件大小上传限制为4MB,如果您要上传任何大于您在web.config文件中配置设置所需的内容

#3


1  

Add a property to your view model to get this file:

在视图模型中添加属性以获取此文件:

public class AdvertiseView
{
    ...    
    public HttpPostedFileBase NameOfFileInput;
    ....
}

So you can grab the file as a property of the model:

因此,您可以将文件作为模型的属性获取:

if (myAd.NameOfFileInput != null)
{
    var path = Path.Combine(Server.MapPath("~/Content/Image"), myAd.NameOfFileInput.FileName);
    myAd.NameOfFileInput.SaveAs(path);
    byte[] buffer = System.IO.File.ReadAllBytes(path);
    myAd.AdImage = buffer;
}

Of course you can use the same property AdImage and just save it to the right place, without copying the buffer if its of the same type.

当然,您可以使用相同的属性AdImage并将其保存到正确的位置,而不是复制缓冲区(如果它的类型相同)。