How to bind form to Nancy - c#

I’ve written a code snippet creates HTML form via C#. But I want the form’s fields to be bound class’s field after the form is submitted. How can I do that and check the result(if the class’s fields are filled)? Moreover, I don’t know how to test the code via Postman or Fiddle. Could you exemplify? For example, when the form is filled via a browser, I don’t know how to see the result forwarded to sent.
HTML form,
<form action="sent” method="POST"<br>
<label for="firstName">First Name Label:</label>
<input type="text" title="testTitle" name="firstName" placeholder="First Name" ><br>
<label for="lastName">Last Name Label:</label>
<input type="text" name="lastName" placeholder="Last Name" ><br>
<input type="submit" name = "noname">
</form>
Nancy,
Get("/form", parameters =>
{
// codes to construct the above HTML code
return Response.AsText(form.ToString(), "text/html");
}
// Received form information (fields)
Post("/sent”, _ =>
{
testClass receivedData = this.Bind<testClass>();
return new
{
success = true,
message = $"Record recieved First Name = {receivedData.Name}",
message2 = $"Record recieved Last Name = {receivedData.SurName}"
};
});
testClass,
public class testClass
{
public string Name { get; set; }
public string SurName { get; set; }
}

Serving your form should be easy with this working example.
Get("/api/base", _ =>
{
return Response.AsFile("content/Base.html", "text/html");
});
Make sure to add content folder and make files inside copy to output directory when newer.
make sure you close tags properly.
Also your form could just call a mapped api on submit like this
<form action="/api/submit" method="POST">
<br>
<label for="firstName">First Name Label:</label>
<input type="text" title="testTitle" id="firstName" placeholder="First Name"><br>
<label for="lastName">Last Name Label:</label>
<input type="text" id="lastName" placeholder="Last Name" ><br>
<input type="submit" id = "noname">
</form>
https://stackoverflow.com/a/53192255
Post("/api/submit”, args =>
{
//this.Request.Body;
var r = (Response)"";
testClass receivedData = this.Bind<testClass>();
r = (Response)$"Record recieved First Name = {receivedData.Name}"
+ Environment.NewLine +
$"Record recieved Last Name = {receivedData.SurName}";
r.StatusCode = HttpStatusCode.OK;
return r;
});
I Could be wrong, but I think it is because you are using a discard for the input.

Related

Addition and Removal of parts of a Dynamic Form Array

I am currently playing around an idea of making views as much typed as possible. What I want to do is make a Partial View that will be capable of adding a new items into the array/list (and ofc the removal as well). I have noticed that I am basically unable to avoid JavaScript, however I wish not to hardcore anything other than URLs. Is it possible to achive this without making basically unreadable reflection for someone that gets the code in their hands after me ?
For a bit more clarification, lets assume a simple Pizza shop with the following models:
PizzaViewModel:
public class PizzaViewModel
{
[Required]
public string Name { get; set; } = "";
[Required]
public string Description { get; set; } = "";
[Required]
public IList<IngredientViewModel> Ingredients { get; set; } = new List<IngredientViewModel>();
}
IngredientViewModel:
public class IngredientViewModel
{
public int Id { get; set; }
public string? Name { get; set; }
[Required]
public int Amount { get; set; }
[Required]
public string? TypeOfAmount { get; set; }
}
What I want to be able to create is something that resembles something like this:
Form
- Name
- Description
- (Ingredient1 Name; Ingredient1 Amount)
- (Ingredient2 Name; Ingredient2 Amount)
...
- (IngredientX Name; IngredientX Amount)
- [Add Ingredient ; Remove Ingredient]
Now, to the core of my question, is it possible to write the HTML/Csharp method using PartialView or even the view itself to generate something like this?
<div id="NewItem" style="display:none">
<input type="text" name="Ingredient[#_PlaceHolder_#].Name"/>
<input type="text" name="Ingredient[#_PlaceHolder_#].Amount"/>
</div>
to be a little bit more specific:
<input type="text" name="Ingredient[#_PlaceHolder_#].Amount"/>
^ ^
I wish not to hardcore these, since they can be changed while refactoring
Additionally, regarding the removal, I am kinda wondering if its possible to do this differently than just re-indexing the whole array.
Thank you all in advance for any help.
if I understand correctly
It is possible to generate a dynamic form array in ASP.NET Core without hardcoding the index. You can use JavaScript to handle the addition and removal of items in the list, but you can also make use of Razor's support for indexed properties to keep track of the index. Here's a simple example that demonstrates how this can be done:
<form asp-action="Create">
<div class="form-group">
<label asp-for="Name"></label>
<input asp-for="Name" class="form-control" />
</div>
<div class="form-group">
<label asp-for="Description"></label>
<input asp-for="Description" class="form-control" />
</div>
<div id="ingredients">
#for (var i = 0; i < Model.Ingredients.Count; i++)
{
<div class="form-group">
<label asp-for="Ingredients[i].Name"></label>
<input asp-for="Ingredients[i].Name" class="form-control" />
<label asp-for="Ingredients[i].Amount"></label>
<input asp-for="Ingredients[i].Amount" class="form-control" />
</div>
}
</div>
<button id="add-ingredient" type="button">Add Ingredient</button>
<input type="submit" value="Create" class="btn btn-primary" />
</form>
<script>
$(document).ready(function () {
var ingredients = $('#ingredients');
var index = #Model.Ingredients.Count;
$('#add-ingredient').click(function () {
ingredients.append(
'<div class="form-group">' +
'<label for="Ingredients[' + index + '].Name"></label>' +
'<input type="text" asp-for="Ingredients[' + index + '].Name" class="form-control" />' +
'<label for="Ingredients[' + index + '].Amount"></label>' +
'<input type="text" asp-for="Ingredients[' + index + '].Amount" class="form-control" />' +
'</div>'
);
index++;
});
});
</script>
In this example, the index is managed in JavaScript and appended to the name attribute of each input field. The Razor code generates the initial form inputs using a loop, and the JavaScript code adds new inputs when the "Add Ingredient" button is clicked. To remove an item, you can add a button next to each ingredient that removes its corresponding inputs.

How to find the form in scrapysharp when it only has attributes i.e. no name or id

I am new to scrapySharp as well as web scraping. I am trying to scrape a site that is secured and has a login screen. The form element does not have a name/id attribute, thus making my life more complicated. I have been unable to figure out how to load the form using the code below. Any insight is greatly appreciated!
C#:
ScrapingBrowser browser = new ScrapingBrowser();
var homepage = browser.NavigateToPage(new Uri("https://somedomain.com/ProviderLogin.action/"));
var form1 = homepage.Find("form", ScrapySharp.Html.By.Text("form"));
var form2 = homepage.FindFormById("form[action='provider-login']");
HTML:
<form action="provider-login" method="post">
<div class="login-box">
<input type="text" name="username" id="username" autocomplete="false" placeholder="Username"
class="form-control input-lg login-input login-input-username" value="" />
<input type="password" id="password" name="password" placeholder="Password" type="password"
class="form-control input-lg login-input login-input-password" />
<button name="login" type="submit" class="btn btn-primary btn-block btn-md login-btn" >
Login
</button>
</div>
</form>
You can't achieve that using in ScrapySharp using the "By" since it has just four "Element Search Kinds" :
{
Text,
Id,
Name,
Class
}
In your case, you don't have one of them so consider to use "CssSelect" instead to achieve your purpose :
var form = homepage.Html.CssSelect("form[action='provider-login']");
//Or
var form = homepage.Html.CssSelect("form[action*='provider-login']");
You can find the first form node by tag, then use the PageWebForm constructor:
var browser = new ScrapingBrowser();
var homepage = browser.NavigateToPage(new Uri("https://somedomain.com/ProviderLogin.action/"));
var form1node = homepage.Html.SelectSingleNode("//form");
var form1 = new PageWebForm(form1node, browser); // this is where it happens!
form1["username"] = "some username";
form1["password"] = "some password";
form1.Method = HttpVerb.Post;
var webpage = form1.Submit();

Asp.net MVC - form is not sent to controller

In a Asp.net MVC view, i created a form, with a input field.
The user Sets a first name (or part of it), presses the submit button.
This is the form section:
<div>
<form action="SearchCustomer" methos="post">
Enter first name: <input id="Text1" name="txtFirstName" type="text" />
<br />
<input id="Submit1" type="submit" value="Search Customer" />
</form>
</div>
This is the SearchCustomer in the Controller, that gets the data from the form:
CustomerDal dal = new CustomerDal();
string searchValue = Request.Form["txtFirstName"].ToString();
List<Customer> customers = (from x in dal.Customers
where x.FirstName.Contains(searchValue)
select x).ToList<Customer>();
CustomerModelView customerModelView = new CustomerModelView();
customerModelView.Customers = customers;
return View("ShowSearch", customerModelView);
When i run the program, and enter a first name ("Jhon" for example), the code returns to SearchCustomer function, but Request.Form is empty.
Why?
Thanks.
Your method is spelled wrongly should not read methos but method like below:
<form action="SearchCustomer" method="post">
....
</form>
You need to modify your code:
you need to provide a action name here, which should be defined in your controller(SearchController) with the same name as 'ActionName' you will put in the below code.
if SearchController is your action name then provide the controller in which the action is available.
<div>
<form action="SearchCustomer/<ActionName>" method="post">
Enter first name: <input id="Text1" name="txtFirstName" type="text" />
<br />
<input id="Submit1" type="submit" value="Search Customer" />
</form>
</div>
With Html.BeginForm :
#using (Html.BeginForm("<ActionName>","<ControllerName>", FormMethod.Post))
{
Enter first name: <input id="Text1" name="txtFirstName" type="text" />
<br />
<input id="Submit1" type="submit" value="Search Customer" />
}
Set [HttpPost] on your controller.
[HttpPost]
public ActionResult SearchFunction(string txtFirstName)
{
CustomerDal dal = new CustomerDal();
string searchValue = txtFirstName;
List<Customer> customers = (from x in dal.Customers
where x.FirstName.Contains(searchValue)
select x).ToList<Customer>();
CustomerModelView customerModelView = new CustomerModelView();
customerModelView.Customers = customers;
return View("ShowSearch", customerModelView);
}
If you View is the same name as your ActionResult method, try this:
#using(Html.BeginForm())
{
... enter code
}
By default, it'll already be a POST method type and it'll be directed to the ActionResult. One thing to make sure of: You will need the [HttpPost] attribute on your ActionResult method so the form knows where to go:
[HttpPost]
public ActionResult SearchCustomer (FormCollection form)
{
// Pull from the form collection
string searchCriteria = Convert.ToString(form["txtFirstName"]);
// Or pull directly from the HttpRequest
string searchCriteria = Convert.ToString(Request["txtFirstName"]);
.. continue code
}
I hope this helps!

'Global' variables Razor

I'm creating a form so members of a site can change the passwords for their accounts, and I'd like to display a message explaining mistakes the users made while filling the fields (such as password too short, needs at least a non-alphanumeric character, etc.). I'd like to display these messages in the same page, beside the field names. Here's my code:
#helper RenderForm()
{
<form method="post">
<p>Change your password below</p>
<div><label for="currentPassword">Current Password</label>
<input type="password" id="currentPassword" name="currentPassword"/></div>
<div><label for="newPassword">New Password:</label>
<input type="password" id="newPassword" name="newPassword"/></div>
<div><label for="confirmPassword">Confirm New Password</label>
<input type="password" id="confirmPassword" name="confirmPassword"/></div>
<div><input type="submit" id="submit" name="submit" value="submit"/></div>
</form>
}
#helper Message(string message)
{
<p>#message</p>
}
<style type="text/css">
p,label {color:black;}
</style>
#{
if(!IsPost) {
#RenderForm();
}
else {
var account = Membership.GetUser();
var currentPassword = HttpContext.Current.Request["currentPassword"];
if(Membership.ValidateUser(account.UserName, currentPassword)){
var newPassword = HttpContext.Current.Request["newPassword"];
var confirmPassword = HttpContext.Current.Request["currentPassword"];
if(check(newPassword, confirmPassword)){
account.ChangePassword(account.ResetPassword(), newPassword);
}
}
else {
#Message("The password provided didn't match with the database.");
}
}
}
#functions{
List<string> check(string newPassword, string confirmPassword)
{
//just a place holder
return false;
}
}
I've tried adding a List to be filled when an error was found, and when the form was reloaded the message would be displayed, but the RenderForm() function can't find any reference to the List. How can I display these messages?
You should use the built in validation that comes with the Web Pages framework. I have an article that explains how to use it: http://www.mikesdotnetting.com/Article/191/Validation-In-Razor-Web-Pages-2

C# ASPX - Form Submission Query

I have a C# aspx form in which I need to input it's data into an SQL database and then return a response saying successful or not. I have no idea how to get the form data that is sent from the Default.aspx page. My basic code structure is below:
Default.aspx
<form runat="server" name="aForm" action="Results.aspx" method="post" onsubmit="ValidateForm()">
<input name="firstname" type="text" />
<input name="surname" type="text" />
<input type="submit" value="Submit" />
</form>
Results.aspx.cs
public partial class AwardsForm : System.Web.UI.Page {
protected void Page_Load(object sender, EventArgs e) {
if (!this.IsPostBack){
Response.Redirect("Default.aspx");
} else (this.IsPostBack) {
writeResults(FormSubmit());
}
protected boolean FormSubmit() {
// get form data and insert it into SQL
// return true/false based on success
}
protected void writeResults(boolean results) {
if (results == true) {
Response.Write ("Success");
} else {
Response.Write ("Failed");
}
}
}
You can get the posted form data through Request.Form["key"], or, if your form elements are decorated with runat="server" then you should be able to grab them by id right in your code behind
<asp:TextBox id="yourTb" runat="server"></asp:TextBox>
string postedText = yourTb.Text;
Or you can do (though this is much less common)
<input type="text" runat="server" id="yourOtherTb" />
string otherPostedText = yourOtherTb.Value;
Or if you're working with purely html form inputs:
<input type="text" id="clientTb" name="clientTb" />
string clientText = Request.Form["clientTb"];
You can try by the following code.
string firstname = Request.Form["firstname"]
string surname = Request.Form["surname"]
Since you are doing something like this
<input name="firstname" type="text" />
<input name="surname" type="text" />
<input type="submit" value="Submit" />
the name attribute of the input controls are posted back to the server(IIS). Hence you would do this.
If(IsPostBack)
{
string firstName = Request.Form["firstname"];
string surName = Request.Form["surname"];
if(string.IsNullOrEmpty(firstName))
{
Response.Write("Firstname is required this form");
}
}

Categories