Hijacked Umbraco HttpPost action not firing - asp.net-mvc

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();
}
}

Related

Contact us form action not found

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);
}

getting values View data in controller

i did this all but now how to get values being typed in Textbox, password box etc in CONTROLLER. I defined all necessary methods, boxes and buttons etc. So the only problem is to get values in controller and then to send them to model for accessing db data
.csHtml
#using (Html.BeginForm("register","Home", FormMethod.Post, new {id="submitForm"}))
{
<div>
<i>#Html.Label("Name:")</i>
#Html.TextBox("txtboxName")
</div>
<div>
<i>#Html.Label("Email:")</i>
#Html.TextBox("txtboxEmail")
</div>
<div>
<i>#Html.Label("Password:")</i>
#Html.Password("txtboxPassword")
</div>
<div>
<button type="submit" id="btnSubmit" name="Command" value="Submit">Submit</button>
</div>
}
Controller code:
namespace LoginSys.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Registration";
return View();
}
[HttpPost]
public ActionResult register(string command, FormCollection formData )
{
if (command == "submit")
{
var name = formData["txtboxName"];
var email = formData["txtboxEmail"];
}
return View();
}
}
}
i'm intentionally using this way of coding it instead of complex and advance one. Just help me to get values in controller
[HttpPost]
public ActionResult register(YOURMODEL model)
{
//db operation
return View();
}
NOTE: make sure your textbox name should be same as your model name
You should use viewmodels. create a model for the view that can be posted to the action. However, if you wish to continue your current approach you need to change the controller action to something like this:
[HttpPost]
public ActionResult register(string btnSubmit, string txtboxName, string txtboxEmail, string txtboxPassword)
{
if (command == "submit")
{
}
return View();
}
if this doesn't work, you can test it by using this:
[HttpPost]
public ActionResult register(FormCollection form)
{
if (command == "submit")
{
}
return View();
}
When you debug you can check the 'form' parameter and see that your fields exists in the form, and get the proper names for the parameters you need.

How can i do search inside same page in MVC Razor

How can i do search inside same page in MVC Razor? For example; my page do not any result when open if i search return.i must use IEnumerable<model> for getting result but if i use IEnumerable<model> for empty page, i am getting error.
Search page
#model IEnumerable<SearchResult>
<span>Search results:</span>
<p>
#foreach(var item in Model)
{
#item.Title<br/>
}
</p>
You need to return empty model for such case. for example in controller code:
public ActionResult Test()
{
// some actions
return View(new List<SearchResult>());
}
in that case it will send empty model, and won't fail.
You can create a model that contain the search properties and the result list.
Model
Public class MySearchModel{
public string searchInput { get; set; }
public List<mySearchResultModel> resultList { get; set; }}
Controller
public ActionResult Index()
{
var model = new MySearchModel();
return View(model);
}
[HttpPost]
public ActionResult Index(MySearchModel model)
{
model.searchInput //filter
model.mySearchResultModel = //query where filter
return View(model);
}
View
#model MySearchModel
<div>
#Html.LabelFor(x => x.searchInput)
#Html.TextBoxFor(x => x.searchInput)
</div>
<span>Search results:</span>
#foreach (var item in Model.mySearchResultModel){
#item.Title<br />
}
Another way to accomplish the same is to add your search inputs and map them to the controller action that you are posting using the input name:
Controller
public ActionResult Index()
{
var model = new mySearchResultModel();
return View(model);
}
[HttpPost]
public ActionResult Index(mySearchResultModel model, string searchInput)
{
model.mySearchResultModel = //query where filter (searchInput)
return View(model);
}
View
#model IEnumerable<mySearchResultModel>
<input type="text" name="searchInput"/>
Search results:
#foreach(var item in Model) { #item.Title<br/> }

How do I populate HTML content with new values once data has been changed on postback?

I have MVC3 razor application. Once I'm submitting a form and in Action i'm changing ViewModel content, i can't see new values populated.
There was a topic about that in MVC2 where guys told that it may be fixed in MVC3
http://aspnet.codeplex.com/workitem/5089?ProjectName=aspnet
Can you tell if there is an option to do that or what is the better way(workaround) to update UI without JavaScript using postbacks?
Action:
[HttpPost]
public ActionResult Index(MyViewModel model)
{
model.Value = "new value"
return View("Index", model);
}
UI:
#Html.HiddenFor(x => x.Value)
ViewModel:
public class MyViewModel
{
public string Value { get;set; }
}
Looks like it's using the ModelState values that were posted.
If you clear the ModelState using ModelState.Clear() the new value you set should be in the hidden field.
You should use form and to post it to action.
#model MyViewModel
#using (Html.BeginForm("Index", "Home", FormMethod.Post))
{
#Html.HiddenFor(x=>x.Value)
<input type="submit" value="Submit" />
}
Controller
//
public ActionResult Index()
{
MyViewModel model = new MyViewModel();
model.Value = "old value";
return View("Index", model);
}
[HttpPost]
public ActionResult Index(MyViewModel model)
{
//get posted model values (changed value by view "new value")
string changed_value = model.Value;
// you can return model again if your model.State is false or after update
return View("Index", model);
}

Model change in post action not visible in Html.TextBoxFor?

This must be something very obvious but for me it looks very strange. I have simple controller, model with one property, and view which displays value of property and renders editor for that property. When I click the button, form is posted and exclamation mark is appened to property. This exclamation mark is visible in my view but only in p tag, not in input tag rendered by Html.TextBoxFor().
Why Html.TextBoxFor() ignores that I updated my model in post action?
Is there any way to change this behavior of Html.TextBoxFor()?
View
#model ModelChangeInPostActionNotVisible.Models.IndexModel
#using (Html.BeginForm())
{
<p>#Model.MyProperty</p>
#Html.TextBoxFor(m => m.MyProperty)
<input type="submit" />
}
Model
namespace ModelChangeInPostActionNotVisible.Models
{
public class IndexModel
{
public string MyProperty { get; set; }
}
}
Controller
namespace ModelChangeInPostActionNotVisible.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new IndexModel { MyProperty = "hi" });
}
[HttpPost]
public ActionResult Index(IndexModel model)
{
model.MyProperty += "!";
return View(model);
}
}
}
HTML after clicking on submit button
<form action="/" method="post"> <p>hi!</p>
<input id="MyProperty" name="MyProperty" type="text" value="hi" /> <input type="submit" />
</form>
This is by design.
The helper methods are using the ModelState, thus if the response of your request is using the same Model, it will display the value that was posted.
This is to allow you to render the same view in the situation where the validation would have failed.
To make sure you display the new information add : ModelState.Clear(); before you return.
Read more here : http://blogs.msdn.com/b/simonince/archive/2010/05/05/asp-net-mvc-s-html-helpers-render-the-wrong-value.aspx
namespace ModelChangeInPostActionNotVisible.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new IndexModel { MyProperty = "hi" });
}
[HttpPost]
public ActionResult Index(IndexModel model)
{
model.MyProperty += "!";
ModelState.Clear();
return View(model);
}
}
}
Yan Brunet is absolutely correct that the variable needs to be removed from the ModelState in order to be modified in the controller. You don't have to clear the entire ModelState, though. You could do the following to remove just the variable to want to modify:
ModelState.Remove("MyProperty");
This would be useful in case you wanted to retain other values which the user had entered.

Resources