Upload file along with text in Create view - asp.net-mvc

My first .Net/MVC project, I generated a view that allows me to list, edit, and create items in a database, and I would like to add a file upload control to the Create page, to just upload one file.
I understand that within [HttpPost] I need "public ActionResult Index(HttpPostedFileBase file)" but my current [HttpPost] is like this: "public ActionResult Create(lm_pics lm_pics)".

Why do you have 2 file inputs? Why do you have 2 forms? Isn't the first form sufficient (assuming of course you add the enctype="multipart/form-data" attribute to it as you cannot upload files without it)?:
#model PictureUploader_MVC.Models.lm_pics
#{
ViewBag.Title = "Create";
}
<h2>Upload Picture</h2>
#using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>lmit_pics</legend>
<div class="editor-label">
#Html.LabelFor(model => model.brand)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.brand)
#Html.ValidationMessageFor(model => model.brand)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.enabled)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.enabled)
#Html.ValidationMessageFor(model => model.enabled)
</div>
<div>
<label for="file">Filename:</label>
<input type="file" name="file" id="file" />
</div>
</fieldset>
<button type="submit">Create</button>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
and your controller action that will process the form submission:
[HttpPost]
public ActionResult Create(lm_pics lm_pics, HttpPostedFileBase file)
{
...
}

Related

using viewmodel with create view

I have a ViewModel with two models in it which works find when displaying data. My problem is I want to add a foreach() within the Create.cshtml file. Any ideas?
----Create.cshml-----
#model demo.Models.ViewModel
#{ ViewBag.Title = "Create Reference";}<h2>Create</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Submission Form </legend>
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Title)
#Html.ValidationMessageFor(model => model.Title)
</div>
<div class="editor-field">
<!-- iterate through ExternalContentModel and make checkboxes. -->
#foreach (var item in Model.ExternalContentModel)
{
<label class="checkbox">
<input type="checkbox" name="users" value="#item.auth_lname"> #item.auth_lname
</label>
}
</div>
<div class="editor-label">
#Html.LabelFor(model => model.OrganizationName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.OrganizationName)
#Html.ValidationMessageFor(model => model.OrganizationName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Address)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Address)
#Html.ValidationMessageFor(model => model.Address)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.City)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
------Controller-----
//
// GET: /Create
public ActionResult Create() <=== can this be the problem????
{
demo.Models.ViewModel vm = new demo.Models.ViewModel();
vm.ExternalContentModel = _repository.ExternalContent();
// Return the content from the External Model to the Create.
return View(vm);
}
//
// POST: /MailingReferences/Create
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Reference reference) <=== can this be the problem????
{
if (ModelState.IsValid)
{
db.References.Add(reference);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(reference);
}
If you have different models then why don't you just create a editor templates for each model?
You can do this by creating a folder called "EditorTemplates" in the same folder your Create.cshtml view lives in. Now add a view for your model into that folder. The view should be named the same as your model class. E.g. a class called FooBarModel would have an editor template called FooBarModel.cshtml.
You would then just use the editor template by doing #Html.EditorFor(x => x.FooBar)

How to get a form value in another form value submission

I had username and password in first form and retrieve password in another form , in which i want userame entered in first form in submission of second form.
#model Network.Models.LoginDetail
<script type="text/javascript">
</script>
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<p>
Please enter your user name and password. #Html.ActionLink("Register", "Register") if you don't have an account.
</p>
#using (Html.BeginForm("Index","Student",FormMethod.Post)) {
<div>
<fieldset>
<legend>Account Information</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Username)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Username)
#Html.ValidationMessageFor(model => model.Username)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Password)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Password)
#Html.ValidationMessageFor(model => model.Password)
</div>
<p>
<input type="submit" value="Log in" style="width: 200px"/>
</p>
#ViewBag.Message
</fieldset>
</div>
}
#using (Html.BeginForm("RetrievePassword","Student",FormMethod.Post)) {
<p>
Forgot password? <input type="submit" onclick="updateUsername();"value="Click Here" style="width: 150px"/> Entering your username to retrieve your password.
</p>
#Html.HiddenFor(model => model.Username)
}
How can we acheive this, i tried in javascript capturing of username in hiddenfield but not working.
Or can form within form be used to acheive this.
Please provide a solution.
Thanks,
Michaeld
At the post method of "Index" action in "Stundent" controller you will be able to get the value either in formcollection or in LoginDetail object form.
Example:
public ActionRestult Index(FormCollection FC)
{
string UserName = FC["Username"];
string Password = FC["Password"];
}
Or Alternatively
public ActionRestult Index(LoginDetail obj)
{
string UserName = obj.Username;
string Password = obj.Password;
}
This will fix your concern.

Adding model with user input and hard coded values

Okay so I am using the MVC framework. I have a view for adding a model. At the moment I am using the default "Create" controller.
I want to be able to create a model with my own variables pre-set. For example the model.UserId I want to set to the users Id. I want some values to be inputed by the user and I want some to be already set. Is there a way I could do something like this
(pseudo code)
model.matchId = 123
model.prediction type = "user input"
add model
here is my current code below
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>Predictions</legend>
<div class="editor-label">
#Html.LabelFor(model => model.MatchId, "Match")
</div>
<div class="editor-field">
#Html.DropDownList("MatchId", String.Empty)
#Html.ValidationMessageFor(model => model.MatchId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.UserId, "User")
</div>
<div class="editor-field">
#Html.DropDownList("UserId", String.Empty)
#Html.ValidationMessageFor(model => model.UserId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Type)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Type)
#Html.ValidationMessageFor(model => model.Type)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Prediction)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Prediction)
#Html.ValidationMessageFor(model => model.Prediction)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
In the controller, you would set the values on the model before returning it to the View.
public class HomeController : Controller
{
public ActionResult About()
{
var model = new MyModel();
model.SomeId = 123;
model.SomeOtherProperty = "Hello World";
return View(model);
}
}

Can not upload file/image

I am working on a simple form where user will enter some data and select a file to upload.
But i can not get this working..
For some reason when I click save, the file does not go to the controller.
Here is some code.
#using (Ajax.BeginForm("Add", "Category", null, new AjaxOptions
{
UpdateTargetId = "upload-message",
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
OnSuccess = "uploadSuccess"
}, new { id = "AddCategoryForm", enctype = "multipart/form-data" }))
{
<div class="editorLabel">
#Html.LabelFor(m=>m.CategoryName)
</div>
<div class="editorText">
#Html.TextBoxFor(m=>m.CategoryName)
</div>
<div class="editorLabel">
#Html.LabelFor(m => m.Description)
</div>
<div class="editorText">
#Html.TextAreaFor(m => m.Description)
</div>
<div class="editorLabel">
#Html.LabelFor(m => m.IconPath)
</div>
<div class="editorText">
<input type="file" id="file" name="file" />
</div>
<div class="editorLabel">
#Html.LabelFor(m => m.IsActive)
</div>
<div class="editorText">
#Html.CheckBoxFor(m=>m.IsActive)
</div>
<p>
<input type="submit" id="submit" value="Save" />
</p>
}
Controller:
[HttpPost]
public ActionResult Add(HttpPostedFileBase file,CategoryViewModel model)
{
if (ModelState.IsValid)
{
System.IO.FileInfo info = new FileInfo(file.FileName);
string ext = info.Extension;
//other code
}
}
Here in the controller, file is always null.
Where am I doing wrong??
First swapping parameters of your controller to have it as follows:
[HttpPost]
public ActionResult Add(CategoryViewModel model, HttpPostedFileBase file)
For example.
If this won't work for some reason, make the file you uploading part of your model (CategoryViewModel) and have controller signature as follows:
[HttpPost]
public ActionResult Add(CategoryViewModel model)
For example. That way file will be returned as part of the model and you will extract it as one of model's properties. This will work (it worked for me).
Hope this helps.

Form not 'POST'ing with a FormMethod.Post attribute

I have a form in a view like so:
#using (Html.BeginForm("CreateDTActionBasedOnSelectedMetaAction", "TestCase", FormMethod.Post))
And an action method with the following signature:
[AcceptVerbs( new string[]{"GET","POST"})]
public void CreateDTActionBasedOnSelectedMetaAction(FormCollection fc)
However, when the 'submit' button (located in the form) is clicked, it comes to the action method, but the Request.HttpMethod property shows a "GET", and obviously the form data is then not available in the FormCollection object as it wasn't posted.
Any thoughts?
UPDATE:part of the View:
#using (Html.BeginForm("CreateDTActionBasedOnSelectedMetaAction", "TestCase", FormMethod.Post)){
<fieldset>
<legend>Test Case</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
<p>#DTContext.CurrentTestCase.Name</p>
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Criteria)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Criteria)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.DTTestCaseReqSet.DTMetaReqProcessor.DTMetaActions)
</div>
<div class="editor-field">
#Html.ListBox("MyListBox", new SelectList(Model.DTTestCaseReqSet.DTMetaReqProcessor.DTMetaActions.Where(p => p.Enabled == true), "NameWithID", "NameWithID"));
</div>
<p>
<input type="submit" value="Select" />
</p>
</fieldset>
}
UPDATE2:
Okay that was silly. Turns out that the app has a custom routing system written by another dev, which expected a certain parameter in the query string to be preserved, which my code wasn't doing. This resulted in the routing system taking the POST from the form, being unable to find a suitable method, it converted it to a GET, which then found my actionmethod.
I would request this question to be deleted.
Create two action methods. One for get and one for post.
[HttpPost]
public void CreateDTActionBasedOnSelectedMetaAction(FormCollection fc)
[HttpGet]
public void CreateDTActionBasedOnSelectedMetaAction()

Resources