views:

152

answers:

1

I'm trying to send data from a client application using jQuery to a REST WCF service based on the WCF REST starter kit.

Here's what I have so far.

Service Definition:

[WebHelp(Comment = "Save PropertyValues to the database")]        
[WebInvoke(Method = "POST", UriTemplate = "PropertyValues_Save",
           BodyStyle = WebMessageBodyStyle.WrappedRequest,
           RequestFormat = WebMessageFormat.Json,
           ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
public bool PropertyValues_Save(Guid assetId,
                                Dictionary<Guid, string> newValues) {
            // ...
}

Call from the client:

$.ajax({
     url:SVC_PROPERTYVALUES_SAVE,
     type: "POST",
     contentType: "application/json; charset=utf-8",
     data: jsonData,
     dataType: "json",
    error: function(XMLHttpRequest, textStatus, errorThrown) {
     alert(textStatus + ' ' + errorThrown);
      },
     success: function(data) {
      if (data)  {
       alert('Values saved'); $("#confirmSubmit").dialog('close'); 
      }
      else {
       alert('Values failed to save'); $("#confirmSubmit").dialog('close');
      }      
     }
    });

Example of the JSON being passed:

{
    "assetId": "d70714c3-e403-4cc5-b8a9-9713d05b2ee0",
    "newValues": [
        {
            "key": "bd01aa88-b48d-47c7-8d3f-eadf47a46680",
            "value": "0e9fdf34-2d12-4639-8d70-19b88e753ab1" 
        },
        {
            "key": "06e8eda2-a004-450e-90ab-64df357013cf",
            "value": "1d490aec-f40e-47d5-865c-07fe9624f955" 
        } 
    ] 
}

web.config

<?xml version="1.0"?>
<configuration>

     <configSections>

          <sectionGroup name="applicationSettings"
                        type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">

          </sectionGroup>

     </configSections>

 <system.web>
  <compilation debug="true"/>
        </system.web>
 <system.serviceModel>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>
 </system.serviceModel>

     <appSettings>

         ...

     </appSettings>

</configuration>

I'm using Windows Authentication on the virtual directory and anonymous access is disabled. When I call operations that are GETs, everything is fine. This code is prompting the browser to log in. When I enter my credentials, I simply get an alert in my browser which says "error undefined".

Even if you can't help my specific error, do you see anything that looks wrong from glancing?

I've been beating my head on this nearly all day.

Thanks in advance.

A: 

If you have authentication problems it can be important to verify that only "Windows Authentication" is switches on and "Anonymous" access is switches of in your virtual directory.

If you do have no problem with irtual directory your should post the code of your web.config file.

From your question it stay not clear for me whether you have only authentication problems or the PropertyValues_Save will be not called with the JSON data which you posted. Could you formulate more clear this?

UPDATED: It seems to me that your program will work if the JavaScript client will use "Key" and "Value" property names instead of "key" and "value".

I recommend you also look at the end on my old answer http://stackoverflow.com/questions/2737525/how-do-i-build-a-json-object-to-send-to-an-ajax-webservice/2738086#2738086 to verify, that you pack the data correct for the call of server.

Oleg
Authentication is Integrated and yes, Anonymous is disabled. I only get the login prompt for this particular method. The web.config you asked for:<?xml version="1.0"?><configuration> ... <system.web> <compilation debug="true"/> </system.web> <system.serviceModel> <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/> </system.serviceModel> </configuration>
Randall Sexton
It's correct. I hope you have also `<authentication mode="Windows"/>` inside of `<system.web>` block, if not you should add this. Is `PropertyValues_Save` works without any problem? (only authentication problem)
Oleg
Yes, the method itself works fine inside a unit test.
Randall Sexton
The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:newValues. The InnerException message was 'The data contract type 'System.Runtime.Serialization.KeyValue`2[[System.Guid, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' cannot be deserialized because the required data members 'Key, Value' were not found.'. Please see InnerException for more details.
Randall Sexton
I've seen this error before too. I added the authentication mode to the web.config and got this exeception.I was thinking that perhaps my JSON was bad, but it passes validation at: http://www.jsonlint.com/
Randall Sexton
If seems to me, that JSON is OK, but to deserialize a `Dictionary` you should use `CollectionDataContract` attribute (see http://msdn.microsoft.com/en-us/library/ms731923.aspx, http://msdn.microsoft.com/en-us/library/aa347850.aspx or http://www.netframeworkdev.com/windows-communication-foundation/problem-with-datacontract-dictionaryltstring-objectgt-65475.shtml). Another general way is to make you all interface methods use only very simple data types. For example you can use two `List<>` instead of `Dictionary<>` and combine there in a `Dictionary` inside of `PropertyValues_Save`.
Oleg
I have one more idea. Could you post how you construct `jsonData`. Probably your problem can be very easy solved.
Oleg
Oleg: It was the case-sensitivity of "Key" and "Value". Wow. Exactly what I needed and things are fine now. Thank you for your help.
Randall Sexton