Contact us form action not found - asp.net-mvc

Not sure why this isn't working, but I suspect it's something to do with routing... (Using MVC5)
When clicking on the submit button I get the following message:
The resource cannot be found.
Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /contact
Using a model as follows:
public class EmailMessageModel
{
/// <summary>Gets or sets from name.</summary>
/// <value>From name.</value>
[Required, Display(Name = "Name")]
public string FromName { get; set; }
}
The view is then as follows:
#model EmailMessageModel
#using (Html.BeginForm("index", "contact", FormMethod.Post, new { enctype = "multipart/form-data", #class = "contact-form" }))
{
#Html.AntiForgeryToken()
#Html.LabelFor(m => m.FromName, new { #class = "control-label" })
#Html.TextBoxFor(m => m.FromName, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.FromName)
<input type="submit" value="Send Message" id="btnSubmitQuery" />
}
Controller is as follows:
(the breakpoint on the HttpPost Index action is never hit, any ideas why?)
namespace ExternalSite.Controllers
{
using ExternalSite.Models;
using System.Net.Mail;
using System.Web.Mvc;
[RoutePrefix("contact")]
public class ContactController : Controller
{
[HttpGet]
[Route]
public ActionResult Index()
{
return View();
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Index(EmailMessageModel model)
{
// !!!!!!!!!!BREAKPOINT HERE IS NEVER BEING HIT!!!!!!!!!!!
if (ModelState.IsValid)
{
}
return View(model);
}
}

The solution was to add the blank route attribute [Route] to the HttpPost Index method, i.e.
[HttpPost]
[Route]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Index(EmailMessageModel model)
{
// !!!!!!!!!!BREAKPOINT HERE IS NEVER BEING HIT!!!!!!!!!!!
if (ModelState.IsValid)
{
}
return View(model);
}

Related

submit button doesn't pass input from textbox

Basically i have an input box in which an user can type in his email, and a button that submits the email. I can press the button, and it redirects to my "details" page. However, the input from the texbox is not passed to my controller.
View:
#using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
<div class="form-group form-inline">
<label class="margin20">Sign up for newsletter</label>
#Html.TextBoxFor(Model => Model.Email, new { name= "mail", Class = "form-control", Style = "display:inline-block; max-width:200px", Placeholder="Example#Example.com" })
<input type="submit" class="btn btn-default" style="display:inline-block" id="emailSignup"/>
</div>
}
Controllers
public class HomeController : Controller
{
// GET: Home
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(string mail)
{
return RedirectToAction("details", new {address = mail });
}
public ActionResult details(string address)
{
EmailSignup person = new EmailSignup { Email = address};
return View(person);
}
}
i left the model out, because it basically is 1 property.
Your
#Html.TextBoxFor(Model => Model.Email, ...)
is generating an input with name="Email".
Note that new { name = "mail" } does absolutely nothing fortunately (look at the html your generating) because if it did, it would screw up the model binding process - the whole purpose of using the HtmlHelper methods is to bind to your model.
You could change the method to
[HttpPost]
public ActionResult Index(string email)
and the parameter will be correctly bound, however your method should be
[HttpPost]
public ActionResult Index(XXX model)
{
if (!ModelState.IsValid)
{
return View(model);
}
return RedirectToAction("details", new { address = model.Email });
}
where XXX is the model that you declared in the view (i.e. with #model XXX), so that you get correct model binding and can take into account validation.
Note also that you property should be
[Display(Name = "Sign up for newsletter")]
[Required("Please ...")] // assuming you want to ensure a value is submitted
[EmailAddress] // assuming you want a valid email
public string Email { get; set; }
and then the view will be
#Html.LabelFor(m => m.Email) / correctly generates a label associated with the input
#Html.TextBoxFor(m => m.Email, new { #class = "form-control", placeholder="Example#Example.com" })
#Html.ValidationMessageFOr(m => m.Email)
and I recommend adding another class name and using css rather than you inline style = ".." element

Inserting a User through ActionController using Entity Framework

I am trying to add a new User in my database, but every time I press submit i get this error
HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly. "
This is my controller:
public class CreateController : Controller
{
// GET: Create
public ActionResult Index()
{
return View();
}
public ActionResult Create()
{
return View();
}
[HttpPost]
public ActionResult Create(User user)
{
using (var db = new UserEntities())
{
User newUser = new User();
newUser.Name = user.Name;
db.Users.Add(newUser);
db.SaveChanges();
return View();
}
}
}
This is my view:
#model FormulörModul.Models.User
<title>Create</title>
#using (Html.BeginForm("Create", "CreateController", FormMethod.Post))
{
<label>Namn</label>
#Html.TextBoxFor(m=>m.Name)
#Html.ValidationMessageFor(m => m.Name)
<input id="Submit1" type="submit" value="submit" />
}
I think the error is in the call to Html.BeginForm. By convention in MVC, when you name a controller you just name the string before "Controller". I.e. replace this
#using (Html.BeginForm("Create", "CreateController", FormMethod.Post))
with this
#using (Html.BeginForm("Create", "Create", FormMethod.Post))
BTW, "Create" is a really bad name for a controller. I would name it "User".

Hijacked Umbraco HttpPost action not firing

I've hijacked the route in Umbraco 7.1 and for some reason my HttpPost is not firing when the submit button is pressed. Any input as to why this is? There is a postback taking place when send is pressed but the when putting a break point in the HttpPost it's never fired.
Here's a snippet of my code, the markup followed by the controller.
#inherits UmbracoViewPage
#{
Layout = "Layout.cshtml";
}
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.TextAreaFor(m => m.Message)
< i n p u t type="submit" value="Send" />
#Html.ValidationMessageFor(m => m.Message)
</div>
}
public ActionResult Index(ManageMessageId? smess)
{
var errorModel = new ErrorModel();
...
return CurrentTemplate(errorModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(ErrorModel model)
{
if (ModelState.IsValid)
{
...
}
return View();
}
Assuming you are using SurfaceControllers, you would want to create your form as follows. Note the change in how you create the form and how the generic and parameter match that of the surface controller:
#using (Html.BeginUmbracoForm<MyController>("Index"))
{
}
Your controller should look something like:
public class MyController : SurfaceController
{
public ActionResult Index(ManageMessageId? smess)
{
var errorModel = new ErrorModel();
...
return CurrentTemplate(errorModel);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(ErrorModel model)
{
if (ModelState.IsValid)
{
...
}
return View();
}
}

How do I get a strongly typed DropDownList to bind to a control Action

I've just started a new MVC project and I'm having trouble getting the post result from a form.
This is my Model Class :
public class User
{
public int id { get; set; }
public string name { get; set; }
}
public class TestModel
{
public List<User> users { get; set; }
public User user { get; set; }
public SelectList listSelection { get; set; }
public TestModel()
{
users = new List<User>()
{
new User() {id = 0, name = "Steven"},
new User() {id = 1, name = "Ian"},
new User() {id = 2, name = "Rich"}
};
listSelection = new SelectList(users, "name", "name");
}
}
This is my view class
#model MvcTestApplicaiton.Models.TestModel
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
#using (Html.BeginForm())
{
#Html.DropDownListFor(x => x.user, #Model.listSelection)
<p>
<input type="submit" value="Submit" />
</p>
}
#if (#Model.user != null)
{
<p>#Model.user.name</p>
}
And this is my controller :
public class TestModelController : Controller
{
public TestModel model;
//
// GET: /TestModel/
public ActionResult Index()
{
if(model ==null)
model = new TestModel();
return View(model);
}
[HttpPost]
public ActionResult Test(TestModel test)
{
model.user = test.user;
return RedirectToAction("index", "TestModel");
}
}
The drop down list appears just fine but I can't see to get the ActionResult Test function to run. I thought it would just bind itself with reflection but whatever is wrong, I can't see it.
You have two main errors in your code.
As Brett said you're posting to the Index method, but you don't have Index method that supports POST verb. The easiest way to fix is to change Html.BeginForm() with Html.BeginForm("Test", "TestModel")
You're using Html.DropDownListFor in a wrong way. You could pass only a value types there, because don't forget that the View will generate an HTML page. So instead of User in your Model you should have an UserID and in your View you should have #Html.DropDownListFor(x => x.UserID, #Model.listSelection). And finally in your Action you should query your data source to get the details for the user with this ID.
Hope this helps.
Looks like you're posting back to index. Either use a GET Test() action method, or specify the ACTION parameter in BeginForm().
For example,
#using (Html.BeginForm("Test", "TestModel"))
{
#Html.DropDownListFor(x => x.user, #Model.listSelection)
<p>
<input type="submit" value="Submit" />
</p>
}
Or use a view named Test (rename index.cshtml to test.cshtml):
public ActionResult Test()
{
if(model ==null)
model = new TestModel();
return View(model);
}

Inconvenient to upload files to the server and use TempData

I'm trying to make a file upload to the server using Uploadify, but not working the TempData to pass variables between controllers and I have not found an error.
I'm trying passing the variables fileName and file with TempData of the controller "GetFile" to the controller "ModelCreate".
The controller "GetFile" works well, but when I check the value of "date1" and "date2" in the controller "ModelCreate" is null
I just want to make the file saved in the controller "ModelCreate"
public string GetFile(HttpPostedFileBase file)
{
var fileName = this.Server.MapPath("~/Informs/" + System.IO.Path.GetFileName(file.FileName));
if (System.IO.File.Exists(fileName))
return "has been uploaded successfully";
file.SaveAs(fileName);
TempData["NameFile"] = fileName;
TempData["File"] = file;
return "1";
}
[HttpPost]
public ActionResult ModelCreate(INFORME inform)
{
var date1 = TempData["NameFile"] as string;
var date2 = TempData["File"] as HttpPostedFileBase;
date2.SaveAs(date1);
.
.
.
.
}
why "date1" and "date2" are null?
Blessings
There's not enough information to provide an answer to this question. As requested in the comments section I will provide a full example illustrating a form allowing the user to fill a couple of input fields and upload a file.
As always we start by defining the view model which will reflect the information that we want to display on the view:
public class MyViewModel
{
[Required]
public string TextField { get; set; }
[DataType(DataType.MultilineText)]
public string TextAreaField { get; set; }
public bool CheckBoxField { get; set; }
[Required]
public HttpPostedFileBase FileField { get; set; }
}
Then we could have a controller with 2 actions: a GET action that simply displays the form and a POST action that processes the form information when submitted:
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel();
return View(model);
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
if (!ModelState.IsValid)
{
// there were validation errors => redisplay the view
return View(model);
}
// at this stage the model is valid => we could do some processing
// first let's save the file
var appData = Server.MapPath("~/app_data");
var file = Path.Combine(appData, Path.GetFileName(model.FileField.FileName));
model.FileField.SaveAs(file);
// then we could process the other properties
// ...
return Content("Thanks for submitting the data");
}
}
and finally a strongly typed view top the view model:
#model MyViewModel
#Html.ValidationSummary(false)
#using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div>
#Html.EditorFor(x => x.TextField)
#Html.ValidationMessageFor(x => x.TextField)
</div>
<div>
#Html.EditorFor(x => x.TextAreaField)
#Html.ValidationMessageFor(x => x.TextAreaField)
</div>
<div>
#Html.CheckBoxFor(x => x.CheckBoxField)
#Html.ValidationMessageFor(x => x.CheckBoxField)
</div>
<div>
#Html.LabelFor(x => x.FileField)
#Html.TextBoxFor(x => x.FileField, new { type = "file" })
</div>
<button type="submit">OK</button>
}

Resources