I am trying to upload an image to a SQL database using ASP.NET MVC. The database BeforeImage remains as null although I am receiving no error a few file sizes and formats. Thanks
public class Job
{
public int ID { get; set; }
public byte[] BeforeImage { get; set; }
public byte[] AfterImage { get; set; }
}
View model:
public class BeforePhotoVM
{
public int ID { get; set; }
public HttpPostedFileBase BeforeImage { get; set; }
}
Get:
public ActionResult AddBefore(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var job = db.Jobs.Find(id);
var BeforeVM = new BeforePhotoVM();
//vm = db.Jobs.Find(id);
return View("Job2", BeforeVM);
}
Post:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult AddBefore([Bind(Include = "ID,BeforeImage")] BeforePhotoVM BeforeVM)
{
var job = db.Jobs.Find(BeforeVM.ID);
if (ModelState.IsValid)
{
byte[] BeforeImage = new byte[BeforeVM.BeforeImage.InputStream.Length];
BeforeVM.BeforeImage.InputStream.Read(BeforeImage, 0, BeforeImage.Length);
job.BeforeImage = BeforeImage;
db.Entry(job).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("AddBefore", new { id = job.ID });
}
return View("Job");
}
Look, you are doing too many things for something that should be simple.
Plus, next time, post ur html code with ur ajax.
Let me try to help you.
At your asp.net page.
your Html.Begin form should have the enctype = "multipart/form-data"
like this
#using (Ajax.BeginForm("Here goes ur action", "Here goes ur controller", new AjaxOptions { OnSuccess = "something with sucess" }, new { enctype = "multipart/form-data" }))
with that in mind
lets got to ur model
public byte[] Photo { get; set; }
ok ... now lets finish with the controller
public ActionResult Cadastro(YOURMODEL _model, HttpPostedFileBase file)
{
_model.Photo = new byte[file.ContentLength];
see, ur controller recives the HttpPostedFileBase and u can access creating a new byte.. but remember.. in ur asp.net code the file name has to be the same in ur controller as it bellow
The rest is with u
Hope this will help you.
Related
I've been struggling with this problem for a while now and I can't find any solution on that solves it for me.
I'm trying to add a string to my model in a view, however when the model gets returned to my HttpPost everything is null except for the string that I'm trying to fill
My model looks like this
namespace WhatsUp.Models {
public class ChatModel
{
public Account user { get; set; }
public Contact contact { get; set; }
public Chat chatA { get; set; }
public Chat chatB { get; set; }
public string newMessage { get; set; }
public ChatModel() { }
public ChatModel(Account user, Contact contact, Chat chatA, Chat chatB)
{
this.user = user;
this.contact = contact;
this.chatA = chatA;
this.chatB = chatB;
}
}
}
My controller looks like this
namespace WhatsUp.Controllers
{
public class ChatsController : Controller
{
IMessageRepository repository = new DbMessageRepository();
IContactRepository contactRepository = new DbContactRepository();
IAccountRepository accountRepository = new DbAccountRepository();
IChatRepository chatRepository = new DbChatRepository();
// GET: Chats
public ActionResult Index()
{
return View();
}
public ActionResult Chat(int contactId)
{
Account user = accountRepository.GetAccount(User.Identity.Name);
Contact contact = contactRepository.GetContact(contactId);
Chat chatA = chatRepository.GetChat(user.id, contact.accountId ?? default(int));
if(chatA == null)
{
chatRepository.CreateChat(user.id, contact.accountId ?? default(int));
}
Chat chatB = chatRepository.GetChat(contact.accountId ?? default(int), user.id);
if(chatB == null)
{
chatRepository.GetChat(user.id, contact.accountId ?? default (int));
}
ChatModel chatModel = new ChatModel(user, contact, chatA, chatB);
return View(chatModel);
}
[HttpPost]
public ActionResult Chat(ChatModel chatModel)
{
repository.SendMessage(new Message(0, chatModel.newMessage, chatModel.chatA.Id));
ModelState.Clear();
return View(chatModel);
}
}
}
And my view
#using WhatsUp.Models
#model ChatModel
#{
ViewBag.Title = "Chat";
}
<h2>Chat with #Model.contact.name</h2>
<div id="chatWindow" style="overflow-y:auto; overflow-x:hidden; height:500px;">
<script>
var element = document.getElementById('chatWindow');
element.scrollTop = element.offsetHeight
</script>
</div>
#using (Html.BeginForm())
{
#Html.TextAreaFor(x => x.newMessage, new { #class = "form-control"})
<input type="submit" value="Send" class="btn btn-primary" />
}
Always use a ViewModel for that kind of things. Follow this steps:
First, create a ViewModel that will contain your message and the chat ids.
Second, ake the ids as a hidden field in your view.
Last thing is, in your POST action, to make sure to get each Chat instance via their id before sending the message.
I want to use create, but when I post my values don´t register in my database also in my view too.
Model:
public class WebPages
{
[Key]
public DateTime DomainStart { get; set; }
public DateTime DomainExp { get; set; }
}
ViewModel:
public class WebPagesViewModel
{
public DateTime DomainStart { get; set; }
public DateTime DomainExp { get; set; }
}
Post Controller:
[HttpPost]
public async Task<ActionResult>Create([Bind(Include = "DomainName,DomainExp")] WebPagesViewModel model)
{
if (ModelState.IsValid)
{
model.WC();
await db.SaveChangesAsync();
return RedirectToAction("Index", "WebPages");
}
return View(model);
}
Extension method of my post:
public static WebPagesViewModel WC(this WebPagesViewModel model)
{
var wb= new WebPages
{
DomainStart = model.DomainStart,
DomainExp = model.DomainExp,
};
db.WebPagesList.Add(wb);
db.SaveChangesAsync();
return model;
}
So try catch pass, and I get a success post, but values don´t save on database, what I´m doing wrong?
Thankyou in advance!
[HttpPost]
public async Task<ActionResult>. Create([Bind(Include = "DomainName,DomainExp,DomainEmails,DomainUsers,DomainPasswords,ClientsName")]
Change your post method to
[HttpPost]
public async Task<ActionResult> Create([Bind(Include = "DomainName,DomainExp,DomainEmails,DomainUsers,DomainPasswords,ClientsName")]
//model.WebPagesCreate();
pass parameter to the above method
if you want to see error
db.SaveChangesAsync()
change to
db.SaveChanges()
And also check bind values are correctly coming from the view
Add this to view model
public WebPagesViewModel()
{
AvalilableClients = new List<SelectListItem>();
}
public List<SelectListItem> AvalilableClients { get; set; }
Add your client list to Model
foreach (var client in Clients )
{
model.WebPagesViewModel.Clients .Add(item: new SelectListItem()
{
Text = dept.DepartmentName,
Value = dept.DepartmentId.ToString()
});
}
Then Pass model to View Then populate the view drop down using Html Healper
#Html.DropDownListFor(model => model.SelectedClient, Model.AvalilableClients , new { #class = "form-control" })
Finally I solve it, the problem was that my datetime is not setted correctly in my extension method, so I change DomainStart = model.DomainStart to DomainStart = Datetime.now
I am trying to populate a web grid view with static data but I am not having any luck.
I always get the error:
"A data source must be bound before this operation can be performed".
I understand where the error is coming from by setting up breakpoints. Basically, when the page is loaded up, the code never accesses the Account() function. Since it doesn't do that, allFiles is never initialized and returned.
Would the best way to do this be to call Action() from the View and initialize all files? I've read other questions regarding the same error but no one highlighted the fact that the code is not accessing the controller function.
Here is the Controller:
public ActionResult Account()
{
FileModel file = new FileModel();
List<FileModel> allFiles = new List<FileModel>();
file.FileID = "1";
file.UserID = "1";
var data = allFiles;
return View(data);
}
Here is the Model
public class FileModel
{
public string FileID { get; set; }
public string UserID { get; set; }
public string FileName { get; set; }
public string AddedOn { get; set; }
public int Downloads { get; set; }
public int Show { get; set; }
}
Here is the View
#model IEnumerable<GridTest1.Models.FileModel>
#{
ViewBag.Title = "Files";
WebGrid grid = new WebGrid(Model);
}
<h2>People</h2>
#grid.GetHtml(columns: new [] {
grid.Column("FileID"),
grid.Column("UserID")
})
your controller coding order is wrong. Check the following code
public ActionResult Account()
{
// Assign a value to class
FileModel file = new FileModel();
file.FileID = "1";
file.UserID = "1";
file.FileName = "Text.txt";
file.AddedOn = "AddedOn";
// Create instance for all file
List<FileModel> allFiles = new List<FileModel>();
// Add file model to list
allFiles.Add(file);
// Pass the file list to view
return View(allFiles);
}
View
#model List<GridTest1.Models.FileModel>
#{
ViewBag.Title = "Files";
WebGrid grid = new WebGrid(Model);
}
#grid.GetHtml(columns: new[] {
grid.Column("FileID"),
grid.Column("UserID"),
grid.Column("FileName"),
grid.Column("AddedOn"),
})
This will work
I started working with asp.net and I have encountered a problem when I try to edit multiple values from a table. I have a bookmark tables which is connected to another tag table, with an 1 : N relationship. My problem is when I want to edit already existing tags associated with an existing url. I can display them on the page but when I try to post the edited data I don't know how to pick it up in the controller. So far I have managed to send them back as a string but I doubt that is the solution since I have to edit all the data again later. I want to replace the existing values in the Tag table with the edited data. Here are my model and controller code snippets.
Bookmark model:
public int id { get; set; }
public string url { get; set; }
public virtual ICollection<Tag> tags { get; set; }
Tag model:
public int id { get; set; }
public string name { get; set; }
public virtual Bookmark bookmark { get; set; }
public string user { get; set; }
Controller:
public ActionResult Edit(int id)
{
var editBookmark = adc.Bookmarks.Single(x => x.id == id);
var query_where2 = from a in adc.Tags
where a.bookmark.id == id
select a;
BookmarkTag bkTag = new BookmarkTag();
bkTag.bookmark = new List<Bookmark>();
bkTag.bookmark.Add(editBookmark);
bkTag.tag = query_where2.ToList();
return View(bkTag.tag);
}
//
// POST: /SavedBookmark/Edit/5
[HttpPost]
public ActionResult Edit(int id, ICollection<FormCollection> tag)
{
try
{
return View();
}
catch
{
return View();
}
Html code:
#using (Html.BeginForm("edit", "SavedBookmark"))
{
#Html.AntiForgeryToken()
if (Model != null) {
var aa= Model.First();
#Html.TextBox("test2", aa.bookmark.url);
List<BookIT2.Models.Tag> allTags = new List<BookIT2.Models.Tag>();
allTags = Model.ToList();
for (int i = 0; i < allTags.Count; i++)
{
if (!allTags[i].name.IsEmpty())
{
#Html.TextBox(allTags[i].name, allTags[i].name);
#Html.Hidden(allTags[i].id.ToString(), allTags[i].id);
#Html.Hidden(allTags[i].user, allTags[i].user)
#Html.Hidden(allTags[i].bookmark.id.ToString(), allTags[i].bookmark.id.ToString())
}
}
#Html.Label("Additional tag")
#Html.TextBox("additionalTag")
<input type="submit" value="edit" />
}
In short: I can't get any values in the http post ICollection, it's always null.
Here is the updated code:
#using (Html.BeginForm("edit", "SavedBookmark"))
{
#Html.AntiForgeryToken()
if (Model != null)
{
for (int i = 0; i < Model.tag.Count; i++)
{
if (!Model.tag[i].name.IsEmpty()) {
#Html.Hidden(Model.tag[i].id.ToString(), Model.tag[i].id);
#Html.Label("name");
#Html.TextBox(Model.tag[i].name, Model.tag[i].name);
#Html.Hidden(Model.tag[i].bookmark.id.ToString(), Model.tag[i].bookmark.id);
#Html.Hidden(Model.tag[i].user, Model.tag[i].user);
}
}
#Html.TextBox(Model.bookmark.id.ToString(), Model.bookmark.url);
<input type="submit" value="edit" />
}
}
Model class:
public class TestBookmark
{
public Bookmark bookmark{get; set;}
public List<Tag> tag {get; set;}
}
[HttpPost]
public ActionResult Edit(TestBookmark edit)
{}
Don't really understand why you're doing it this way. I would like to suggest you totally different approach.
First:
Create a class with all the fields you want in your view.
Second:
Use this class as the MODEL in your View
Third:
In the controller, in the POST function user your class as the only one parameter of that function.
Would someone mind to guide me, how to save file into my database, and also retrieve it if possible,
I still new to this C# and MVC 4.
my databse Assignment contain a attribute call FileLocation which is varBinary ( MAX) .
Model
public partial class Assignment
{
public Assignment()
{
this.CourseAvailables = new HashSet<CourseAvailable>();
}
public string AssignmentID { get; set; }
public Nullable<System.DateTime> SubmissionDate { get; set; }
public string Status { get; set; }
[Range(0,100, ErrorMessage="Only Value between 0-100 is accepted.")]
public Nullable<decimal> Mark { get; set; }
public string Comments { get; set; }
public byte[] FileLocation { get; set; }
public virtual ICollection<CourseAvailable> CourseAvailables { get; set; }
}
}
Control
[HttpPost]
public ActionResult Create(Assignment assignment)
{
if (ModelState.IsValid)
{
db.Assignments.Add(assignment);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(assignment);
}
View
#using(Html.BeginForm("Create","Assignment",FormMethod.Post,new {enctype="multipart/form-data"}))
{
...
<div class="editor-field">
<%: Html.TextBoxFor(model => model.FileLocation, new { type="file"})%>
<%: Html.ValidationMessageFor(model => model.FileLocation) %>
</div>
...
}
You need a bit more processing here. Uploaded files come in as a HttpPostedFileBase, not a byte[] so you need to get the byte[] from the HttpPostedFileBase's InputStream, like so:
[HttpPost]
public ActionResult Create(Assignment assignment)
{
if(Request.Files != null && Request.Files.Count == 1)
{
var file = Request.Files[0];
if (file != null && file.ContentLength > 0)
{
var content = new byte[file.ContentLength];
file.InputStream.Read(content, 0, file.ContentLength);
assignment.FileLocation = content;
// the rest of your db code here
}
}
return RedirectToAction("Create");
}
P.S. That model looks suspiciously like an Entity object. It's a tremendously bad idea to use Entity objects as your models. Try making an intermediary model and using that to render your data instead.
Edit
In your view, change this:
<%: Html.TextBoxFor(model => model.FileLocation, new { type="file"})%>
to this:
<input type="file" id="file" name="file" />
The error you're getting is because the model binder is mistakenly trying to bind your FileLocation field on the page (HttpPostedFileBase type) to the FileLocation field in your model (byte[] type).
In Asp.Net MVC we have to use HttpPostedFileBase for Uploaded files as shown below :-
[HttpPost]
public ActionResult Create(Assignment assignment, HttpPostedFileBase file)
{
if (file != null)
{
int byteCount = file.ContentLength; <---Your file Size or Length
.............
.............//You can store file in database//
}
return RedirectToAction("Create");
}