How to pass string object data to mvc controller for posting? - c#

This is my code
<form class="form-horizontal formtext col-xs-12 col-sm-10 col-lg-10 row">
<div class="form-group">
<div class="col-xs-12 col-sm-5 col-lg-3 paddnone">
<label class="control-label">First Name</label>
</div>
<div class="col-sm-5" ng-if="!newRecord">
<input type="text" class="form-control" ng-model="userDetails.firstname" />
</div>
<div class="col-sm-5" ng-if="newRecord">
<input type="text" class="form-control" ng-model="userDetails.firstName" />
</div>
</div>
<div class="form-group">
<div class="col-xs-12 col-sm-5 col-lg-3 paddnone">
<label class="control-label">Last Name</label>
</div>
<div class="col-sm-5" ng-if="!newRecord">
<input type="text" class="form-control" ng-model="userDetails.lastname" />
</div>
<div class="col-sm-5" ng-if="newRecord">
<input type="text" class="form-control" ng-model="userDetails.lastName" />
</div>
</div>
<div class="form-group">
<div class="col-xs-12 col-sm-5 col-lg-3 paddnone">
<label class="control-label">Email Id</label>
</div>
<div class="col-sm-5" ng-if="!newRecord">
<input type="text" class="form-control" ng-model="userDetails.emailid" />
</div>
<div class="col-sm-5" ng-if="newRecord">
<input type="text" class="form-control" ng-model="userDetails.emailId" />
</div>
</div>
<div class="col-xs-12 col-sm-9 col-lg-7 btnbg">
<button class="btn btn-primary " ng-click="create(userDetails)">
SAVE
</button>
<button class="btn btn-primary ">
Cancel
</button>
</div>
$scope.create = function (userDetails) {
var userData = angular.toJson(userDetails);
return dataFactory.post("/Usercontroller/Save", userData)
.then(function (result) {
alert("save successfully");
});
public class UserDataModel
{
public UserDataModel ();
public Dictionary<string, string> Data { get; set; }
public string FormName { get; set; }
}
public async Task<JsonNetResult> SaveUser(string applicationId, dynamic user)
{
Dictionary<string, string> dict = JsonConvert.DeserializeObject<Dictionary<string, string>>(user);
UserDataModel userDataModel = new UserDataModel ();
//userDataModel .Data = dict;
userDataModel.FormName = "one";
userDataModel = await Post<UserDataModel>(new UserDataModel{ Data = dict });
return new JsonNetResult { Data = userDataModel };
}
In the above code when i click save button data pass to create function in js,then the entire data convert to string and pass to mvc controller , but the dynamic user got object , now how to deserialze and store to webapi.

So you have two options here, 1) You should use razor cshtml instead
of html, it will ease your life. Following link will help you.
http://blog.michaelckennedy.net/2012/01/20/building-asp-net-mvc-forms-with-razor/
If you want to use existing html code:
a) You have to make the name of all fields same as your class object variable, it will automatically parse it to object when server side c# code got the control after form submission.
b) Make the parameter of c# form submission handler function to FormCollection
Following links will help you,
ASP.NET MVC 3 Razor: Passing Data from View to Controller
Deserialization:
var json = JsonConvert.DeserializeObject<dynamic>(sampleJson);
var data = ((JObject)json.data).Children();
Deserialize JSON with dynamic objects

Have your HTML code like this, using Razor Syntax
#using (Html.BeginForm("Upload", "ModelClass")
{
#Html.ValidationSummary(true)
//HTML elements which are based on your model class members.
}
In your controller class method, it would send this form data to the Upload Method.
[HttpPost]
public ActionResult Upload(ModelClass model)
{
//Send model to the model object to Model class for processing
return RedirectToAction("Upload");
}
EDIT: This method I have used in ASP.NET MVC 5 on Visual Studio community edition 2013.

Related

Asp.net MVC core, posting previous ViewModel from PopupView

Maybe I'm looking at this the wrong way, maybe the fact that the browser is showing the view as a pop up doesn't change the fact that for MVC this is just a different View with it's own ViewModel. Since this is a form inside a form in a way, maybe there are better ways to do the following;
The initial view (CreateTimeslot.cshtml) is a form with properties of a workshop to be scheduled. name, description,.., And a speaker multiselect list:
#model MDFrontend.Models.Timeslots.TimeslotManagementViewModel
<div class="form-group">
<label asp-for="StartTime" class="control-label"></label>
<input asp-for="StartTime" type="datetime" class="form-control" value="#startTime" />
<span asp-validation-for="StartTime" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="EndTime" class="control-label"></label>
<input asp-for="EndTime" type="datetime" class="form-control" value="#startTime.Add(Model.WorkshopDuration)" readonly />
<span asp-validation-for="EndTime" class="text-danger"></span>
</div>
<!--------------------------------------------------------------SpeakerBox---------------------------------------------------------------------->
<div class="form-group">
<label asp-for="Speakers" class="control-label"></label>
<select asp-for="SpeakerIDs" id="speakerBox" name="SpeakerIDs[]" asp-items="#Model.Speakers" multiple="multiple">
</select>
<span asp-validation-for="SpeakerIDs" class="text-danger"></span> <!--This is not showing, asp-validation-summary does-->
</div>
<button onclick="showFormInPopup('#Url.Action("CreateSpeaker","SpeakerAdmin",Model,Context.Request.Scheme)',
'New Speaker')" type="button" id="btnAddSpeaker" class="btn btn-primary"> #Localizer["Add_Speaker"]
</button>
I'm passing the TimeslotManagementViewModel in the Url.Action method, which I'm mapping to the CreateSpeakerViewModel
public class CreateSpeakerViewModel
{
public string Firstname { get; set; }
public string Lastname { get; set; }
public TimeslotManagementViewModel oldModel { get; set; }
}
This view is shown as a popup:
<!-------------------------------------------Hidden Add Speaker Popup--------------------------------------------------->
<div class="modal" tabindex="-1" role="dialog" id="form-modal">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title"></h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
</div>
</div>
</div>
</div>
<!-------------------------------------------Hidden Add Speaker Popup--------------------------------------------------->
The body of this CreateSpeaker View:
#model MDFrontend.Models.Speakers.CreateSpeakerViewModel
<form asp-action="CreateSpeaker" asp-controller="SpeakerAdmin">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Firstname" class="control-label"></label>
<input asp-for="Firstname" class="form-control" />
<span asp-validation-for="Firstname" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Lastname" class="control-label"></label>
<input asp-for="Lastname" class="form-control" />
<span asp-validation-for="Lastname" class="text-danger"></span>
</div>
<div class="form-group" >
<input type="submit" value="Save" asp-action="CreateSpeaker" asp-controller="SpeakerAdmin"
formmethod="post" class="btn btn-primary" />
</div>
</form>
The CreateSpeaker Post method is receiving this simple form, adding them to the db, redirecting to the initial CreateTimeslot view with an updated multiselect.
[HttpPost]
[Authorize(Roles = RoleConstant.Admin)]
public async Task<IActionResult> CreateSpeaker(CreateSpeakerViewModel vm,
TimeslotManagementViewModel model)
{
//The idea would be to have TimeslotManagementViewModel model posted back with the set values by the user before "AddSpeaker" was clicked.
}
However with this solution the previous set inputs are lost to the user.
So atm I'm thinking either to use map every property of the TimeslotManagementViewModel to the CreateSpeakerViewModel to pass them between controllers or maybe an Ajax call could work or drop the popup all togheter. Or better yet someone here knows a better option?
Many thanks!
After some trail and error realized the best, maybe only solution comes by using some simple Javascript.
function SaveSpeaker(e) {
var firstname = $('#txtFirstname').val();
var lastname = $('#txtLastname').val();
$.ajax({
url: '/SpeakerAdmin/CreateSpeaker',
dataType: 'Json',
type: "POST",
data: { firstname: firstname, lastname: lastname },
success: function (data, status, jqXHR) {
console.log('success');
if (data.valFirstname == false) {
$('#valFirstname').text('Firstname not complete');
}
if (data.valLastname == false) {
$('#valLastname').val('Lastname not complete')
}
if (data.valSpeaker == true) {
$('#form-modal').modal('hide');
$('#valSpeaker').text('Speaker added');
$('#speakerBox').append(new Option(firstname + " " + lastname, data.speakerID))
}
},
error: function (jqXHR, status, err) {
},
complete: function (jqXHR, status) {
}
});
So instead of posting the form just using an Ajax call to post to the controller and return Json to populate the new select option.

Why do I receive null values in my controller when I submit a form from a view with multiple forms? With ASP.NET Core 5 MVC

I am developing a web application using ASP.NET Core 5 MVC, in which I seek to make multiple submissions of POST type forms to my controller from a view that receives an IEnumerable (from a model called Result) with which I am filling in dynamically the values of the inputs of each form.
However, when I send one of those forms from the view through the controller, in the controller I only receive an object from the model with all the null or empty values, which tells me that it seems that this data was never sent through the form to my controller.
Is there a better way to accomplish this or how do I pass these values from multiple forms to my controller? In advance an apology if what I am doing is already totally wrong, I have been learning ASP.NET Core MVC for a few days.
CONSIDERATIONS
What I seek to achieve is that the user can enter multiple values that belong to the same model in the same view, since each form although it is the same seeks to update a different record or column in the same model or table, so when the submit of the form is sent to the Controller the view does not change, and only the records in the database are updated with each submit in the view. If there is a better way or correct way to do this, I am willing to change the logic, because as I mentioned, I have been using the Framework for little.
Explained the problem and my goal, I will explain in greater detail the flow and code mentioned:
From the Mechanical method of my controller, I return a list of Objects to their corresponding View, which are brought by a DataBaseContext:
// CONTROLLER() that passes an enumerable list of Objects to View Mechanical.cshtml
public IActionResult Mechanical()
{
IEnumerable<Result> objList = _db.Results;
return View(objList);
}
In the Mechanical() view, I get this list of objects and iterate over it through a forEach() loop, where for each object I create a form that directs to the same controller method called Update(), in which I get the values of the object in null and empty (that being my problem):
// VIEW
#model IEnumerable<FatForm.Models.Result>
#if (Model.Count() > 0)
{
#foreach(var result in Model)
{
<form method="post" asp-action="Update">
<input asp-for="#result.Id" hidden />
<input asp-for="#result.Type" hidden />
<input asp-for="#result.FatId" hidden />
<div class="border p-3">
<div class="form-group row">
<h2 class="text-black-50 pl-3">Edit Result</h2>
</div>
<div class="row">
<div class="col-12">
<div class="form-group row">
<div class="col-3">
<label asp-for="#result.Section"></label>
</div>
<div class="col-3">
<label asp-for="#result.Procedure"></label>
</div>
<div class="col-3">
<label asp-for="#result.ResultDescription"></label>
</div>
<div class="col-3">
<label asp-for="#result.Passed"></label>
</div>
</div>
<div class="form-group row">
<div class="col-3">
<input asp-for="#result.Section" class="form-control" />
</div>
<div class="col-3">
<input asp-for="#result.Procedure" class="form-control" />
</div>
<div class="col-3">
<input asp-for="#result.ResultDescription" class="form-control" />
<span asp-validation-for="#result.ResultDescription" class="text-danger"></span>
</div>
<div class="col-3">
<input asp-for="#result.Passed" class="form-control" />
<span asp-validation-for="#result.Passed" class="text-danger"></span>
</div>
</div>
<div class="form-group row">
<div class="col-8 offset-2 row">
<div class="col">
<input type="submit" class="btn btn-info w-75" value="Save" />
</div>
</div>
</div>
</div>
</div>
</div>
</form>
}
}
else
{
<p>No results created yet</p>
}
#section Scripts{
#{
<partial name="_ValidationScriptsPartial" />
}
}
I'm supposed to be looking to send the form values to the following Update() controller method, in which I get all the object values to null:
// POST Update
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Update(Result obj)
{
if (ModelState.IsValid)
{
_db.Results.Update(obj);
_db.SaveChanges();
//return RedirectToAction("Index");
}
return View(obj);
}
As I explained at the beginning, I hope can help me by indicating what I am doing wrong or in what way I should do it. Thanks in advance for your help.
Model binding looks through the sources for the name pattern prefix.property_name. If nothing is found, it looks for just property_name without the prefix.In your code,the asp-for tag helper will generate the name like:result.propertyName.It could not match with backend model. You need use [Bind(Prefix ="result")] to specify the prefix:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Update([Bind(Prefix ="result")]Result obj)
{
//do your stuff...
}
As for receive IEnumerable parameter in action, firstly you need change your razor view to move the form outside the foreach loop, then you need change the asp-for tag helper tattribute to #Model.ToList()[index].PropertyName:
#model IEnumerable<Result>
#if (Model.Count() > 0)
{
<form method="post" asp-action="Update">
#for (int i = 0; i < Model.Count(); i++)
{
<input asp-for="#Model.ToList()[i].Id" hidden />
<input asp-for="#Model.ToList()[i].Type" hidden />
<input asp-for="#Model.ToList()[i].FatId" hidden />
<div class="border p-3">
<div class="form-group row">
<h2 class="text-black-50 pl-3">Edit Result</h2>
</div>
<div class="row">
<div class="col-12">
<div class="form-group row">
<div class="col-3">
<label asp-for="#Model.ToList()[i].Section"></label>
</div>
<div class="col-3">
<label asp-for="#Model.ToList()[i].Procedure"></label>
</div>
<div class="col-3">
<label asp-for="#Model.ToList()[i].ResultDescription"></label>
</div>
<div class="col-3">
<label asp-for="#Model.ToList()[i].Passed"></label>
</div>
</div>
<div class="form-group row">
<div class="col-3">
<input asp-for="#Model.ToList()[i].Section" class="form-control" />
</div>
<div class="col-3">
<input asp-for="#Model.ToList()[i].Procedure" class="form-control" />
</div>
<div class="col-3">
<input asp-for="#Model.ToList()[i].ResultDescription" class="form-control" />
<span asp-validation-for="#Model.ToList()[i].ResultDescription" class="text-danger"></span>
</div>
<div class="col-3">
<input asp-for="#Model.ToList()[i].Passed" class="form-control" />
<span asp-validation-for="#Model.ToList()[i].Passed" class="text-danger"></span>
</div>
</div>
</div>
</div>
</div>
}
<div class="form-group row">
<div class="col-8 offset-2 row">
<div class="col">
<input type="submit" class="btn btn-info w-75" value="Save" />
</div>
</div>
</div>
</form>
}
else
{
<p>No results created yet</p>
}
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Update(IEnumerable<Result> obj)
{
return View("Mechanical", obj);
}
Result:
Here you need to add FromBody attribute in your action method parameter.
public IActionResult Update([FromBody]Result obj)
{
.....
}

ASP.Net Core MVC how to post unknown number of fields against strongly-typed model

Totally stumped on this. I have a page where users can click an "Add Step" button, and some javascript appends rows with additional inputs from a <template> tag to a form. When debugging from the controller, the values are empty.
I looked at the following posts, but neither answer seem to help here (not sure if it's because I'm using .Net core - probably not):
Get post data with unknown number of variables in ASP MVC
Passing data from Form with variable number of inputs - MVC 5
Model (Procedure.cs)
public class Procedure
{
public int Id { get; set; }
public string Name { get; set; }
public string Type { get; set; }
public int MinNumber { get; set; }
public int MaxNumber { get; set; }
}
Controller (ProceduresController.cs)
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([FromForm]List<Procedure> model)
{
if (ModelState.IsValid)
{
foreach(var field in model)
{
// Database things will happpen eventually, but at this point the Count = 0
}
}
return View(model);
}
Currently the Create action signature includes the [FromForm] attribute, but I have no idea if that's required here. I also tried List<Procedure> model.
And the View (Create.cshtml)
I've stripped out a lot of the UI and javascript to make things easier to read
#model List<Procedure>
/* also tried #model Procedure */
#{
ViewData["Title"] = "Create Procedure";
ViewData["Sidebar"] = "App";
}
<form asp-action="Create" enctype="multipart/form-data">
<div asp-validation-summary="All" class="field-validation-summary"></div>
<div class="builder">
<div class="field-row">
<div class="field-group">
<label class="field-label">Instruction Name</label>
<input type="text" name="Name" class="field type:text" placeholder="Enter an instruction name" />
</div>
<div class="field-group">
<label for="Type" class="field-label">Instruction Type</label>
<select id="Type" name="Type" class="field type:select stretch">
/* removing for brevity */
</select>
</div>
</div>
<div class="field-row">
<div class="field-group">
<label class="field-label">Minimum Number</label>
<input type="number" name="MinNumber" class="field type:number" />
</div>
<div class="field-group">
<label class="field-label">Maximum Number</label>
<input type="number" name="MaxNumber" class="field type:number" />
</div>
</div>
</div>
<div class="field-row">
<div class="field-group">
<div class="add-step">Add Step</div>
</div>
</div>
<div class="field-row">
<div class="field-group">
<input type="submit" value="Submit Procedures" class="button button-submit" />
</div>
</div>
</form>
<template id="template">
<details class="accordion" open>
<summary>Procedure Step</summary>
<div class="details-content">
<div class="field-row">
<div class="field-group">
<label class="field-label">Instruction Name</label>
<input type="text" name="Name" class="field type:text" placeholder="Enter an instruction name" />
</div>
<div class="field-group">
<label for="Type" class="field-label">Instruction Type</label>
<select id="Type" name="Type" class="field type:select stretch">
/* removing for brevity */
</select>
</div>
</div>
<div class="field-row">
<div class="field-group">
<label class="field-label">Minimum Number</label>
<input type="number" name="MinNumber" class="field type:number" />
</div>
<div class="field-group">
<label class="field-label">Maximum Number</label>
<input type="number" name="MaxNumber" class="field type:number" />
</div>
</div>
</div>
</details>
</template>
#section Scripts {
#{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); }
<script>
const modal = new Modal();
function getParent(element, selector) {
for (; element && element !== document; element = element.parentNode) {
if (element.classList.contains(selector)) {
return element;
}
}
return null;
}
this.Builder = function () {
this.template = document.querySelector('#template');
this.builder = document.querySelector('.builder');
this.addStep = document.querySelector('.add-step');
this.clone = null;
this.counter = 0;
this.addStep.addEventListener('click', this.add.bind(this));
};
Builder.prototype = {
add: function () {
this.counter++;
this.clone = document.importNode(this.template.content, true);
this.builder.appendChild(this.clone);
// i'm doing things here to set the new field attribute values - removed for brevity
}
};
let builder = new Builder();
builder.add();
</script>
}
In the javascript do I need to set the new field name values a specific way? Should they look like <input type="text" name="Name[index]"> or <input type="text" name="#Model.Procedure[index].Name">?
I tried both but the Count is still 0 when posting back. I've pretty much hit a wall, so I appreciate any and all help.
.NET requires a little more effort for model binding on complex types. Naming of elements is important.
<input name="model[index].Name" />
<input name="model[index].Type" />
<input name="model[index].MinNumber" />
<input name="model[index].MaxNumber" />
The naming convention to bind is: Name of the parameter in your controller (model), index, property name. This will properly pass all objects to your list.
The same is true if you are passing objects to a list inside your model.
For example
public class Example {
public int Id { get; set; }
public List<Procedure> Procedures { get; set; }
}
in this case we just need to tell .NET what property you are mapping too.
<input name="model.Procedures[index].Name" />
In some cases you may need to also add a hidden field for the index: https://www.red-gate.com/simple-talk/dotnet/asp-net/model-binding-asp-net-core/

How to post Form data and File in the same submit with Angular 4 in .NET Core

I am trying to add in the Suppliers table a new entry. This table also has another one linked to it in which are stored the contracts with each supplier.
The desired functionality is to submit in the same form both the data for the new Supplier and the contract, but I can't make it work.
I am able to add a new supplier and after the contract by uploading the file separately in another form, but not in the same submit action.
How can I do that?
My form looks like this:
<form class="form-material m-t-40" enctype="multipart/form-data">
<div class="form-group has-warning">
<h4 class="entity-info"><label for="denumire" class="label-has-danger"> Denumire furnizor </label></h4>
<input type="text" id="denumire" name="denumire" class="form-control" placeholder="Denumire" [(ngModel)]="furnizor.denumire" #denumire="ngModel">
</div>
<div class="form-group has-warning">
<h4 class="entity-info"><label for="cod" class="label-has-danger"> Cod intern furnizor </label></h4>
<input type="text" id="cod" name="cod" class="form-control" placeholder="Cod intern" [(ngModel)]="furnizor.cod" #cod="ngModel">
</div>
<div class="form-group has-warning">
<h4 class="entity-info"><label for="cod" class="label-has-success"> Cod de inregistrare fiscala furnizor </label></h4>
<input type="text" id="codIntern" name="codIntern" class="form-control" placeholder="Cod" [(ngModel)]="furnizor.codIntern" #codIntern="ngModel">
</div>
<div class="form-group has-warning">
<h4 class="entity-info"><label for="adresa" class="label-has-success"> Adresa </label></h4>
<input type="text" id="adresa" name="adresa" class="form-control" placeholder="Adresa" [(ngModel)]="furnizor.adresa">
</div>
<div class="form-group has-warning">
<h4 class="entity-info"><label for="persoanaContact" class="label-has-success"> Persoana Contact </label></h4>
<input type="text" id="persoanaContact" name="persoanaContact" class="form-control" placeholder="Persoana Contact" [(ngModel)]="furnizor.persoanaContact" #reprezentant="ngModel">
</div>
<div class="form-group has-warning">
<h4 class="entity-info"><label for="telefon" class="label-has-success"> Telefon </label></h4>
<input type="tel" id="telefon" name="telefon" class="form-control" placeholder="Telefon" [(ngModel)]="furnizor.telefon" #telefon="ngModel">
</div>
<div class="form-group has-warning">
<h4 class="entity-info"><label for="dataIncepereContract" class="label-has-success"> Data incepere contract </label></h4>
<input type="date" class="form-control m-b-40" placeholder="2017-06-04" id="dataIncepereContract" name="dataIncepereContract" [(ngModel)]="furnizor.dataIncepereContract" #dataIncepereContract="ngModel">
</div>
<div class="form-group has-warning">
<h4 class="entity-info"><label for="dataExpirareContract" class="label-has-success"> Data expirare contract </label></h4>
<input type="date" class="form-control m-b-40" placeholder="2017-06-04" id="dataExpirareContract" name="dataExpirareContract" [(ngModel)]="furnizor.dataExpirareContract" #dataExpirareContract="ngModel">
</div>
<input type="file" #fileInput>
<button type="button" class="btn btn-md btn-add animated flipInX flipInY lightSpeedIn slideInUp" (click)="submit()">
<i class="fa fa-floppy-o"></i> Save
</button>
</form>
I have tried a lot of options and combinations for the file and the other form fields, but none work.
My ts file reads the file input like this:
...
#ViewChild('fileInput') fileInput: ElementRef;
...
submit() {
var nativeElement: HTMLInputElement = this.fileInput.nativeElement;
if (nativeElement.files) this.file = nativeElement.files[0];
this.furnizorService.create(this.furnizor, this.file).subscribe(() => {});
}
My service:
create(furnizor: any, fileToUpload: any) {
let input = new FormData();
input.append("file", fileToUpload);
furnizor.file = input;
return this.http.post('/api/furnizor', furnizor).map(res => res.json());
}
And in my C# Controller I tried:
[HttpPost("/api/furnizor")]
public async Task<IActionResult> CreateFurnizor([FromBody]FurnizorResource furnizorResource)
{
...
}
Where I added a new property
public IFormFile file { get; set; }
in FurnizorResource, but if I do this, furnizorResource is not mapped and is null.
I also tried sending them separately (just to try):
[HttpPost("/api/furnizor")]
public async Task<IActionResult> CreateFurnizor([FromBody]FurnizorResource furnizorResource, IFormFile file)
{
...
}
(Which obviously doesn't work since in the Angular service I can't send 2 "body" elements). With this method the furnizorResource data is correct, but of course file is null...
How can I post Json data and a file at the same time in Angular 4.3.6 and ASP.NET Core 2?
Have you tried something like that? That's teh way I use it in my app and it works.
var formData = new FormData()
for (var key in model)
formData.append(key, furnizor[key])
formData.append('file', fileToUpload)
let headers = new Headers({ 'Content-Type': 'multipart/form-data' })
let options = new RequestOptions({ headers: headers })
return this.authHttp.post('/api/furnizor', formData, options).map(res => res.json())
I understand that your both, Angular and c# must be the property fornitureResources that it will be a array of FornitureResource
interface Forniture
{
cod:number;
...
fornitureResources :IFromFile[]
}
So, e.g.
let myforniture={
cod:1,
...
fornitureResources:[
{ file:"file1"},
{ file:"file2"}
]
}
If you send "myforniture" using this.http.post('/api/furnizor', myforniture) you must be get a "Forniture" in your API

How I can use html tags for input and submit in asp.net mvc 5 without Html.BeginForm?

net mvc 5 application and for this I use bootstrap because it looks fine.
I don't want to use for an input and a searchbutton the
#using (Html.BeginForm("...
Can I control the html tags without this from my controller. For example here is my index.cshtml
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="container">
<div class="row">
<h2>Suche</h2>
<div id="custom-search-input">
<div class="input-group col-md-12">
<input type="text" class=" search-query form-control" placeholder="Search" />
<span class="input-group-btn">
<button class="btn btn-danger" type="button">
<span class=" glyphicon glyphicon-search"></span>
</button>
</span>
</div>
</div>
</div>
</div>
I want if I click on the Searchbutton I get a message with the text from the inputfield.
Here is the Controller:
public ActionResult Search(string value)
{
//listofUsers is a arraylist of all users that found^^
return View(listofUsers);
}
How I can do this? :)
Add a div to show the result:
<div id="custom-search-input">
<div class="input-group col-md-12">
<input type="text" class=" search-query form-control" placeholder="Search" />
<span class="input-group-btn">
<button class="btn btn-danger" type="button">
<span class=" glyphicon glyphicon-search"></span>
</button>
</span>
</div>
</div>
<div class="custom-search-result"></div>
Then in a script tag or a linked js file:
$(document).ready(function () {
$('.custom-search-input').each(function () {
var sinput = $(this);
var svalue = sinput.find('input');
var sresult = sinput.next('.custom-search-result');
sinput.find('button').click(function () {
$.ajax({
url: '/ControllerName/Search?value=' + svalue.val(),
type: 'GET'
}).done(function (result) {
sresult.html(result);
});
});
});
});
This is a basic example with no error handling.
First I highly recommend reading Philip Walton (Google) - Decoupling your HTML, CSS and Javascript, it's extremely good.
Here how I would use MVC to it's full potential.
Model:
// Extensible Programming
// Using a string limits additional features
// Future proofing via a class that takes 2 minutes to create
public class GlobalSearch
{
public string SearchTerms { get; set; }
}
View:
#Model GlobalSearch
<div class="container">
<div class="row">
<h2>Suche</h2>
<div id="custom-search-input">
#using (Html.BeginForm("Search"))
{
<div class="input-group col-md-12">
#Html.TextBoxFor(m => m.SearchTerms, new {
#class="search-query form-control",
placeholder="Search" })
<span class="input-group-btn">
<button class="btn btn-danger" type="button">
<span class=" glyphicon glyphicon-search js-form-submit"></span>
</button>
</span>
</div>
}
</div>
</div>
</div>
Controller:
// Strongly Typed Class is Returned
public ActionResult Search(GlobalSearch search)
{
return View(listofUsers);
}
The following script will require this fantastic script called form2js which correctly converts any strongly-typed forms generated by MVC (arrays, lists etc) into Json that will be ModelBinded correctly.
$(document).ready(function() {
('.js-form-submit').on('click', function() {
var $form = $(this).closest('form');
var json = form2js($form);
var ajaxSettings = {
url: $form.attr('action'),
type: $form.attr('method'),
data: json,
contentType: "application/json",
}
$.ajax(ajaxSettings)
.done()
.always()
.fail();
});
});
Of course this could be easily abstract into it's own javascript class/namespace that returns the promise and reusable on any form that simply has a button with the class js-form-submit instead of continually rewriting $.ajax over and over again each time for different forms.

Categories