Post a file from View to Controller - asp.net

I have following code in view :
<div>
<input type="file" name ="file" onchange="location.href='<%: Url.Action("ChangeImage", new{Id = Model.Id}) %>'" />
</div>
And in Controller I have the ChangeImage method :
public ActionResult ChangeImage(FormCollection collection, int Id,Products products)
{
var file = Request.Files["file"];
//Do something
}
But the selected file does not post to the controller. What is the problem? How can I send the file content to the controller to use it?

Because you are not posting the form data is probably the reason.
When creating an MVC form for submitting files you must specify the "enctype", with the helpers you can do this:
#using (Html.BeginForm("MyAction", "MyController", new { #Id = Model.Id }, FormMethod.Post, new { name = "Form", enctype = "multipart/form-data" }))
{
//all form fields code in here
}
Then you will want to change your javascript to post the form, something like:
document.forms[0].submit();//assuming you only have one form
Also, your action parameters don't seem to match anything. Specifically ShopID and products. You will probably get an error because you don't have default values for them. I am not 100% sure on that part though. Or maybe you have then in other parts of your form, so it might be ok

Related

passing data by POST method between views in asp.net

I have data in a particular view page(collected from the user) which I need to send to another view page which has a form needing this data. Now I can use:-
1. post method of javascript(jquery)
$().redirect('/Events/Create', {'arg1': 'value1', 'arg2': 'value2'});
or
A form:-
$('#inset_form').html(' < form action="/Events/Create"
method="post"style="display:none;">< input type="text" name="lat"
value="' + latitude + '" />< /form>');
document.forms['vote'].submit();
Now my question is, which method should be chosen?
Also, the '/Events/Create' page has form in the following way:-
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="editor-label">
#Html.LabelFor(model => model.lat)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.lat)---------> THIS field accepts the POSTed data
#Html.ValidationMessageFor(model => model.lat)
</div>
<div>
....OTHER INPUT FIELDS.....
</div>
<p>
<input type="submit" value="Create" />
</p>
}
So, my next question is how do I make the text box 'lat' created by #Html.EditorFor in the form show the POSTed data as its default value. Then, the user can fill other fields and then submit the form.
As per HTTP standards, if a call is not changing the state of the website (i.e. data), you should use a GET request. This means you should provide the user with a link including the proper query string to populate the form on the /Events/Create page.
Also, keep in mind you never send data from view to view in MVC. Everything goes through a controller action so make sure your "Create" action on the "Events" controller accepts the proper arguments to populate the form for submission. If the Model.lat variable has a value in it when rendering the view, the text box will be prepopulated with that value.
Why do you want to POST the data to the second form? If you want to show the form and load it with default values, create a GET action method for it and pass the default values in the url. Although there's nothing stopping you having two POST methods for the same view, the normal approach would be to load the form using a GET, then POST back the data after editing.
[HttpGet]
public ActionResult Create(string lat)
{
MyView view = new MyView();
view.lat = lat;
View(view);
}
[HttpPost]
public ActionResult Create(MyView view)
{
//process posted data after editing
}
The view object here is a ViewModel class containing properties for the data that you will edit on the form. Make your View strongly typed to this ViewModel type.
To invoke the GET method from your jQuery (above):
window.location = "Events/Create?lat=myValue";

Ajax.BeginForm using ASP.NET MVC 3 - Nothing Happens

All I need to do is create a simple search page that displays results in a partial view. I have a search text box and a search submit button. I followed a tutorial I found online that seems very easy and quick to implement, but I am missing something here. When I click the search button nothing happens. Any ideas on what I am doing wrong or missing would be greatly appreciated.
I include the following script files in the main layout page
#Script("jquery-1.5.1.min.js")
#Script("modernizr-1.7.min.js")
#Script("jquery-ui.min.js")
#Script("jquery.unobtrusive-ajax.js")
#Script("jquery.validate.min.js")
#Script("jquery.validate.unobtrusive.min.js")
#helper Script(string scriptName)
{
<script src="#Url.Content("~/Scripts/" + scriptName)" type="text/javascript"> </script>
}
The main search view is called AdminMenu. This is listed under a Area in my project called Admin.
The following code in my main view
#using (Ajax.BeginForm("AdminSearch", "AdminMenu", new {area = "Admin"}, new AjaxOptions { HttpMethod = "GET", InsertionMode = InsertionMode.Replace, UpdateTargetId = "searchResults"}))
{
<input type="text" name="q" />
<input type="submit" value="Search"/>
}
<div id="searchResults">
</div>
Code in my partial view _adminSearch
<div id="searchResults">
<div class="entitybox">
#{
var grid = new WebGrid(
Model,
defaultSort: "Name", canPage: false
);
}
#grid.GetHtml(
tableStyle: "_tableGrid",
columns: grid.Columns
(
grid.Column("Name", "Name", item => #Html.ActionLink((string)item.Name, "SelectRecord", new { controller = "Menu", agencyKey = item.Id, name = item.Name }))
)
)
</div>
</div>
Code for the Controller
public class AdminMenuController : Controller
{
public ActionResult AdminMenu()
{
return View();
}
public PartialViewResult AdminSearch(string q)
{
Records results = AgencyBusiness.GetAdminSearch(q);
return PartialView("_adminSearch", results);
}
}
When the search button is clicked nothing happens. If you put a break point on the AdminSearch method in the controller class it never gets hit.
Thanks in advance for your time.
I think the problem is that you have a div called "searchResults" in both your main view and partial view. Ajax is probably getting confused.
You need to include the MicrosoftAjax.js file when using Ajax.BeginForm.
I solved this issue. Odd thing. I used a shared view to show the current user at the top of the view using the following line.
#RenderPage("~/Views/Shared/_LoginBar.cshtml")
The main problem was that #Ajax.BeginForm function did not output any form tags to the browser.
By using the following line instead, the form tags appeared in the HTML source and the ajax function worked.
#Html.Partial("~/Views/Shared/_LoginBar.cshtml")

Return the view with the css class in the controller of asp.net mvc c#

I used to put the class of css in the action link like this:
<%: Html.ActionLink("Us", "Us", "Por", new { #class = "contactus" })%>
The purpose that I put the class is for the pop up of color box.
Now I have an action in my controller that return the result to the view like this :
return Redirect(#"~/Test/TestFirst?msg=Please complete all the information.");
Question : How can I add class = "contactus" to the return of my action ?
Thanks in advanced.
The Controller cannot and should not add css classes, this is the views responsibility. And it looks like you are stuffing a message in the query string, but it probably should be in the TempData
Controller:
TempData["msg"] = "Please complete all the information";
return Redirect(#"~/Test/TestFirst");
View:
#if(TempData["msg"] != null)
{
<div class="myclass">#TempData["msg"]</div>
}
notice that TempData will survive a redirect.

Asp.Net MVC Return to page on error with fields populated

I am starting a new project in Asp.net MVC 2.
I have been mostly a webforms developer and have limited exposure to Asp.Net MVC and hence this is probably a noob question.
My situation is as follows:
I have a create page for saving some data to the DB.
The view for this page is not strongly bound / typed - so the way I am extracting the data from the view is by looking at the POST parameters.
Incase there is an error (data validation, etc), I need to send the user back to the previous page with everything filled in the way it was and displaying the message.
On webforms, this got handled automatically due to the view state - but how can I go about doing the same here?
A code example can be as follows:
View:
<% using (Html.BeginForm("Create", "Question", FormMethod.Post)) { %>
<div>
Title: <%: Html.TextBox("Title", "", new { #style="width:700px" })%>
</div>
<div>
Question: <%: Html.TextBox("Question", "", new { #style="width:700px" })%>
</div>
<input type="submit" value="Submit" />
<% } %>
Controller:
[HttpPost]
[ValidateInput(false)]
public ActionResult Create() {
Question q = new Question();
q.Title = Request.Form["Title"];
q.Text = Request.Form["Question"];
if(q.Save()) {
return RedirectToAction("Details", new { id = q.Id });
}
else {
// Need to send back to Create page with data filled in
// Help needed here
}
}
Thanks.
You could simply return the View in case of error. This will preserve the context.
[HttpPost]
[ValidateInput(false)]
public ActionResult Create(Question q) {
if(q.Save()) {
return RedirectToAction("Details", new { id = q.Id });
}
else {
// Need to send back to Create page with data filled in
// Help needed here
return View();
// If the view is located on some other controller you could
// specify its location:
// return View("~/Views/Question/Create.aspx");
}
}
Also I would recommend you to use strongly typed views along with the strongly typed helpers. Notice how I used a Question object directly as action parameter. This is equivalent to the code you have written in which you were manually extracting and building this object. The model binder does this job automatically for you.

Retrieving data from Html.DropDownList() in controller (ASP MVC) | string returned?

I have the following problem:
I have a form in site/banen (currently local running webserver) which is using a SQL database. The link is made using ADO.net and is instantiated in the controller in the following way:
DBModelEntities _entities;
_entities = new DBModelEntities(); // this part is in the constructor of the controller.
Next, I use this database to fill a Html.DropDownList() in my view. This is done in two steps. At the controller side we have in the constructor:
ViewData["EducationLevels"] = this.GetAllEducationLevels();
and a helper method:
public SelectList GetAllEducationLevels()
{
List<EducationLevels> lstEducationLevels = _entities.EducationLevels.ToList();
SelectList slist = new SelectList(lstEducationLevels, "ID", "Name");
return slist;
}
In the view I have the following:
<% using (Html.BeginForm()) {%>
<fieldset>
<legend>Fields</legend>
<!-- various textfields here -->
<p>
<label for="EducationLevels">EducationLevels:</label>
<!-- <%= Html.DropDownList("EducationLevels", ViewData["EducationLevels"] as SelectList)%> -->
<%= Html.DropDownList("EducationLevels", "..select option..")%>
</p>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
<% } %>
Now, the form is rendered correctly when I browse to the create page. I can select etc. But when selected I have to use that value to save in my new model to upload to the database. This is where it goes wrong. I have the following code to do this in my controller:
//
// POST: /Banen/Create
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(FormCollection form)
{
// set rest of information which has to be set automatically
var vacatureToAdd = new Vacatures();
//vacatureToAdd.EducationLevels = form["EducationLevels"];
// Deserialize (Include white list!)
TryUpdateModel(vacatureToAdd);
// Validate
if (String.IsNullOrEmpty(vacatureToAdd.Title))
ModelState.AddModelError("Title", "Title is required!");
if (String.IsNullOrEmpty(vacatureToAdd.Content))
ModelState.AddModelError("Content", "Content is required!");
// Update the variables not set in the form
vacatureToAdd.CreatedAt = DateTime.Now; // Just created.
vacatureToAdd.UpdatedAt = DateTime.Now; // Just created, so also modified now.
vacatureToAdd.ViewCount = 0; // We have just created it, so no views
vacatureToAdd.ID = GetGuid(); // Generate uniqueidentifier
try
{
// TODO: Add insert logic here
_entities.AddToVacatures(vacatureToAdd);
_entities.SaveChanges();
// Return to listing page if succesful
return RedirectToAction("Index");
}
catch (Exception e)
{
return View();
}
}
#endregion
It gives the error:
alt text http://www.bastijn.nl/zooi/error_dropdown.png
I have found various topics on this but all say you can retrieve by just using:
vacatureToAdd.EducationLevels = form["EducationLevels"];
Though this returns a string for me. Since I'm new to ASP.net I think I am forgetting to tell to select the object to return and not a string. Maybe this is the selectedValue in the part where I make my SelectList but I can't figure out how to set this correctly. Of course I can also be complete on a sidetrack.
Sidenote: currently I'm thinking about having a seperate model like here.
Any help is appreciated.
You can't return an object from usual <SELECT> tag wich is rendered by Html.DropDownList() method, but only string variable could be returned. In your case ID of EducationLevels object will be send to the server. You should define and use one more custom helper method to reconstruct this object by ID.

Resources