Mvc View rendering - c#

I'm trying to create contact us page where user fill's in the detail and submit and at the bottom display message which comes from server.
The way i have implemented is something like this.
[HttpGet]
public ActionResult ContactUs()
{
//Process the stuff
return View("~Views/Contact/Contact.cshtml", model)
}
now when page load it hits above method and display form with the layout including header and footer.
Once user submits form it hits below method
[HttpPost]
public ActionResult ContactUs(ContactUs form)
{
//Process the stuff
View.Message="Thank you for your enquiry."
return View("~Views/Contact/Contact.cshtml", model)
}
It returns to the same page but it doesnt render the body layout not even header or footer simply display outputs form.
Not sure what im doing wrong there, is there any better approach ?
Thanks

Based on the code above, I believe you're attempting something like:
public class UxController : Controller
{
public ActionResult WithResponse(ActionResult result, string message)
{
PageResponse(message);
return result;
}
protected void PageResponse(string message)
{
TempData["Ux_Response"] = message;
}
}
That would be your Controller, then the Controller for that specific page, it would look like:
public class HomeController : UxController
{
public ActionResult Index()
{
return View();
}
public ActionResult SubmitForm(string message)
{
return WithResponse(RedirectToAction("Index"), "Thank you for feedback.");
}
}
Then in your front-end code, you would do the following:
#if(TempData["Ux_Response"] != null)
{
<div>#TempData["Ux_Response"]</div>
}
<form action="/Home/SubmitForm" method="post">
<input type="text" name="message" />
<input type="submit" value="Submit" />
</form>
Obviously you could enhance this, with more versatility. However, you're relying on Post, which will cause a screen flicker. So the better route, may be to do Ajax, then return a JsonResult. Hopefully this helps you out.

It should work if you change your controller/view like this.
Controller;
public ActionResult Contact(ContactModel model)
{
ViewBag.Message = "Your contact page.";
return View(model);
}
public ActionResult SaveContact(ContactModel model)
{
//process values in your model and then rest model
ContactModel.Message = "Thank you for contacting us"; //show thank you message
return RedirectToAction("Contact",model);
}
View;
#model MvcApplication1.Models.ContactModel
#{
ViewBag.Title = "Contact";
}
#using (Html.BeginForm("SaveContact", "Home", Model, FormMethod.Post))
{
#Html.DisplayFor(m => m.Message);
<button type="submit">Submit</button>
}

I manged to solve this. the issue was the because i was using sitecore cms the form action wasnt processing it full work flow, after i removed the action, it defaults to action method which defined in cms and triggers the cms workflow.

Related

Having a problem redirecting a form post to another view

I have a basic MVC form that allows a user to submit a zip code and after clicking submit, the user should be redirected to a new view. My code seems to redirect to the next action successfully. However after the redirect, the controller returns back to the original action, so to the user, the page next changed at all.
Here's my View code:
#using (Html.BeginForm("PricingQuote", "Home", FormMethod.Post, new { #class = "rd-mailform text-center offset-top-30" }))
{
<div class="form-group">
<label class="form-label" for="contact-zip">Zip Code</label>
<input class="form-control" id="contact-zip" type="text" name="zip" data-constraints="##Required">
</div>
<button class="btn btn-primary offset-top-30" type="submit">GET STARTED</button>
}
Here's the PricingQuote action in my HomeController. This action redirects to the Pricing action in my Pricing controller:
[HttpPost]
public ActionResult PricingQuote(string zipCode)
{
return RedirectToAction("Pricing", "Pricing");
}
Here's my PricingController:
public class PricingController : Controller
{
// GET: Pricing
public ActionResult Pricing()
{
return View();
}
}
So, after clicking GET STARTED, it accesses my Home/PricingQuote action. This action then tries to redirect to the Pricing/Pricing action, which it does however, the code then seems to (incorrectly) return back to Home/PricingQuote and exits the action.
Any idea how I can redirect & display my Pricing view?
Thanks
Pass the controller in as the second parameter:
[HttpPost]
public ActionResult PricingQuote(string zipCode)
{
return RedirectToAction("Pricing", "PricingController");
}
Thanks for your responses. I was able to figure out my problem. The name of the action I was trying to redirect to ("Pricing") was the same name as my controller ("Pricing"). As a test, I renamed my action to "PricingA" & it worked, so apparently based on this, an action cannot be the same name as the controller when attempting a "RedirectToAction", which I was unaware of (at least that's my assumption based on the results I've found).
Unfortunately, I tried googling for some add'l evidence of this, to provide with this answer, but was unable to find any.
This works:
HomeController:
[HttpPost]
public ActionResult PricingQuote(string zipCode)
{
return RedirectToAction("PricingA", "Pricing");
}
Pricing Controller
[HttpGet]
public ActionResult PricingA()
{
return View();
}

Html.Actionlink shows my model data

I'm passing my model to actionlink using that
#Html.ActionLink("download", "action", "controller", Model, null)
But it generates html
<a href="/secure/action/controller?PrivateNo=3123123&LastName=lastname ..... >download</a>
So if user will change something it will affect to passed parameter and it will serious vulnerability. How can I avoid that?
as asked in comments i provide more details about controller.
public ActionResult List(MyModel model)
{
if (ModelState.IsValid)
{
bla bla bla
MyModel myModel = new MyModel()
{
PrivateNo = PrivateNumber,
FirstName = FirstName,
...
};
...
}
...
}
and in view I have
#Html.ActionLink("download", "GenerateDoc", "controller", Model, null)
and it goes to action which generates pdf
public ActionResult GenerateDoc(MyModel pdfModel)
{
string pdfData = FillTemplate(pdfModel);
byte[] source = Encoding.UTF8.GetBytes(pdfData);
byte[] resultDoc = Convert(source, "Template.xml");
return File(resultDoc, "application/pdf", Server.UrlEncode("test.pdf"));
}
Please achieve this by using form approach in your code Please refer below code:
On .cshtml/View page you have to put hidden fields (if you don't want to show these properties on page, it can also work for TextBoxes) for your Properties like below:
#using(Html.BeginForm("Index","Home",FormMethod.Post))
{
#Html.HiddenFor(x=>x.PrivateNo)
#Html.HiddenFor(x=>x.FirstName)
#Html.HiddenFor(x=>x.LastName)
<input type="submit" name="Submit" title="Submit" value="Submit" />
}
and on Controller you can get these values by following code:
[HttpPost]
public ActionResult Index(MyModel model)
{
return View();
}
after that you will get all the values on controller :
See below :
as you can see we have got the values from view to controller and no parameter is shown in URL.
Hope it helps you..:)
Thanks.
Happy coding :)

how to take input from TextBox and show in view in MVC

I want to show one TextBox. In that if give any input string and button clicked it should so like this
hai , what is ur name
[TextBox]
welcome,ur name is "xyz"
I am new in MVC. Please help me to do this.
View
#{
ViewBag.Title = "MyPage";
}
<h2>Mymethod</h2>
<h3>#ViewBag.Message</h3>
#Html.TextBox("Name")
<form method="post">
<input type="submit" value="Submit" name="btn" />
</form>
HomeController.cs
public ActionResult Mymethod()
{
ViewBag.Message = "Hello what is ur name ??? ";
return View();
}
There are many ways to do this to accomplish what you want. I will provide you with a simplistic approach, please modify and change it to fit in with your scenario.
I would normally recommend using a view model above any other way, for example using a single string value or using FormCollection or ViewBag. They can work but I prefer to use view models.
I answered a question on what view models are and what they are supposed to do, please read it:
What is ViewModel in MVC?
First you will create a view model that will handle your input data, like first name, last name, age, etc. You will then pass this view model through to the view. In your example I will only include name:
public class ViewModel
{
public string Name { get; set; }
}
In your Create action method you will instantiate this view model and pass it to the view. And when you click on the button to submit the form then the post action method will receive this view model as input parameter:
public ActionResult Create()
{
ViewModel model = new ViewModel();
return View(model);
}
[HttpPost]
public ActionResult Create(ViewModel model)
{
if (!ModelState.IsValid)
{
// If validation fails send the view model back to the view and fix any errors
return View(model);
}
// Do what you need to do here if there are no validation errors
// In your example we are posting back to the current view to
// display the welcome message
return View(model);
}
And then finally you view will look like this:
#model Project.Models.ViewModel
#using (Html.BeginForm())
{
#Html.TextBoxFor(m => m.Name)
<button type="submit">Submit</button>
if (!string.IsNullOrWhiteSpace(Model.Name))
{
<p>welcome, your name is #Model.Name</p>
}
}
Please spend some time reading through the many online tutorials on ASP.NET MVC.
Modify your current view to
#using(Html.BeginForm("ControllerName","Mymethod",FormMethod.Post))
{
<input type="submit" value="Submit" name="btn" />
}
Add another action method in your controller like this :
[HttpPost]
public ActionResult Mymethod(FormCollection form)
{
string Name = form["Name"];
Viewbag.Name = Name;
return View()
}
Then add view to this controller and write this into it.
Hi , Your Name is #Viewbag.Name
You should wrap your form in form tag. It is a form after all. So when you click submit, you are submitting the form.
<form method="post">
<h2>Mymethod</h2>
<h3>#ViewBag.Message</h3>
#Html.TextBox("Name")
#if (!String.IsNullOrEmpty(ViewBag.Name))
{
<h3>
welcome,ur name is #ViewBag.Name
</h3>
}
<input type="submit" value="Submit" name="btn" />
</form>
On the controller, you need to add HttpPost handler for your Mymethod action. This is where your web server is accepting the form you've submitted.
[HttpPost]
public ActionResult Mymethod(string name)
{
ViewBag.Message = "Hello what is ur name ???";
ViewBag.Name = name;
return View();
}

Execute code on Post request in ASP.NET MVC

I'm pretty new to ASP.NET MVC and was wondering how to do the following:
I have a list with some buttons like this:
#model List<SitefinityWebApp.Mvc.Models.ProfileModel>
#using (Html.BeginForm())
{
<ul>
#foreach (var item in Model)
{
<li>
<span>#item.EmailAddress</span>
<button id="submit">Generate code</button>
</li>
}
</ul>
}
So when a user clicks on the button, I need to execute some code on the server where I need the email address as a parameter.
I think I would need a POST for this, but I'm not sure how to set this up. In the end I want the same list to be rendered again.
I tried an ActionLink, but this is only for GET requests as I understood?
Any ideas on how to do this?
Thanks,
Daniel
You can define POST function in the Controller. Same name as the GET call.
Your Get Call should like somehing like this:
public ActionResult Index()
{
List<ProfileModel> list = new List<ProfileModel>();
list.add(listItem);
return View(list);
}
Then make the POST function:
[HttpPost]
public ActionResult Index(List<ProfileModel> postModel)
{
var emailAddress = postModel.EmailAddress
// do some stuff here
return RedirectToAction("Index");
}
You can call any POST function with the parameters in the Html.BeginForm:
#using (Html.BeginForm("MothodeName", "ControllerName", FormMethod.Post))
{
<!-- form here -->
}
It's not entirely clear what you want to do. Currently you are rendering multiple buttons in side a single form, but the form has no controls so nothing will post back (and since you have not specified the buttons type attribute, it may not trigger a submit anyway depending on the browser). One way to solve this is to have a form (specifying a route parameter) for each item that posts back the email address and then redirects back to the index page.
#foreach (var item in Model)
{
<span>#item.EmailAddress</span>
#using (Html.BeginForm("ProcessEmail", new { emailAddress = item.EmailAddress }))
{
<button type="submit">Generate code</button>
}
}
and the POST method would be
[HttpPost]
public ActionResult ProcessEmail(string emailAddress)
{
// do something with the email
return RedirectToAction("Index"); // redisplay the page
}
Alternatively you could use a hidden input instead of a route parameter
#foreach (var item in Model)
{
<span>#item.EmailAddress</span>
#using (Html.BeginForm("ProcessEmail"))
{
#Html.HiddenFor(m => item.EmailAddress , new { id = "" }) // remove the id attribute to prevent invalid html
<button type="submit">Generate code</button>
}
}
However, to get far better performance and avoid having to regenerate the view each time, you can use ajax to post the value
#foreach (var item in Model)
{
<span>#item.EmailAddress</span>
<button type="button" class="process-email" data-email="#item.EmailAddress">Generate code</button>
}
var url = '#Url.Action("ProcessEmail")';
$('.process-email').click(function() {
$.post(url, { emailAddress: $(this).data('email') }, function(response) {
if(response) {
// processing succeeded - display message?
} else {
// processing failed = display error?
}
})
})
and modify the method to
[HttpPost]
public JsonResult ProcessEmail(string emailAddress)
{
// do something with the email
return Json(true); // or return Json(null) if an error occured
}

Performing search in Asp.net MVC

I am new to Asp.net MVC and have no idea as to how can i perform the search. Here's my requirement, please tell me how will you handle this :-
I need to have textbox where user can enter a search query or string. The user then clicks on a button or presses enter to submit it. The string needs to matched with a table's property name.
NOTE:- Querying the data and fetching the result isn't the main point here. All I need to know is how will you take the user input and pass it to a controller action or whatever for further processing. Just tell me how will you read the user input and where will you send it to search.
Asp.Net MVC uses standard HTTP verbs. For the html part, it's a normal html form that points to an url. Server side, that url will be routed to a controller/action which will handle the input and do what is needed.
Let's have a sample. You want to make a search form. First of all, it's a best practice to have search forms use the HTTP GET method instead of POST, so the search results can be bookmarked, linked, indexed, etc. I won't be using Html.BeginForm helper method to make things more clear.
<form method="get" action="#Url.Action("MyAction", "MyController")">
<label for="search">Search</label>
<input type="text" name="search" id="search" />
<button type="submit">Perform search</button>
</form>
That's all the html you need. Now you'll have a controller called "MyController" and the method will be something like this:
[HttpGet]
public ActionResult MyAction(string search)
{
//do whatever you need with the parameter,
//like using it as parameter in Linq to Entities or Linq to Sql, etc.
//Suppose your search result will be put in variable "result".
ViewData.Model = result;
return View();
}
Now the view called "MyAction" will be rendered, and the Model of that view will be your "result". Then you'll display it as you wish.
As always in an ASP.NET MVC application you start by defining a view model which will express the structure and requirements of your view. So far you have talked about a form containing a search input:
public class SearchViewModel
{
[DisplayName("search query *")]
[Required]
public string Query { get; set; }
}
then you write a controller:
public class HomeController : Controller
{
public ActionResult Index()
{
return View(new SearchViewModel());
}
[HttpPost]
public ActionResult Index(SearchViewModel model)
{
if (!ModelState.IsValid)
{
// There was a validation error => redisplay the view so
// that the user can fix it
return View(model);
}
// At this stage we know that the model is valid. The model.Query
// property will contain whatever value the user entered in the input
// So here you could search your datastore and return the results
// You haven't explained under what form you need the results so
// depending on that you could add other property to the view model
// which will store those results and populate it here
return View(model);
}
}
and finally a view:
#model SearchViewModel
#using (Html.BeginForm())
{
#Html.LabelFor(x => x.Query)
#Html.EditorFor(x => x.Query)
#Html.ValidationMessageFor(x => x.Query)
<button type="submit">Search</button>
}
This is the best way to do it.
Create a ViewModel
public class SearchViewModel
{
public string Query { get; set; }
}
Create a Controller
public class SearchController : Controller
{
[HttpPost]
public ActionResult Search(SearchViewModel model)
{
// perform search based on model.Query
// return a View with your Data.
}
}
Create the View
// in your view
#using (Html.BeginForm("Search", "SearchController"))
{
#Html.TextBox("Query")
<input type="submit" value="search" />
}
hope this helps

Categories