MVC Model validation on "HttpPostedFileWrapper" - asp.net-mvc

Can someone help me with model validation on a HttpPostedFileWrapper object?
Model:
[Required(AllowEmptyStrings = false)]
public HttpPostedFileWrapper BlahFile { get; set; }
Controller:
[HttpPost]
public ActionResult LoadBlahData(BlahModel blahModel)
{
if (!ModelState.IsValid)
return RedirectToAction("Index");
}
cshtml:
#using (Html.BeginForm("LoadBlahData", "Admin", FormMethod.Post, new { #class = "blahhForm", enctype = "multipart/form-data", id = "uploadBlah" }))
{
<fieldset>
<legend>Upload Blah Information</legend>
#Html.LabelFor(x=>x.BlahFile, "Upload Blah file:")
<input size="26" class="uploader" type="file" name="BlahFile" />
<p><input class="ttButton" type="submit" value="Load Stuff" /></p>
</fieldset>
}
Problem:
Cannot see the "data-val*" attributes being added to the html.
Does not set the unobtrusive validation off (red border on input box)
Notes:
Other items in the Model are working fine with validation, its only the <input type="file"/> that seems to be having problems.
Comes into the action method fine - (i.e - i can access the InputStream if i want).
All scripts are referenced correctly (its working on normal text input's)
Thanks in advance,

Just for anyone else coming across this question you can also do this -
<%: Html.TextBoxFor(x => x.BlahFile, new { type = "file" }) %>

you have not added any data attributes to your element. Add it like,
<input data-pk="1" size="26" class="uploader" type="file" name="BlahFile" />
and there is no support of validation of <input type="file"

Related

upload image from view to controller 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

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.

Update and ASP.NET MVC model on button click

I'm new to ASP.NET MVC. I'm trying to update model on button click with no success: every time I push the button an HttpGet controller method is invoked.
Here is my markup
#model DataInterface.Model.Entry
<button onclick="location.href='#Url.Action("Survey")'">Finish survey</button>
Here is Controller code
[HttpGet]
public ActionResult Survey()
{
var entry = new Entry();
return View(entry);
}
[HttpPost]
public ActionResult Survey(Entry newEntry)
{
// save newEntry to database
}
When I click button HttpGet method is invoked. Why?
It is bad to be a rookie)
Thanks to all!
If you access a URL without explicitly specifying the HTTP method, ASP.NET MVC will assume a GET request. To change this, you can add a form and send it:
#using (Html.BeginForm("Survey", "Controller", FormMethod.Post))
{
<input type="submit" value="Finish survey" />
}
If you do this, your POST method will be invoked. The Entry parameter, however, will be empty, since you do not specify any values to send along with the request. The easiest way to do so is by specifying input fields, e.g. text inputs, dropdown, checkboxes etc.
#using (Html.BeginForm("Survey", "Controller", FormMethod.Post))
{
#Html.TextBoxFor(m => m.Title)
<input type="submit" value="Finish survey" />
}
If you have the object stored on the server somewhere and only want to finish it off by writing it into the database or changing its status, you could pass the Id of the object (or some temporary Id) along the post request and make the controller method work only with the Id:
#using (Html.BeginForm("Survey", "Controller", FormMethod.Post))
{
#Html.HiddenFor(m => m.Id)
<input type="submit" value="Finish survey" />
}
[HttpPost]
public ActionResult Survey(Entry newEntry)
{
// newEntry.Id will be set here
}
#using (Html.BeginForm("Survey", "<ControllerName>", FormMethod.Post))
{
<input type="submit" value="Finish survey" />
}
you must declare your form
#model DataInterface.Model.Entry
#using (Html.BeginForm("action", "Controlleur", FormMethod.Post, new {#class = "form", id = "RequestForm" }))
{
<input type="submit" value="Finish survey" />
}

How can I get both a model and HttpPostedFileBase into a controller?

I've looked quite a bit online, and every example I see explains how to get IEnumerable<HttpPostedFileBase> into a controller, OR how to get a model, but not both.
What I want is something like:
<form>
<input type="text" name="Stored file name>
<input type="file" multiple="multiple" name="files>
<input type="submit">
</form>
with controller
[ActionName("Index"), HttpPost]
public ActionResult IndexPost(Models.MyModel mdl, IEnumerable<HttpPostedFileBase> files)
{
// Do some something with the data in mdl and files here
return RedirectToAction("Index");
}
But every way I try to implement this, it comes back 'no parameterless handler found'. It works fine if I don't include the model.
Am I missing something really obvious?
I guess you couldn't find Darin's this post. It's not exactly about passing model with HttpPostedFileBase but if you undrerstand the behavior the it's easy to do that.
See below example.
View
#model WebApplication2.Models.MyModel
#using (Html.BeginForm("Index", "Home", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.HiddenFor(m => m.Id)
<input type="file" name="file" />
<input type="submit" value="OK" />
}
Action Method
[HttpPost]
public ActionResult Index(MyModel model, HttpPostedFileBase file)
{
if (file != null)
{
//do your stuff here
}
return View();
}

ASP.NET MVC - Can't bind array to view model

I have a view model with a from that includes a set of checkboxes. I need the check boxes to map to an array when binding in the post back method of my controller.
Here's the view model.
#model TMDM.Models.TestSeriesCreateViewModel
#{
ViewBag.Title = "Create";
}
<h2>Create a Test Series</h2>
#using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<div class="editor-label">
#Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Title)
#Html.ValidationMessageFor(model => model.Title)
</div>
<h3>Which Test Collections are in this Test Series?</h3>
<div class="editor-field">
#{
var i = 0;
foreach (var testCollection in Model.TestCollections)
{
<input type="checkbox" id="ChosenTestCollectionIds[#i]" name="ChosenTestCollectionIds[#i]" value="#testCollection.Id" />
<span>#testCollection.Title</span>
<br />
i++;
}
}
</div>
<p>
<input type="submit" value="Save" class="medium green awesome" />
#Html.ActionLink("Cancel", "Index", "TestSeries", null, new { #class = "medium black awesome" })
</p>
</fieldset>
The form is rendering fine, I've checked the source and each output check box has a different number for their id and name fields.
<input type="checkbox" id="ChosenTestCollectionIds[0]" name="ChosenTestCollectionIds[0]" value="5" />
<input type="checkbox" id="ChosenTestCollectionIds[1]" name="ChosenTestCollectionIds[1]" value="6" />
//etc...
Here is the view model.
public class TestSeriesModel
{
public int Id { get; set; }
public string Title { get; set; }
}
public class TestSeriesCreateViewModel : TestSeriesModel
{
public List<ITestCollectionDataObject> TestCollections { get; set; }
public int[] ChosenTestCollectionIds { get; set; }
}
Problem I'm having is that when the form posts back the ChosenTestCollectionIds array comes back null. What am I doing wrong here?
ANSWER
I've worked out how to do it:
<input type="checkbox" id="[#i]" name="ChosenTestCollectionIds" value="#testCollection.Id" />
<input type="checkbox" id="[#i]" name="ChosenTestCollectionIds" value="#testCollection.Id" />
I always come back to Phil Haack's post about model binding a list. In addition, I always define my own index because my user's will alter the list on the client side then post back the changes.
http://haacked.com/archive/2008/10/23/model-binding-to-a-list.aspx
Set the name of the input types to all be the same. You can also create a custom model binder if you are trying to bind a more complex model than just a list. Here is an excellent article on the different ways to bind to your models
Various Model Binding techniques

Resources