upload image from view to controller mvc - asp.net-mvc

Good day,
I am trying to upload an image from my view
#using (Html.BeginForm("CrearCurso", "ProfesorCurso", null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="form-group">
<label>Upload Image</label>
<div class="input-group">
<span class="input-group-btn">
<span class="btn btn-default btn-file">
Browse… <input type="file" id="imgInp">
</span>
</span>
<input type="text" class="form-control" readonly>
</div>
<img id='img-upload'/>
</div>
}
I have this controller in mvc
[HttpPost]
public ActionResult CrearCurso(CursoViewModel CursoViewModel, HttpPostedFileBase imgInp)
{
return View();
}
However when I inspect the HttpPsotedFileBase, it is empty. What is wrong here? thanks

Forms posts back the name/value pairs of its successful form controls. Your file input has no name attribute. Change it to
<input type="file" name="imgInp">
However, its better to strongly bind to your model, so add a
public HttpPostedFileBase ImgInp { get; set; }
property to your view model and use
#Html.TextBoxFor(m => m.ImgInp, new { type = "file" })
which will also allow you to add validation attributes to your file input if required

Related

Asp.Net MVC Core built-in tag helpers won't process attributes provided from custom taghelpers

Out of boredom of writing the same boilerplate forms, I thought I'd rather write a tag helper that would produce attributes that can be processed from stock tag helpers. But, even though I managed to get my tag helper before work before form tag helpers, form tag helpers won't process the ones that I produce.
Here is the cshtml:
#model City
#{
Layout = "_Layout";
ViewData["Title"] = "Create City";
}
<form method="post" asp-action="Create">
#foreach (string propName in BaseModel.GetProperties<City>()) {
<formgroup for="#propName" />
}
<div class="form-group">
<label asp-for="Name">Name:</label>
<input class="form-control" asp-for="Name" />
</div>
<div class="form-group">
<label asp-for="Country">Country:</label>
<input class="form-control" asp-for="Country" />
</div>
<div class="form-group">
<label asp-for="Population">Population:</label>
<input class="form-control" asp-for="Population" />
</div>
<button type="submit" class="btn btn-primary">Create</button>
<a class="btn btn-secondary" asp-controller="Home" asp-action="Index">Cancel</a>
</form>
Here is the output:
<form method="post" action="/City/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="Country"></label><input asp-for="Country" class="form-control"></div>
<div class="form-group"><label asp-for="Population"></label><input asp-for="Population" class="form-control"></div>
<div class="form-group">
<label for="Name">Name:</label>
<input class="form-control" type="text" id="Name" name="Name" value="">
</div>
<div class="form-group">
<label for="Country">Country:</label>
<input class="form-control" type="text" id="Country" name="Country" value="">
</div>
<div class="form-group">
<label for="Population">Population:</label>
<input class="form-control" type="number" data-val="true" data-val-required="The Population field is required." id="Population" name="Population" value="">
</div>
<button type="submit" class="btn btn-primary">Create</button>
<a class="btn btn-secondary" href="/">Cancel</a>
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8M_6usK6CRRNkwluTiTW8uaAAfhMcU9tAxyCT7z55zQKmpUwpi_lfSDIN4FrlMo9cE3Ka9zgX4WdpXHUdlBFVGsLIw7h_cR3FjJb6Vjqnjm8mQmtKTey_9l188p9E2sKgiksO_OB6K9-F1D7SP2lX0g"></form>
Here is my tag helper:
using Microsoft.AspNetCore.Html;
using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading.Tasks;
namespace ViewComponents.Infrastructure.TagHelpers {
[HtmlTargetElement("formgroup", Attributes = "for", TagStructure = TagStructure.NormalOrSelfClosing)]
public class FormGroupTagHelper : TagHelper {
/// <inheritdoc />
public override int Order => -2000;
[HtmlAttributeNotBound]
[ViewContext]
public ViewContext ViewContext { get; set; }
protected IHtmlGenerator Generator { get; }
public string For { get; set; }
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output) {
if (context == null) {
throw new ArgumentNullException(nameof(context));
}
if (output == null) {
throw new ArgumentNullException(nameof(output));
}
// So that other tag helpers are processed after me...
var childContent = await output.GetChildContentAsync();
// Starting up...
// Replace the tag name, include the form-group bootstrap class.
output.TagName = "div";
output.TagMode = TagMode.StartTagAndEndTag;
output.Attributes.Add("class", "form-group");
PropertyInfo propInfo = ViewContext.ViewData.ModelMetadata.ModelType.GetTypeInfo().GetDeclaredProperty(For);
output.Content.AppendHtml(GenerateLabel(new Dictionary<string, string> { ["asp-for"] = propInfo.Name }));
output.Content.AppendHtml(GenerateInput(new Dictionary<string, string> { ["asp-for"] = propInfo.Name, ["class"] = "form-control" }));
}
public static IHtmlContent GenerateLabel(IReadOnlyDictionary<string, string> attrDict) {
TagBuilder tBuilder = new TagBuilder("label");
foreach (var kvp in attrDict)
tBuilder.Attributes.Add(kvp);
return tBuilder;
}
public static IHtmlContent GenerateInput(IReadOnlyDictionary<string, string> attrDict) {
TagBuilder tBuilder = new TagBuilder("input");
foreach (var kvp in attrDict)
tBuilder.Attributes.Add(kvp);
return tBuilder;
}
}
}
Any help will be appreciated.
Have a nice one!
Tag Helpers aren't processed in a specific order, so you cannot count on one being able to do something based on the output of the other. Each tag helper needs to be designed to work independently of any other, so if you need to render HTML, you'll need to handle that yourself in your tag helper. However, since you're trying to have one tag generate any kind of form field, that's going to be a heavy lift. This is basically beyond the scope of what a tag helper is intended for.

Send Forms issue

I'm developing an application on asp.net.I use the standard modelbinder
I have code
#model Sciencecom.Models.Billboards1
#{
ViewBag.Title = "CreateBilboard";
SelectList owners = new SelectList(new SciencecomEntities().Owners.Select(m=>m.Name).ToList());
}
#using (Html.BeginForm("Bilboard", "Data", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true)
#Html.ValidationMessage("Error")
#*владелец*#
<input type="text" name="Locality" value="345"/>
<input type="text" name="Locality" value="3435" />
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Добавить" class="btn btn-default" />
</div>
</div>
</div>
}
I send form on controller.but i have issue .I have reference-null
public ActionResult Bilboard( IEnumerable<Sciencecom.Models.Billboards1> Billboard, IEnumerable<Sciencecom.Models.Surface> test)
{
return View();
}
what ideas?
Inside your form you have only 2 input fields with the same name (Locality) which is quite confusing. So on your server all you can get is a variable with the same name as your input field because that's the only information that is posted back when the form is submitted:
public ActionResult Bilboard(Locality locality)
{
...
}
In the code you have shown in your question your Bilboard action seem to be taking some Billboard and test collection arguments but they are not present as input fields inside your form so you cannot possibly expect them to be populated.

Uploading a file will pass a null object

I have the following _CreateOrEditPartial partial view which contain a text & a file upload:-
#model TMS.Models.DataCenter
#* This partial view defines form fields that will appear when creating and editing entities *#
#Html.AntiForgeryToken()
<div>
<span class="f">Name </span>
#Html.EditorFor(model=>model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
<div>
<span class="f">Data Center Picture </span>
<input type="file" name="DataCenterfile" />
</div>
and the following main view :-
#using (Html.BeginForm("Create","DataCenter", FormMethod.Post))
{
#Html.ValidationSummary(true)
#Html.Partial("_CreateOrEdit", Model)
<input type="submit" value="Create" class="btn btn-primary"/>
}
Which will call the following ActionMethod:-
[HttpPost]
[ValidateAntiForgeryToken]
[CheckUserPermissions(Action = "Edit", Model = "DataCenter")]
public ActionResult Create(DataCenter dc, HttpPostedFileBase DataCenterfile)
{
// Verify that the user selected a file
if (DataCenterfile != null && DataCenterfile.ContentLength > 0)
{
// extract only the fielname
var fileName = Path.GetFileName(DataCenterfile.FileName);
// store the file inside ~/App_Data/uploads folder
var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
DataCenterfile.SaveAs(path);
}
but the datacenterfile will always be null .. can anyone advice what is causing this problem?
Thanks
You forgot to add the enctype attribute to your form.
Something like this:
#using (Html.BeginForm("actionName", "controllerName", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
}
About enctype attribute: What does enctype='multipart/form-data' mean?

how to upload file in Strong-Type view in ASP.NET MVC

I use:
#using (Html.BeginForm("UploadPackage", "Manager"))
to send webForm data to UploadPackage action.
Now I add an input tag whose type is file(< input type = "file" />) in that strong-type view. What I want to do is: How can I get all data from webForm (including file) in my Action and handle them?
Form in view:
#using (Html.BeginForm("FileUpload", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.ValidationSummary();
<ol>
<li class="lifile">
<input type="file" id="fileToUpload" name="file" />
<span class="field-validation-error" id="spanfile"></span>
</li>
</ol>
<input type="submit" id="btnSubmit" value="Upload" />
}
At Controllers side :
[HttpPost]
public ActionResult FileUpload(HttpPostedFileBase file)
{
// Implementation
}

HttpPostedFileBase is Not Being Populated

I have a model (simplified, removing extraneous properties):
public class SubmitModel
{
[Required]
[DataType("FileUpload")]
[Display(Name = "Formatted Data File")]
public HttpPostedFileBase FormattedDataFile { get; set; }
}
A controller:
[HttpPost]
public ActionResult Submit(SubmitModel model)
{
if (this.ModelState.IsValid)
{
//...
}
return this.View(model);
}
A FileUpload view:
#{
IDictionary<string, object> htmlAttributes = Html.GetUnobtrusiveValidationAttributes(string.Empty);
}
<input type="file" id="#this.ViewData.TemplateInfo.GetFullHtmlFieldId(string.Empty)" name="#this.ViewData.TemplateInfo.GetFullHtmlFieldName(string.Empty)" #(new MvcHtmlString(htmlAttributes.ToHtmlAttributesString())) />
#Html.ValidationMessage(string.Empty)
And a simple view:
#model SubmitModel
#using (Html.BeginForm())
{
<div class="Form">
#Html.EditorForModel()
<div class="Footer">
<button class="Button" data-options='{ "icons": { "primary": "ui-icon-disk" } }'>Submit</button>
</div>
</div>
}
Which renders to this HTML:
<form action="/Data/Submit" method="post">
<div class="Form">
<div class="Item">
<div class="Label Required">Formatted Data File:</div>
<div class="Input">
<input type="file" id="FormattedDataFile" name="FormattedDataFile" data-val-required="The Formatted Data File field is required." data-val="true" />
<span class="field-validation-error" data-valmsg-for="FormattedDataFile" data-valmsg-replace="true">The value 'Test.xlsx' is invalid.</span>
</div>
</div>
<div class="Footer">
<button class="Button" data-options='{ "icons": { "primary": "ui-icon-disk" } }'>Submit</button>
</div>
</div>
</form>
Upon clicking Submit, I'm brought to the proper controller/action and my model's FormattedDataFile property is null. The ModelState is invalid, saying that "The Formatted Data File field is required." This same code worked fine in some MVC-3 projects I've done - is there anything different regarding this in MVC-4?
i think you are missing enctype="multipart/form-data" in the form
http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2

Resources