I had a problem with file upload.
Here is my controller
public class StoreManagerController : Controller
{
private StoreContext db = new StoreContext();
//Some actions here
//
// POST: /StoreManager/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Book book, HttpPostedFileBase file)
{
if (ModelState.IsValid)
{
book.CoverUrl = UploadCover(file, book.BookId);
db.Books.Add(book);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.AuthorId = new SelectList(db.Authors, "AuthorId", "Name", book.AuthorId);
ViewBag.GenreId = new SelectList(db.Genres, "GenreId", "Name", book.GenreId);
ViewBag.PublisherId = new SelectList(db.Publishers, "PublisherId", "Name", book.PublisherId);
return View(book);
}
private string UploadCover(HttpPostedFileBase file, int id)
{
string path = "/Content/Images/placeholder.gif";
if (file != null && file.ContentLength > 0)
{
var fileExt = Path.GetExtension(file.FileName);
if (fileExt == "png" || fileExt == "jpg" || fileExt == "bmp")
{
var img = Image.FromStream(file.InputStream) as Bitmap;
path = Server.MapPath("~/App_Data/Covers/") + id + ".jpg";
img.Save(path, System.Drawing.Imaging.ImageFormat.Jpeg);
}
}
return path;
}
}
My Create View
#using (Html.BeginForm("Create", "StoreManager", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
#/* divs here */#
<div class="editor-label">
Cover
</div>
<div class="editor-field">
<input type="file" name="file" id="file"/>
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Description)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
When I try upload a file, I got a default placeholder. So I think the post data is null.
But when I inspected it with browser I got the next post data
------WebKitFormBoundary5PAA6N36PHLIxPJf
Content-Disposition: form-data; name="file"; filename="1.JPG"
Content-Type: image/jpeg
What am I doing wrong?
The first thing I can see that is wrong is this conditional:
if (fileExt == "png" || fileExt == "jpg" || fileExt == "bmp")
This will never return true, because Path.GetExtension includes a '.' in the file extension. It sounds like this might be your main problem as this will simply skip the conditional block and you'll be left with your placeholder. This will need to be changed to:
if (fileExt == ".png" || fileExt == ".jpg" || fileExt == ".bmp")
However, there is so much code in your question that it's difficult to determine whether this is the only problem.
If you still have problems, I would suggest placing a breakpoint in your controller action (you haven't specified whether this is Edit or Create and checking whether the value of file is as expected. You should be able to isolate where the problem is from there and - if you still can't resolve it - will at least be able to narrow your question down a bit.
Related
First and foremost I do not have access to the controller part, the website it's already compiled and I do not have the source just the .dll
#using (Html.BeginForm("Details", "Shop", FormMethod.Post, new { role = "form"}))
{
<p>Select Character:</p>
if (Model.Chars != null && Model.Chars.Count > 0)
{
#Html.AntiForgeryToken()
#Html.ValidationSummary("", new {#class = "text-danger"})
if (Request.IsAuthenticated)
{
#Html.HiddenFor(x => Model.Guid, Model.Guid)
for (var index = 0; index < Model.Chars.Count; index++)
{
var charInfo = Model.Chars[index];
var chdata = charInfo.Name + " (lv." + charInfo.Level + ")";
if (index == 0)
{
<div>
#Html.RadioButtonFor((x) => Model.CharName, charInfo.Name, new {Checked = "checked"}) #chdata
</div>
}
else
{
<div>
#Html.RadioButtonFor((x) => Model.CharName, charInfo.Name) #chdata
</div>
}
}
}
<p/>
<input type="submit" class="position: center !important" value="Confirm Purchase"/>
}
else if (Model.Chars == null)
{
<h4 class="nk-title h4" style="color: red">To purchase items, you must first log in to your account</h4>
}
else
{
<h4 class="nk-title h4" style="color: red">You cannot buy items, you don't have any characters in your account</h4>
}
}
normally it should redirect to Shop when it receives the notification BuyOk as stated in _Layout.cshtml but it doesn't.
#{
var messages = ViewBag.Errors as List<ViewError>;
var notifications = ViewBag.Notifications as List<ViewNotification>;
}
#if (notifications != null && notifications.Count > 0)
{
<div class="alert" style="background: #00ff00">
#foreach (var message in notifications)
{
<span class="closebtn" onclick="this.parentElement.style.display = 'none';">×</span>
string msg;
switch (message)
{
case ViewNotification.BuyOk:
msg = "Purchase complete";
break;
case ViewNotification.ChangePwdOk:
msg = "Password change request successful, description sent to your email";
break;
case ViewNotification.ChangePwdSuccess:
msg = "Password Changed";
break;
case ViewNotification.ChangeEmailSuccess:
msg = "Email has been changed";
break;
default:
msg = "Unknown notification";
break;
}
#msg
}
</div>
}
There are no errors but case ViewNotification.BuyOk: it's not triggered therefore after pressing the submit button the action is completed without any errors but it doesn't redirect to Shop
What I wanna do is to redirect to Shop after I press Confirm Purchase
PS: I only own the compiled code, I tried to decompile with several decompiling software but so far no luck and I cannot see the real controller nor can I edit it
I hope someone can help me with this issue, Thank you
on completion, the website is redirected and isOk=False or isOk=True was added at the end of the URL. I used javascript to create a redirection if isOk=True exists in the URL. Thank you
I have tried this code but I'm unable to save the image/file in the specified folder. What is wrong with the code?
Controller:
public ActionResult Work(Work workmodel, HttpPostedFileBase workpostpath)
{
if (workpostpath != null)
{
// Upload your service images
using (entities = new saabinteriormodel())
{
string workpic = System.IO.Path.GetFileName(workpostpath.FileName);
string workpath = System.IO.Path.Combine(Server.MapPath("~/Content/Images/work/"), workpic);
workpostpath.SaveAs(workpath);
Work work = new Work
{
work_image = "~/Content/Images/work/" + workpic};
workmodel.work_image = work.work_image;
entities.Works.Add(work);
entities.SaveChanges();
}
}
return View();
}
}
View:
#using (Html.BeginForm ("Work", "Admin", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<input id="uploadimage" type="file" />
#ViewBag.Message
<input id="work" type="submit" value="Save Work"/>
}
Thank you.
you're creating a new record in db, but not saving posted files anywhere. try
workpostpath.SaveAs(Server.MapPath("~/folder/file.extension"));
Alsou you could retrieve the posted files from request
HttpPostedFileBase file = Request.Files[0];
I am working on a simple image upload site in which users will have the ability to post comments on the images uploaded to the site, whenever posting a comment I am given this error :
The model item passed into the dictionary is of type '<>f__AnonymousType1`1[System.Int32]', but this dictionary requires a model item of type 'SilkMeme.Models.Meme'.
I know it has something to do with the model being defined at the top of my view being different to the one I am sending the post request to but I'm not entirely sure how to fix it
View
#model SilkMeme.Models.Meme
....
#using (Html.BeginForm("Comment", "Memes", new { id = Model.SilkId }))
{
<label for="thought">Thoughts?</label>
<input type="text" name="thought"/>
<label for="rating">Rating?</label>
<input name="rating" type="range" min="0" max="10" step="1" />
<input type="submit" value="Post Thoughts" />
}
<div class="thoughts">
#foreach (var c in ViewBag.thoughts)
{
<p>- #c.ThoughtWords , #c.ThoughtRating / 10 meme</p>
}
</div>
Controller
public ActionResult Details(int? id)
{
var thoughts = from comment in db.Thoughts where comment.SilkId == id select comment;
ViewBag.thoughts = thoughts;
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Meme meme = db.Memes.Find(id);
if (meme == null)
{
return HttpNotFound();
}
return View(meme);
}
[HttpPost]
public ActionResult Comment(int id)
{
int thoughtid = (from m in db.Thoughts select m).OrderByDescending(e => e.ThoughtId).FirstOrDefault().ThoughtId + 1;
if (Request["thought"].ToString() != "")
{
Thought thought = new Thought()
{
ThoughtId = thoughtid,
SilkId = id,
Meme = db.Memes.Find(id),
ThoughtWords = Request["thought"],
ThoughtRating = Int32.Parse(Request["rating"])
};
db.Thoughts.Add(thought);
}
return View("Details", new { id = id });
}
This line.
return View("Details", new { id = id });
It is basically passing an anonymous object with Id property to your view which is strongly typed to Meme type and expects an object of Meme class.
If you save your data successfully, Ideally,you should do a redirect to the GET action (following PRG pattern)
[HttpPost]
public ActionResult Comment(int id)
{
int thoughtid = (from m in db.Thoughts select m)
.OrderByDescending(e => e.ThoughtId).FirstOrDefault().ThoughtId + 1;
if (Request["thought"].ToString() != "")
{
Thought thought = new Thought()
{
ThoughtId = thoughtid,
SilkId = id,
Meme = db.Memes.Find(id),
ThoughtWords = Request["thought"],
ThoughtRating = Int32.Parse(Request["rating"])
};
db.Thoughts.Add(thought);
db.SaveChanges();
}
return RedirectToAction("Details", new { Id=id });
}
Also, I recommend using MVC Modelbinding to read the submitted form data. You will find a ton of examples on stackoverflow to do that. When using ModelBinding, you can return the posted view model back to the view (with an error message if needed) and the ValidationSummary /ValidationMessgeFor helper methods can show an error message to user as needed.
I got a path from the jquery code URL.createObjectURL(event.target.files[0]);
It returns something like this : blob:http%3A/localhost%3A59105/f7dae0f7-088f-48cf-b446-eeda0bf23705
I tried to save this file like
byte[] data;
using (WebClient client = new WebClient())
{
data = client.DownloadData("blob:http%3A/localhost%3A59105/f7dae0f7-088f-48cf-b446-eeda0bf23705");
}
File.WriteAllBytes(#"~/a.jpg", data);
But it gives an error about the code above:
The URI prefix is not recognized.
How exactly I can copy this file?
Thanks for your suggestions.
1.Create simple GET method
[HttpGet]
public ActionResult GetFile(){
return View();
}
2. Create View with #Html.BeginForm helper
#using (Html.BeginForm("GetFile","YourController", FormMethod.Post, { enctype = "multipart/form-data" }))
{
<input type="file" id="fileup" name="file"/>
<input type="submit" value="Send">
}
Rembember to use name attribute and overloaded version of Html.BeginForm()
3.Get data in Backend
[HttpPost]
public ActionResult GetFile(HttpPostedFileBase file)
{
if (file != null && file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);
var filePath = Path.Combine(Server.MapPath("~/Temp/"), fileName);
file.SaveAs(path);
}
return RedirectToAction("Success");
}
Name in html attribute must have same name as HttpPostedFileBase.
I had this error when use upload file with razor page :
Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
the error occurred here
var uploadedFile = Request.Files[0];
Controller:
[HttpPost]
public ActionResult Create(Category category)
{
if (ModelState.IsValid)
{
var fileSavePath = "";
var fileName = "";
var uploadedFile = Request.Files[0];
fileName = Path.GetFileName(uploadedFile.FileName);
fileSavePath = Server.MapPath("../../Uploads/" + fileName);
uploadedFile.SaveAs(fileSavePath);
db.Categories.Add(category);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(category);
}
View:
#using (Html.BeginForm("Create", "Category", FormMethod.Post,
new { enctype = "multipart/form-data" }))
{
<div class="editor-label">
#Html.LabelFor(model => model.Path)
</div>
<div class="editor-field create-Bt3">
#FileUpload.GetHtml(
initialNumberOfFiles: 1,
allowMoreFilesToBeAdded: false,
includeFormTag: false,
uploadText: "Upload")
</div>
}
The error means, that the Request.Files collection does not contain any item.
You can check with the Count property for the number of files uploaded:
if (Request.Files.Count > 0) {
var uploadedFile = Request.Files[0];
}
Check with fiddler what the browser is sending - maybe its an issue with the FileHelper