ASP.NET MVC4 Web API definește metoda post pentru a salva clientul. Clientul este trecut în format json în cerere POST corpului. Client parametru în metoda post conține valori null pentru proprietăți.
Cum de a repara acest lucru, astfel încât postat de date va trecut în calitate de client obiect ?
Dacă este posibil Content-Type: application/x-www-form-urlencoded ar trebui folosite deoarece nu știu cum să-l schimbe în javascript metodă care posturile de formă.
Controller:
public class CustomersController : ApiController {
public object Post([FromBody] Customer customer)
{
return Request.CreateResponse(HttpStatusCode.OK,
new
{
customer = customer
});
}
}
}
public class Customer
{
public string company_name { get; set; }
public string contact_name { get; set; }
}
Cerere:
POST http://localhost:52216/api/customers HTTP/1.1
Accept: application/json, text/javascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
{"contact_name":"sdfsd","company_name":"ssssd"}
EDIT : 31/10/2017
Același cod/abordare va lucra pentru Asp.Net Core 2.0 la fel de bine. Diferența majoră este, În asp.net de bază, ambele api web controlere și Mvc controlere sunt îmbinate împreună la un singur controler model. Deci tipul de retur poate fi IActionResult
sau unul de l's de implementare (Ex :OkObjectResult
)
Utilizarea
contentType:"application/json"
Ai nevoie de a utiliza JSON.stringify
metoda de a se converti la JSON string atunci când îl trimite,
Și modelul de liant va lega de date json pentru clasa object.
Codul de mai jos va funcționa bine (testat)
$(function () {
var customer = {contact_name :"Scott",company_name:"HP"};
$.ajax({
type: "POST",
data :JSON.stringify(customer),
url: "api/Customer",
contentType: "application/json"
});
});
Rezultat
`contentType proprietate spune serverului ca suntem trimiterea de date în format JSON. De când am trimis-o structura de date JSON,model obligatoriu se va întâmpla în mod corespunzător.
Dacă vă controlați cerere ajax's cap, puteți vedea că "Content-Type" valoarea este setată ca application/json
.
Dacă nu specificați contentType în mod explicit, Se va folosi implicit tipul de conținut care este application/x-www-form-urlencoded;
Editare pe Nov 2015 la adresa de alte posibile probleme ridicate în comentarii
Las's spune că ai un complex de vedere model de clasa ca web api metodă de acțiune parametru astfel de prognoze
public class CreateUserViewModel
{
public int Id {set;get;}
public string Name {set;get;}
public List<TagViewModel> Tags {set;get;}
}
public class TagViewModel
{
public int Id {set;get;}
public string Code {set;get;}
}
și web api punctul final este ca
public class ProductController : Controller
{
[HttpPost]
public CreateUserViewModel Save([FromBody] CreateUserViewModel m)
{
// I am just returning the posted model as it is.
// You may do other stuff and return different response.
// Ex : missileService.LaunchMissile(m);
return m;
}
}
La momentul de acest scris, ASP.NET MVC 6 este cea mai recentă versiune stabilă și în MVC6, Ambele api Web controlere și MVC controlere sunt moștenind de la Microsoft.AspNet.Mvc.Controller` clasa de baza.
Pentru a trimite date la metoda de partea de client, codul de mai jos ar trebui să funcționeze bine
//Build an object which matches the structure of our view model class
var model = {
Name: "Shyju",
Id: 123,
Tags: [{ Id: 12, Code: "C" }, { Id: 33, Code: "Swift" }]
};
$.ajax({
type: "POST",
data: JSON.stringify(model),
url: "../product/save",
contentType: "application/json"
}).done(function(res) {
console.log('res', res);
// Do something with the result :)
});
Dacă nu decora web api parametru metodă cu [FromBody]
atribut
[HttpPost]
public CreateUserViewModel Save(CreateUserViewModel m)
{
return m;
}
Și trimite modelul(raw obiect javascript, nu în format JSON), fără a se preciza contentType valoarea proprietății
$.ajax({
type: "POST",
data: model,
url: "../product/save"
}).done(function (res) {
console.log('res', res);
});
Obligatoriu modelul va lucra pentru apartament proprietăți pe model, nu proprietățile în cazul în care tipul este complex/un alt tip. În cazul nostru, " Id " și "Nume" proprietăți va fi corect legat de parametrul "m", Dar "Tag-uri" proprietatea va fi o listă goală.
Aceeași problemă va apărea dacă utilizați versiunea scurtă, $.post
care va folosi implicit Content-Type la trimiterea cererii.
$.post("../product/save", model, function (res) {
//res contains the markup returned by the partial view
console.log('res', res);
});
Lucrez cu POSTA în webapi poate fi dificil! Ar dori pentru a adăuga la deja răspunsul corect..
Se va concentra în mod special pe POST ca de-a face cu IA este banal. Eu nu't cred că mulți ar fi în căutarea în jurul pentru a rezolva o problemă cu cu webapis. Oricum..
Dacă întrebarea dvs. este - În MVC Web Api, cum să - Utilizare personalizate metodă de acțiune și alte nume decât cele generice HTTP verbe? - Efectuați mai multe posturi? - Posta mai multe tipuri simple? - Post de tipuri de complexe prin jQuery?
Atunci următoarele soluții pot ajuta:
În primul rând, pentru a utiliza Personalizat Metode de Acțiune în API Web, adăugați un api web traseu ca:
public static void Register(HttpConfiguration config)
{
config.Routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}");
}
Și atunci s-ar putea crea metode de acțiune, cum ar fi:
[HttpPost]
public string TestMethod([FromBody]string value)
{
return "Hello from http post web api controller: " + value;
}
Acum, focul următoarele jQuery de la browser-ul dvs. consola
$.ajax({
type: 'POST',
url: 'http://localhost:33649/api/TestApi/TestMethod',
data: {'':'hello'},
contentType: 'application/x-www-form-urlencoded',
dataType: 'json',
success: function(data){ console.log(data) }
});
Al doilea, pentru a a efectua mai multe posturi, este simplu, de a crea mai multe metode de acțiune și decora cu [HttpPost] attrib. Utilizați [ActionName("MyAction")] pentru a atribui nume personalizate, etc. Va veni la jQuery în cel de-al patrulea punct de mai jos
Al treilea rând, mai Întâi de toate, de a posta mai multe SIMPLU tipuri într-o singură acțiune nu este posibilă. Mai mult decât atât, există o format special pentru a posta chiar un *singur tip simplu** (în afară de trecerea parametru în șirul de interogare sau de ODIHNĂ stil). Acesta a fost punctul care m-a dat cu capul cu Restul Clienților (ca Lăutar și Chrome's Avansată RESTUL client extensie) și de vânătoare în jurul valorii de web pentru aproape 5 ore, atunci când în cele din urmă, următoarele URL-ul s-a dovedit a fi de ajutor. Va citez conținutul relevant pentru link-ul s-ar putea transforma mort!
Content-Type: application/x-www-form-urlencoded
in the request header and add a = before the JSON statement:
={"Name":"Turbo Tina","Email":"[email protected]"}
PS: a Observat ciudat sintaxa?
http://forums.asp.net/t/1883467.aspx?The+primit+valoare+e+null+când+I+incearca+sa+Post+de+mi+Web+Api
Oricum, lasă-ne să trecem peste povestea asta. Mutarea pe:
În al patrulea rând, postarea de tipuri complexe prin jQuery, desigur, $.ajax() va veni prompt în rolul:
Sa ne spui acțiunea metodă acceptă un obiect Persoană care are o identitate și un nume. Deci, din javascript:
var person = { PersonId:1, Name:"James" }
$.ajax({
type: 'POST',
url: 'http://mydomain/api/TestApi/TestMethod',
data: JSON.stringify(person),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function(data){ console.log(data) }
});
Iar acțiunea va arata asa:
[HttpPost]
public string TestMethod(Person person)
{
return "Hello from http post web api controller: " + person.Name;
}
Toate cele de mai sus, a lucrat pentru mine!! Noroc!
Am'am jucat cu acest lucru și a descoperit-o destul de ciudat rezultat. Spune că au proprietăți publice de pe clasa ta în C# astfel:
public class Customer
{
public string contact_name;
public string company_name;
}
apoi, trebuie să facă JSON.stringify truc cum a sugerat de către Shyju și sună astfel:
var customer = {contact_name :"Scott",company_name:"HP"};
$.ajax({
type: "POST",
data :JSON.stringify(customer),
url: "api/Customer",
contentType: "application/json"
});
Cu toate acestea, dacă definiți getters și setteri pe clasa ta astfel:
public class Customer
{
public string contact_name { get; set; }
public string company_name { get; set; }
}
apoi, puteți apela mult mai simplu:
$.ajax({
type: "POST",
data :customer,
url: "api/Customer"
});
Acesta utilizează antetul HTTP:
Content-Type:application/x-www-form-urlencoded
Am'm nu este destul de sigur ce's-a întâmplat, dar se pare ca un bug (caracteristică?) în cadru. Probabil obligatorii diferite metode de asteptare diferite "adaptoare", și în timp ce adaptorul pentru application/json funcționează cu proprietăți publice, unul pentru forma de date codate nu't.
Nu am nici o idee care ar putea fi considerate cele mai bune practici, deși.
Folosi JSON.stringify() pentru a obține șirul de caractere în format JSON, să se asigure că în timp ce face apel AJAX trece menționate mai jos atribute:
Mai jos este codul jquery ajax pentru a face apel la post asp.net api web:
var product =
JSON.stringify({
productGroup: "Fablet",
productId: 1,
productName: "Lumia 1525 64 GB",
sellingPrice: 700
});
$.ajax({
URL: 'http://localhost/api/Products',
type: 'POST',
contentType: 'application/json',
data: product,
success: function (data, status, xhr) {
alert('Success!');
},
error: function (xhr, status, error) {
alert('Update Error occurred - ' + error);
}
});
Asigurați-vă că WebAPI servicii se așteaptă un puternic tastat obiect cu o structura care corespunde JSON că sunteți trece. Și asigurați-vă că stringify JSON care le Postați.
Aici este meu JavaScript (folosind AngluarJS):
$scope.updateUserActivity = function (_objuserActivity) {
$http
({
method: 'post',
url: 'your url here',
headers: { 'Content-Type': 'application/json'},
data: JSON.stringify(_objuserActivity)
})
.then(function (response)
{
alert("success");
})
.catch(function (response)
{
alert("failure");
})
.finally(function ()
{
});
Și aici este meu WebAPI Controller:
[HttpPost]
[AcceptVerbs("POST")]
public string POSTMe([FromBody]Models.UserActivity _activity)
{
return "hello";
}
Următorul cod pentru a reveni date în format json ,în loc de xml -API Web 2 :-
Pune următoarea linie în fișierul Global.asax
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
@model MVCClient.Models.ProductDetails
@{
ViewBag.Title = "ProductDetails";
}
<script src="~/Scripts/jquery-1.8.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$("#Save").click(function () {
var ProductDetails = new Object();
ProductDetails.ProductName = $("#txt_productName").val();
ProductDetails.ProductDetail = $("#txt_desc").val();
ProductDetails.Price= $("#txt_price").val();
$.ajax({
url: "http://localhost:24481/api/Product/addProduct",
type: "Post",
dataType:'JSON',
data:ProductDetails,
success: function (data) {
alert('Updated Successfully');
//window.location.href = "../Index";
},
error: function (msg) { alert(msg); }
});
});
});
</script>
<h2>ProductDetails</h2>
<form id="form1" method="post">
<fieldset>
<legend>ProductDetails</legend>
<div class="editor-label">
@Html.LabelFor(model => model.ProductName)
</div>
<div class="editor-field">
<input id="txt_productName" type="text" name="fname">
@Html.ValidationMessageFor(model => model.ProductName)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.ProductDetail)
</div>
<div class="editor-field">
<input id="txt_desc" type="text" name="fname">
@Html.ValidationMessageFor(model => model.ProductDetail)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Price)
</div>
<div class="editor-field">
<input id="txt_price" type="text" name="fname">
@Html.ValidationMessageFor(model => model.Price)
</div>
<p>
<input id="Save" type="button" value="Create" />
</p>
</fieldset>
</form>
<div>
@Html.ActionLink("Back to List", "Index")
</div>
</form>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
Microsoft a dat un exemplu bun de a face acest lucru:
https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/sending-html-form-data-part-1
Prima valida cererea
if (ModelState.IsValid)
și decât să folosesc serializat de date.
Content = new StringContent(update.Status)
Aici 'Stare' este un câmp de tip complex. Serializarea se face prin .NET, nu este nevoie să vă faceți griji despre asta.
1)În partea de client puteți trimite http.cerere post în șir ca mai jos
var IndexInfo = JSON.stringify(this.scope.IndexTree);
this.$http.post('../../../api/EvaluationProcess/InsertEvaluationProcessInputType', "'" + IndexInfo + "'" ).then((response: any) => {}
2)Apoi, în dvs. de web api controller puteți deserialize
public ApiResponce InsertEvaluationProcessInputType([FromBody]string IndexInfo)
{
var des = (ApiReceivedListOfObjects<TempDistributedIndex>)Newtonsoft.Json.JsonConvert.DeserializeObject(DecryptedProcessInfo, typeof(ApiReceivedListOfObjects<TempDistributedIndex>));}
3)ApiReceivedListOfObjects clasă ar trebui să fie ca mai jos
public class ApiReceivedListOfObjects<T>
{
public List<T> element { get; set; }
}
4)asigurați-vă că serializat string (IndexInfo aici) devine ca structura de mai jos înainte de a JsonConvert.DeserializeObject comanda de la pasul 2
var resp = @"
{
""element"": [
{
""A"": ""A Jones"",
""B"": ""500015763""
},
{
""A"": ""B Smith"",
""B"": ""504986213""
},
{
""A"": ""C Brown"",
""B"": ""509034361""
}
]
}";