net I am trying to take a value from a previous form typically in php it would be written like this
$name= $_POST ["Username"];
$pass= $_POST ["Password"];
how can I write this in asp.net
if you use GET
string usrnm = Request.QueryString["username"];
string pass = Request.QueryString["password"];
if you use POST
string usrnm = Request.Form["username"];
string pass = Request.Form["password"];
in web forms
if (Page.IsPostBack)
{
//access posted input as
Request.Form["input1"]
Request.Form["input2"]
Request.Form["input3"]
}
in mvc
[HttpPost]
public ActionResult myaction(strig input1,strig input1,strig input1)
{
//you can access your input here
return View();
}
or if you have view model for it, which is capable to take 3 inputs as
public class myViewmodleclass()
{
public string input1{get;set;}
public string input2{get;set;}
public string input3{get;set;}
}
controller action
[HttpPost]
public ActionResult myaction(myViewmodleclass mymodelobject)
{
//you can access your input here
return View();
}
so you using mvc, which has a nice model binding.
So you are using mvc which has nice model binding. You can simply have a proper model object. For your example
public class LoginInfo()
{
public string UserName{get;set;}
public string Password {get;set;}
}
in your controller
[HttpPost]
public ActionResult Logon(LoginInfo loginInfo )
{
// Do stuff with loginInfo
}
Related
How can I pass query string values to a view model parameter that has default values in ASP.net MVC app?
I tried so but didn't succeed;
public ActionResult Index(MyAnotherVM filter){
// filter.p doesn't set passed value and it equals to 1
}
public class MyAnotherVM {
public int p { get { return 1; } set { } }
// or
public int p=1;
}
You can make use of TempData
[HttpPost]
public ActionResult FillStudent(Student student1)
{
TempData["student"]= new Student();
return RedirectToAction("GetStudent","Student");
}
[HttpGet]
public ActionResult GetStudent(Student passedStd)
{
Student std=(Student)TempData["student"];
return View();
}
Approach 2:
using Query string data passed
Or you can frame it with the help of query strings like
return RedirectToAction("GetStudent","Student", new {Name="John", Class="clsz"});
This will generate a GET Request like
Student/GetStudent?Name=John & Class=clsz
But make sure you have [HttpGet] since RedirectToAction will issue GET Request(302)
This will be quite simple but
What is the best way of using classical webforms "response.write" in asp net MVC. Especially mvc5.
Let's say: I just would like to write a simple string to screen from controller.
Does response.write exist in mvc?
Thanks.
If the return type of your method is an ActionResult, You can use the Content method to return any type of content.
public ActionResult MyCustomString()
{
return Content("YourStringHere");
}
or simply
public String MyCustomString()
{
return "YourStringHere";
}
Content method allows you return other content type as well, Just pass the content type as second param.
return Content("<root>Item</root>","application/xml");
As #Shyju said you should use Content method, But there's another way by creating a custom action result, Your custom action-result could look like this::
public class MyActionResult : ActionResult
{
private readonly string _content;
public MyActionResult(string content)
{
_content = content;
}
public override void ExecuteResult(ControllerContext context)
{
context.HttpContext.Response.Write(_content);
}
}
Then you can use it, this way:
public ActionResult About()
{
ViewBag.Message = "Your application description page.";
return new MyActionResult("content");
}
I want to prevent posting sensitive data via url query string to a MVC 5 application.
In MVC there is a DefaultModelBinder. The DefaultModelBinder looks for the ActionMethod parameters in the url query string, the body and the route. But my target is to bind the parameters exclusively from the body and not from route or query string.
In Asp.Net WebApi there is such a concept. The Attribute [FromBody] will do the job: http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api
Is there something suitable for MVC?
I´ve found the System.Web.ModelBinding.FormAttribute (https://msdn.microsoft.com/en-us/library/system.web.modelbinding.formattribute(v=vs.110).aspx). However, if I decorate the parameter, it has no effect to the model binding.
By default, the binder looks for data in four places: form data, route data, the query string, and any uploaded files.
It is possible to restrict the binding to a single source of data. To do so you should call the UpdateModel method passing, as the second parameter, a FormValueProvider object( an implementation of IValueProvider).
public ActionResult Products()
{
IList<Products> products = new List<Products>();
UpdateModel(products, new FormValueProvider(ControllerContext));
return View(products);
}
The complete list of objects is (they all receive the ControllerContext as the contructor parameter):
FormValueProvider: search for data in the body (Request.Form)
RouteDataValueProvider: search for data in the route (RouteData.Value)
QueryStringValueProvider: search for data in the query string (Request.QueryString)
HttpFileCollectionValueProvider: search for uploaded files (Request.Files)
Another way: create a custom model binder that uses FormValueProvider. The advantage of this is that you don't have to modify the action method.
Example:
[ModelBinder(typeof(PersonBinder))]
public class Person
{
[DisplayName("Social Security Number")]
public int SSN { get; set; }
[HiddenInput(DisplayValue = false)]
public string ShouldNotBind { get; set; }
}
public class PersonBinder : IModelBinder
{
public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
bindingContext.ValueProvider = new FormValueProvider(controllerContext);
Person model = (Person)bindingContext.Model ?? new Person();
model.SSN = Convert.ToInt16(GetValue(bindingContext, "SSN"));
return model;
}
private string GetValue(ModelBindingContext context, string name)
{
ValueProviderResult result = context.ValueProvider.GetValue(name);
if (result == null || result.AttemptedValue == "")
{
return "<Not Specified>";
}
return result.AttemptedValue;
}
}
And your action method:
[HttpPost]
public ActionResult Person(Person person)
{
return View(person);
}
Even if you post with a querystring, the ShouldNotBind property will show as "null".
Why not use form's then?
On submit you post form data
For example:
class MyContoller
{
[MyCustomAttribute]
public ActionResult MyAction(ModelX fromRequest, ModelY fromSession, ModelZ fromCookie)
{
string productId = fromRequest.ProductId;
string userId = fromSession.UserId;
string cultureName = fromCookie.CultureName;
}
}
Reason:
I don't want to visit Request, Session and HttpContext in the controllers, and the default idea of MVC3 which passing models to actions is very great.
I want the number of parameters of MyAction is easy to change. For example, if I add a new parameter, the system will try to look for values in Request, Session or Cookies by the name or type of the parameter (I think custom ModelBinders may be required for cookie values) and pass the filled model to my action. I don't have to write extra code.
Can the custom attribute (MyCustomAttribute in the example) accomplish this idea?
I am not sure I follow you about the custom attribute. What are you expecting the custom attribute to do?
Yes, an action method can take as many model parameters as you want. Obviously, only one can be bound in any given request (because a view can only have one model). Whichever one is found first will be bound, and the others will be null.
So let's say you have the following:
public class ModelX {
public string X {get;set;}
}
public class ModelY {
public string Y {get;set;}
}
public class ModelZ {
public string Z {get;set;}
}
And you have an action method like this:
public ActionResult DoIt(ModelX x, ModelY y, ModelZ z)
{
return View();
}
And in your DoIt.cshtml you have the following:
#model ModelZ
#using(Html.BeginForm()) {
#Html.TextBoxFor(x => x.Z)
<input type="submit"/>
}
If you type something into the textbox and submit, then the model binder will bind a ModelZ with the value you entered and ModelX and ModelY will be null.
If you mean can an action method bind multiple models simultaneously, then I would have to ask you.. How exactly do you plan to have a view have more than one model? You can certainly create a wrapper model to contain the multiple models, but a view can only have one.
Create a composite ViewModel class that incorporates ModelX, ModelY and ModelZ. You can then populate an instance of your new ViewModel class, and pass that to your controller method.
public class XYZViewModel
{
public ModelX fromRequest { get; set; }
public ModelY fromSession { get; set; }
public ModelZ fromCookie { get; set; }
}
public class MyController
{
[MyCustomAttribute]
public ActionResult MyAction(XYZViewModel myModel)
{
string productId = myModel.fromRequest.ProductId;
string userId = myModel.fromSession.UserId;
string cultureName = myModel.fromCookie.CultureName;
}
}
You can always pass multiple parameters to your controller action, yes. The key is to make sure they are properly serialized in the request. If you're using a form, that means using the Html helper methods.
For example, let's say you want an action like this:
public ActionResult Multiple(ModelA a, ModelB b)
{
// ...
}
You could create simple partial view for each model:
#model MyProject.Models.ModelA
#Html.EditorForModel()
Then in your Multiple view, render the partial views like so:
#{ using (Html.BeginForm("Multiple", "MyController", FormMethod.Get))
{
#Html.Partial("A", new MyProject.Models.ModelA())
#Html.Partial("B", new MyProject.Models.ModelB())
<input type='submit' value='submit' />
}
I set the method to GET here so that you can easily see how MVC passes the parameters. If you submit the form, you'll see that MVC successfully deserializes each object.
There are a lot of articles devoted to working with data in MVC, and nothing about MVC 2.
So my question is: what is the proper way to handle POST-query and validate it.
Assume we have 2 actions. Both of them operates over the same entity, but each action has its own separated set of object properties that should be bound in automatic manner. For example:
Action "A" should bind only "Name" property of object, taken from POST-request
Action "B" should bind only "Date" property of object, taken from POST-request
As far as I understand - we cannot use Bind attribute in this case.
So - what are the best practices in MVC2 to handle POST-data and probably validate it?
UPD:
After Actions performed - additional logic will be applied to the objects so they become valid and ready to store in persistent layer. For action "A" - it will be setting up Date to current date.
I personally don't like using domain model classes as my view model. I find it causes problems with validation, formatting, and generally feels wrong. In fact, I'd not actually use a DateTime property on my view model at all (I'd format it as a string in my controller).
I would use two seperate view models, each with validation attributes, exposed as properties of your primary view model:
NOTE: I've left how to combining posted view-models with the main view model as an exercise for you, since there's several ways of approaching it
public class ActionAViewModel
{
[Required(ErrorMessage="Please enter your name")]
public string Name { get; set; }
}
public class ActionBViewModel
{
[Required(ErrorMessage="Please enter your date")]
// You could use a regex or custom attribute to do date validation,
// allowing you to have a custom error message for badly formatted
// dates
public string Date { get; set; }
}
public class PageViewModel
{
public ActionAViewModel ActionA { get; set; }
public ActionBViewModel ActionB { get; set; }
}
public class PageController
{
public ActionResult Index()
{
var viewModel = new PageViewModel
{
ActionA = new ActionAViewModel { Name = "Test" }
ActionB = new ActionBViewModel { Date = DateTime.Today.ToString(); }
};
return View(viewModel);
}
// The [Bind] prefix is there for when you use
// <%= Html.TextBoxFor(x => x.ActionA.Name) %>
public ActionResult ActionA(
[Bind(Prefix="ActionA")] ActionAViewModel viewModel)
{
if (ModelState.IsValid)
{
// Load model, update the Name, and commit the change
}
else
{
// Display Index with viewModel
// and default ActionBViewModel
}
}
public ActionResult ActionB(
[Bind(Prefix="ActionB")] ActionBViewModel viewModel)
{
if (ModelState.IsValid)
{
// Load model, update the Date, and commit the change
}
else
{
// Display Index with viewModel
// and default ActionAViewModel
}
}
}
One possible way to handle POST data and add validation, is with a custom model binder.
Here is a small sample of what i used recently to add custom validation to POST-form data :
public class Customer
{
public string Name { get; set; }
public DateTime Date { get; set; }
}
public class PageController : Controller
{
[HttpPost]
public ActionResult ActionA(Customer customer)
{
if(ModelState.IsValid) {
//do something with the customer
}
}
[HttpPost]
public ActionResult ActionB(Customer customer)
{
if(ModelState.IsValid) {
//do something with the customer
}
}
}
A CustomerModelBinder will be something like that:
public class CustomerModelBinder : DefaultModelBinder
{
protected override void BindProperty(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor)
{
if (propertyDescriptor.Name == "Name") //or date or whatever else you want
{
//Access your Name property with valueprovider and do some magic before you bind it to the model.
//To add validation errors do (simple stuff)
if(string.IsNullOrEmpty(bindingContext.ValueProvider.GetValue("Name").AttemptedValue))
bindingContext.ModelState.AddModelError("Name", "Please enter a valid name");
//Any complex validation
}
else
{
//call the usual binder otherwise. I noticed that in this way you can use DataAnnotations as well.
base.BindProperty(controllerContext, bindingContext, propertyDescriptor);
}
}
and in the global.asax put
ModelBinders.Binders.Add(typeof(Customer), new CustomerModelBinder());
If you want not to bind Name property (just Date) when you call ActionB, then just make one more custom Model Binder and in the "if" statement, put to return the null, or the already existing value, or whatever you want. Then in the controller put:
[HttpPost]
public ActionResult([ModelBinder(typeof(CustomerAModelBinder))] Customer customer)
[HttpPost]
public ActionResult([ModelBinder(typeof(CustomerBModelBinder))] Customer customer)
Where customerAmodelbinder will bind only name and customerBmodelbinder will bind only date.
This is the easiest way i have found, to validate model binding, and i have achieved some very cool results with complex view models. I bet there is something out there that i have missed, and maybe a more expert can answer.
Hope i got your question right...:)