javascript - Yritän saada JQuery Postin kommunikoimaan WCF:n kanssa, mutta JSON-dataa ei hyväksytä


Käytän seuraavaa JQuery\JavaScript-koodia kommunikoidakseni WCF 4 REST -palvelun kanssa.

<script>
var serviceUrl = "http://services.xiine.com/Xiine/Live/AccountService/rest/json/Login";
var userInfo = {
    "IsNotEncrypted":true,
    "Password":null,
    "UserName":null
};

var loginSuccess = function(data, textStatus, jqXHR){
console.log("yay");
};
var loginError = function(){
console.log("oh no");
};

$.post(serviceUrl , userInfo, loginSuccess);
$.post(serviceUrl , loginSuccess);

</script>

Yritän selvittää, miksi palvelu palauttaa oikein väärän arvon, kun en lähetä käyttäjätietoja:

$.post(serviceUrl , loginSuccess);

Toisin kuin silloin, kun lähetän käyttäjätietoja, jolloin se antaa POST 400 (Bad Request) -virheen.

$.post(serviceUrl , userInfo, loginSuccess);

Olen varma, että se liittyy siihen, miten JSON-objekti userInfo rakennetaan tai tulkitaan, ja voin lähettää Fiddler 2- tai WireShark-tallenteita, jos se auttaa. Kerro vain...

Minulla ei oikeastaan ole pääsyä muuttaa WCF-palvelun puolta, joten toivottavasti voin tehdä jotain puoleltani saadakseni tämän toimimaan.

Kiitos!

Muokkaa

Sain vähän lisätietoja... Ilmeisesti ongelma on, että palvelin vastaa seuraavalla virheellä:

Palvelimella ilmeni virhe pyynnön käsittelyssä. Poikkeusviesti on 'Saapuvalla viestillä on odottamaton viestimuoto 'Raw'. Toiminnon odotetut viestimuodot ovat 'Xml', 'Json'. Tämä voi johtua siitä, ettei WebContentTypeMapperiä ole määritetty liitännässä. Katso tarkempia tietoja WebContentTypeMapperin dokumentaatiosta.' Katso palvelimen lokit tarkempia tietoja varten. Poikkeuksen pinon jäljitys on:

järjestelmässä System.ServiceModel.Dispatcher.DemultiplexingDispatchMessageFormatter.DeserializeRequest(Viesti viesti, Object[] parametrit) järjestelmässä System.ServiceModel.Dispatcher.UriTemplateDispatchFormatter.DeserializeRequest(Viesti viesti, Object[] parametrit) järjestelmässä System.ServiceModel.Dispatcher.CompositeDispatchFormatter.DeserializeRequest(Viesti viesti, Object[] parametrit) järjestelmässä System.ServiceModel.Dispatcher.DispatchOperationRuntime.DeserializeInputs(MessageRpc& rpc) järjestelmässä System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc) järjestelmässä System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage5(MessageRpc& rpc) järjestelmässä System.ServiceModel.Dispatcher.ImmutableDispatchRuntime.ProcessMessage41(MessageRpc& rpc) järjestelmässä System.ServiceModel.Dispatcher.MessageRpc.Process(Boolean isOperationContextSet)

Joten ajattelen, että minun täytyy selvittää, miten saada objekti menemään langan yli JSON-objektina JQuery.post()-menetelmällä.

Lisätietoja --- Taas...

ok... Ei ole app.configia tai web.configia sellaisenaan.

Tässä on mitä voin saada sopimusten, koodin ja muun sellaisen osalta.

[ServiceContract]
public interface IAccount
{
[OperationContract]
bool Login(UserInformation user);
}

[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class AccountService : IAccount
{
public bool Login(UserInformation user)
{
    //stuff...
}
}

[DataContract]
public class UserInformation
{
[DataMember(IsRequired = true)]
public string UserName;

[DataMember(IsRequired = true)]
public string Password;

[DataMember(IsRequired = true)]
public bool IsNotEncrypted;
}

public interface IUserInformation
{
UserInformation UserInformation { get; set; }
}

Vastaus #1

Joten löysin vastauksen kysymykseeni.

Joku yritti ohjata minut oikeaan suuntaan mainitsemalla JSON.stringify()-menetelmän, mutta sen toteuttaminen oikein vei minulta hieman vaivaa.

Lopulta käytin WireSharkia kaapatakseni HTTP-pyynnön, nähdäkseni, mitä todella lähetettiin ja vastaanotettiin, ja havaita, että minun ei tarvinnut vain muuttaa tiedot merkkijonoksi, vaan myös määrittää sisältötyyppi.

Tässä on lopullinen koodi.

// This is the URL that is used for the service.
var serviceUrl = "http://services.xiine.com/Xiine/Live/AccountService/rest/json/Login";


// This is the JSON object passed to the service
var userInfo = {
    "UserName": null,
    "Password": null,
    "IsNotEncrypted": true
};

// $.ajax is the longhand ajax call in JQuery
$.ajax({
    type: "POST",
    url: serviceUrl,
    contentType: "application/json; charset=utf-8",

    // Stringify the userInfo to send a string representation of the JSON Object
    data: JSON.stringify(userInfo),
    dataType: "json",
    success: function(msg) {
        console.log(msg);
        }});

Vastaus #2

Palvelusi käyttöliittymässä sinun täytyy olla OperationalContract-attribuutti ja siinä attribuutissa sinun täytyy asettaa RequestFormat. Tässä on esimerkki siitä, millaiselta se voisi näyttää.

[OperationContract, WebInvoke(UriTemplate = "/runGenericMethodJSON", Method = "POST",
        RequestFormat = WebMessageFormat.Json,
        ResponseFormat = WebMessageFormat.Json,
        BodyStyle = WebMessageBodyStyle.WrappedRequest)]