I have an asp.net application which allows a file upload and I had this working correctly but now I have custom styled my file upload field it's no longer working and I can't figure out how to get it working again with my new styled field.
OLD HTML
<div class="form-group">
<asp:Label ID="Label3" class="col-md-3 control-label" runat="server" Text="Upload"></asp:Label>
<div class="col-md-3">
<asp:FileUpload ID="fuAttachment" runat="server" class="fileupload"></asp:FileUpload>
</div>
</div>
OLD Code Behind
var file = fuAttachment.PostedFile;
if (file != null && fuAttachment.PostedFile.FileName != "")
{
var content = new byte[file.ContentLength];
file.InputStream.Read(content, 0, content.Length);
Session["FileContent"] = content;
Session["FileContentType"] = file.ContentType;
Session["File"] = fuAttachment.FileName;
Session["AttachmentProvided"] = "Yes";
}
NEW HTML
<div class="fileinput fileinput-new input-group" data-provides="fileinput">
<div class="form-control" data-trigger="fileinput" style="background-color: #ededed">
<span class="fileinput-filename"></span>
</div>
<span class="input-group-addon btn btn-default btn-file">
<span class="fileinput-new">
<span class="glyphicon glyphicon-folder-open" title="Click to select a file."></span>
</span>
<span class="fileinput-exists">
<span class="glyphicon glyphicon-folder-open" title="Click to change the selected file."></span>
</span>
<input type="file" name="...">
</span>
<a href="#" class="input-group-addon btn btn-default fileinput-exists" data-dismiss="fileinput">
<span class="glyphicon glyphicon-remove" title="Remove selected file."></span>
</a>
</div>
I need to store in my session as this populates another page so I need similar code behind as I had
Edit file input to :
<input type="file" id="fuAttachment" runat="server" />
Now you use fuAttachment from codebehind for access uploaded file.
Note: If runat="server" attribute is missing you don't able to control this input from codebehind.
Related
I am a just starting out with Puppeteer.NET, and i can't get it to autofill a login page.
The HTML for the web site looks like this:
<div class="main-wrapper">
<div class="row">
<div class="column section col-md-8">
<div class="loginForm">
<img src="images/logo.svg" width="300">
<br /><br /><br />
<div style="color: #454550; font-family: 'Neuzeit Grotesk'; font-size: 16px; ">
Welcome back
</div>
<br />
<form action="/login?app=LM&var=au" method="POST" name="login-form" id="login-form">
<input type="hidden" name="_csrf" value="BQ2YoR3d-5P__6b5HfqlVOjv8YgTypKV92XA" />
<div class="form-group text-center">
<input type="text" name="username" id="login-form-username" placeholder="Username" class="form-control" required value="">
</div>
<div class="form-group text-center">
<input type="password" name="password" id="login-form-password" placeholder="Password" class="form-control" required>
</div>
<div class="text-center">
<button type="submit" class="btn btn-danger btn-lg btn-block">Login</button>
</div>
</form>
<div style="color: #808083; margin-top: 30px; font-family: 'Roboto2';">
Trouble logging in?
<img src="images/grey_line.svg" width="300">
Sign up
</div>
</div>
<div style="text-align: center; width:400px;">
<img src="images/logo.svg" width="300">
</div>
</div>
<div class="column section col-md-4">
<iframe width="100%" height="100%" frameBorder="0" src="https://"></iframe>
</div>
</div>
</div>
I am trying to get it to fill in the login and password fields, and press the login button.
I am doing it as:
var extra = new PuppeteerExtra();
var stealth = new StealthPlugin();
LaunchOptions options = new LaunchOptions
{
Headless = false,
ExecutablePath = "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe"
};
Browser browser = extra.Use(stealth).LaunchAsync(options).Result;
string content = null;
using (Page page = browser.NewPageAsync().Result)
{
// do login screen
page.GoToAsync(url);
page.WaitForNavigationAsync();
page.WaitForSelectorAsync("username");
page.FocusAsync("username");
page.Keyboard.TypeAsync(login);
page.WaitForSelectorAsync("password");
page.FocusAsync("password");
page.Keyboard.TypeAsync(password);
page.ClickAsync("submit");
page.WaitForNavigationAsync();
content = page.GetContentAsync().Result;
}
I have tried changing the "username" to "#username" and some other variations, but nothing gets filled in. Ultimately, all I want to to login and then go to a specific page, and have a dump of the resultant HTML.
Also is there a easy way to just a text dump of the resultant HTML?
You can use the selectors #login-form-username and #login-form-password, those are the IDs.
I am using ASP.NET Core MVC with identity but I want to perform my own logic on login. So, what I did is I scaffolded the login page and make my own design.
Here is my form:
#page
#model LoginModel
#{
ViewData["Title"] = "Login";
}
<div class="login-page cnt-bg-photo overview-bgi" style="background-image:
url('#Url.Content("~/assets/img/banner-1.jpg")')">
<div class="container">
<div class="row">
<div class="col-lg-12">
<div class="forgot-box contact-2 clearfix">
<div class="login-header clearfix">
<div class="pull-left">
<h4>Login</h4>
</div>
</div>
<!-- <div role="alert"
class="alert alert-danger font-12">
<strong>Oops!!</strong> Invalid Email or Password
</div>-->
<p>Please enter your user name and password to login</p>
<form action="/Account/Login" method="POST">
<div class="form-group">
<label asp-for="Input.Email"></label>
<input asp-for="Input.Email" class="form-control" />
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Input.Password"></label>
<input asp-for="Input.Password" class="form-control" />
<span asp-validation-for="Input.Password" class="text-danger"></span>
</div>
<div class="form-group w-46-f float-left">
<div class="form-check checkbox-theme pull-left">
<div class="checkbox">
<label asp-for="Input.RememberMe">
<input asp-for="Input.RememberMe" />
#Html.DisplayNameFor(m => m.Input.RememberMe)
</label>
</div>
</div>
</div>
<div class="form-group float-right">
<label class="pull-right forgotpassword-label">Forgot Password ?</label>
</div>
<div class="clearfix"></div>
<button type="submit" class="btn btn-color btn-md pull-right">Login</button>
</form>
<div class="clearfix"></div>
<div class="text-center p-t-46 p-b-20 font-14">
<span class="txt2">
Or Login with
</span>
</div>
<div class="login100-form-social flex-c-m">
<form id="external-account" asp-page="./ExternalLogin" asp-route-returnUrl="#Model.ReturnUrl" method="post">
#foreach (var provider in Model.ExternalLogins)
{
if (provider.DisplayName == "Google")
{
<button type="submit" class="btn login100-form-social-item flex-c-m bg3 m-r-5" style="display: inline-block" name="provider" value="#provider.Name" title="Log in using your #provider.DisplayName account"><i class="fab fa-google"></i></button>
}
else if (provider.DisplayName == "Facebook")
{
<button type="submit" class="btn login100-form-social-item flex-c-m bg1 m-r-5" style="display: inline-block" name="provider" value="#provider.Name" title="Log in using your #provider.DisplayName account"> <i class="fab fa-facebook-f"></i></button>
}
else if (provider.DisplayName == "Twitter")
{
<button type="submit" class="btn login100-form-social-item flex-c-m bg2 m-r-5" style="display: inline-block" name="provider" value="#provider.Name" title="Log in using your #provider.DisplayName account"> <i class="fab fa-twitter"></i></button>
}
}
</form>
</div>
<hr>
<div class="text-center forgotpassword-label font-14">
Not a member?
<a href="#Url.Action("Packages","Account")">
<strong>Sign up now</strong>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
#section Scripts {
<partial name="_ValidationScriptsPartial" />
}
Now I want to post the login data to my own controller action. But it get null on my action method. Parameters are not filled with actual data of the form.
Here is my controller method:
[HttpPost]
public IActionResult Login(LoginModel.InputModel model)
{
//My logic
return View();
}
Why does it get model parameter as null?
Well, specifically, the source of it being null is the fact that in the Razor Page, all the input names begin with Input. because for the code-behind, the model being bound to is LoginModel and the data in those inputs will be bound to the InputModel property (Input) there. However, in your controller, you're binding directly to InputModel, and InputModel has no Input member. As a result, none of the posted inputs match anything and are therefore not bound.
If you're going to post from a Razor Page, you need to do it to a Razor Page. There's just too many inconsistencies between Razor Pages and MVC to line everything up correctly. If you you want to use a controller, you're going to need a view specifically geared for that, not your Razor Page.
I'm trying to use a textbox value in controller route and am having some trouble with the syntax. Essentially, I have my end users selecting a file and then submitting the data to the api to process and send the data off. I have working static code below, but can't get the xml path to be dynamically populated via the textbox value.
note that (as far as I can tell) the forward slash at the end of the path is required since there is a dot in the file path.
#using (Html.BeginForm("", "api/food/dummy food file.xml/"))
{
<div class="row">
<div class="col-lg-6">
<label class="control-label">Select File</label>
<div class="input-group">
<label class="input-group-btn">
<span class="btn btn-default">
Browse… <input type="file" style="display: none;" single>
</span>
</label>
<input id="food.filepath" name="food.filepath" type="text" class="form-control" readonly>
</div>
</div>
</div>
<br />
<div>
<button id = "btnSubmit" type="submit" class="btn btn-primary">Submit</button>
</div>
}
I don't what the syntax would be, but I can't get something like the below to work.
#using (Html.BeginForm("", "api/food/" + food.filepath + "/"))
{
<div class="row">
<div class="col-lg-6">
<label class="control-label">Select File</label>
<div class="input-group">
<label class="input-group-btn">
<span class="btn btn-default">
Browse… <input type="file" style="display: none;" single>
</span>
</label>
<input id="food.filepath" name="food.filepath" type="text" class="form-control" readonly>
</div>
</div>
</div>
<br />
<div>
<button id = "btnSubmit" type="submit" class="btn btn-primary">Submit</button>
</div>
}
Because the form is rendered on server and the value food.filepath is on client, you cannot mix them. Changing form action according to client values need to be done on client with javascript.
You can remove the file from action a add it on submit javascript action, for example by changing BeginForm to this:
#using (Html.BeginForm("", "api/food/", FormMethod.Get, new { onSubmit = "this.dataset.act = this.dataset.act||this.action; this.action = this.dataset.act + this['food.filepath'].value" } ))
I have an ASP.net web application which saves all details entered in the session and at the end, sends an email with all the details including an attachment of the file uploaded (all this currently works fine).
The issue I have is that a change is required to the file upload page. I want to now be able to upload multiple docs, but separately, so basically the user finds the file to upload then clicks an 'Add' button. The upload file field should then clear and a table should populate with the uploaded file(s) with a 'Remove/Delete' button for each file uploaded.
The details that should be displayed in this table are:
File name
Option selected form the new dropdown list
Remove button
As I said I have single file upload working using the code behind but I have no idea how to implement what I'm after so that all uploaded doc's are sent in my email.
Current HTML
<div class="form-group">
<div class="col-sm-offset-2 col-sm-5">
<div class="fileinput fileinput-new input-group" data-provides="fileinput">
<div class="form-control" data-trigger="fileinput" style="background-color: #ededed">
<span class="fileinput-filename"></span>
</div>
<span class="input-group-addon btn btn-default btn-file">
<span class="fileinput-new">
<span class="glyphicon glyphicon-folder-open" title="Click to select a file."></span>
</span>
<span class="fileinput-exists">
<span class="glyphicon glyphicon-folder-open" title="Click to change the selected file."></span>
</span>
<input type="file" name="..." id="fuAttachment" runat="server" />
</span>
</div>
</div>
<div class="col-sm-3">
<asp:DropDownList ID="Step03WebTypeDD" runat="server" class="form-control">
<asp:ListItem Value="- - Please select - -">- - Please select - -</asp:ListItem>
<asp:ListItem Value="Requirements">Requirements</asp:ListItem>
<asp:ListItem Value="Functional specification">Functional specification</asp:ListItem>
<asp:ListItem Value="Page Content">Page Content</asp:ListItem>
<asp:ListItem Value="Page Designs">Page Designs</asp:ListItem>
<asp:ListItem Value="Page Designs">Other</asp:ListItem>
</asp:DropDownList>
</div>
<div class="col-sm-1">
<asp:LinkButton ID="UploadAddButton" runat="server" OnClick="Step05UploadAddButton_Click" CssClass="btn btn-success pull-right" ToolTip="Click to upload the file.">
<span class="glyphicon glyphicon-plus"></span> Add
</asp:LinkButton>
</div>
</div>
Current Code Behind
protected void Step05UploadAddButton_Click(object sender, EventArgs e)
{
var file = fuAttachment.PostedFile;
if (file != null && fuAttachment.PostedFile.FileName != "")
{
var content = new byte[file.ContentLength];
file.InputStream.Read(content, 0, content.Length);
Session["FileContent"] = content;
Session["FileContentType"] = file.ContentType;
Session["File"] = fuAttachment.PostedFile.FileName;
Session["AttachmentProvided"] = "Yes";
}
else
{
Session["FileContent"] = "";
Session["FileContentType"] = "";
Session["File"] = "";
Session["AttachmentProvided"] = "No";
}
}
My code behind does not capture the option selected but will need to so I can display it on my confirmation page (HTML shown below)
<div class="form-group">
<asp:Label ID="Label6" class="col-xs-6 col-sm-3 control-label" runat="server" Text="Attachment provided:"></asp:Label>
<div class="col-xs-6 col-sm-9 form-control-static">
<% if (Session["AttachmentProvided"] == "Yes")
{%>
Yes (<%=Session["File"] %>)
<%}
else
{ %>
No
<%} %>
</div>
</div>
You can use JavaScript to add additional <input type="file" /> elements to the DOM, and generically refer to all of the files using Request.Files as mentioned on MSDN. A sample taken from MSDN:
Files = Request.Files; // Load File collection into HttpFileCollection variable.
arr1 = Files.AllKeys; // This will get names of all files into a string array.
for (loop1 = 0; loop1 < arr1.Length; loop1++)
{
Response.Write("File: " + Server.HtmlEncode(arr1[loop1]) + "<br />");
Response.Write(" size = " + Files[loop1].ContentLength + "<br />");
Response.Write(" content type = " + Files[loop1].ContentType + "<br />");
}
I'm using razor html and attempting to post data to a function. I can get parts of the data to submit and go across just fine but other parts i can not.
#using (Html.BeginForm("Reply", "api/Reply", new { ID = Model.ID, UserName = Model.Username }))
{
<div id="mainArea" class="lightboxContent" style="display: block">
<div class="lightboxText">
<div class="responderTitleLeft">Select Profile: </div>
<div class="responderFormFloat">
<select name="profileSelector" class="select-style">
<option value="Select One" selected>Please Select Your Profile</option>
#foreach (var profile in Model.ProfileModels)
{
<option value="#profile.ProfileID">#profile.ScreenName</option>
}
</select>
</div>
<div class="responderActions">
<div id="Reply" class="TwtiterReply">
<a href="javascript:void(0)">
<img src="/images/engage/actions/reply.png" onclick="toggle('ReplyArea')" title="Reply to message" />
</a>
</div>
<div id="ReplyArea" style="display: none;" class="responderForm">
<div class="responderTitle">Reply</div>
<textarea id="MessageEdit" name="Message" onkeyup="return characterCount(this)" onchange="postChange(this.id, 'messagePreview');" rows="4" cols="50" style="resize: none">#Model.Username</textarea>
<p id="counter"><strong><span id="charCount">140</span></strong> more characters available.</p>
<div class="lightboxButtonsBar">
<input type="button" onclick="toggle('mainArea')" tabindex="3" value="Reply" />
<input type="button" class="cancel" tabindex="4" value="Cancel" />
</div>
</div>
</div>
</div>
</div>
<div id="confirmArea" class="confirmationArea" style="display: none">
<div class="warning">
<p><strong>Warning:</strong></p>
</div>
<div class="warningMessage">
<p>You are posting from #Model.ProfileModels with the message:</p>
<div class="messagePreviewArea" data-form="Reply">
<p>
<textarea id="messagePreview" readonly rows="4" cols="50" style="color: #ffffff; font-size: .9em; background-color: transparent; resize: none; border-color: #808080;"></textarea></p>
<input type="submit" tabindex="3" value="Confirm" />
<input type="button" onclick="toggle('mainArea')" tabindex="3" value="Cancel" />
</div>
</div>
</div>
}
public UserProfile Reply(string ID, string UserName, FormCollection form)
{
var pSelector = form["profileSelector"];
var message = form["Message"];
ApiService msgserv = new ApiService();
UserProfile up = UserProfile.GetFirst(new Guid(pSelector));
messenger.Reply(up.key, UserName, ID, message);
return up;
}
what i'm looking to get out of this form (in order of how it's show) ID, and username (they are provided by the model and i get those no problem.)
The ones i'm having issues with is the profile selector and the text area with the name message.
Can someone point me in the right direction on how to get a textarea and a select into a form?
The reason the select is not providing the model with data is because its name property is not set to corresponing property name in the model. The same goes for the text area. Generally speaking, if you want the form submit to fill those property you use the 'strongly-typed' helper methods, such as DropdownFor and CheckBoxFor. Or you can manually wire those up, try setting the name of the select element to "SelectedProfile" and changing the Reply action to: Reply(string ID,string Username,string SelectedProfile, FormCollection form)
To get from the textarea do something like this on your view #Html.TextArea("messagePreview"); But I would recommend saving things in your model if you can.