c# - Deserializing JSON in REST Service -
i having problem deserializing json in rest self-hosted service.
i have test page invokes self-hosted rest json, here code:
<!doctype html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <script type="text/javascript"> function dofunction() { xhr = new xmlhttprequest(); var url = "https://localhost:1234/business/test/testing2/endpoint"; xhr.open("post", url, true); xhr.setrequestheader("content-type", "application/json"); xhr.onreadystatechange = function () { if (xhr.readystate == 4 && xhr.status == 200) { var json = json.parse(xhr.responsetext); alert(json); } } var data = json.stringify({ testing : "test" }); xhr.send(data); } </script> <title></title> </head> <body> <form id="form1" runat="server"> <div> <input id="clickme" type="button" value="clickme" onclick="dofunction();" /> </div> </form> </body> </html> and here interface , contracts of self-hosted service:
[datacontract] public class operationinput { [datamember] public string testing { get; set; } } [datacontract] public class operationoutput { [datamember] public int status { get; set; } [datamember] public string message { get; set; } [datamember] public string addinfo { get; set; } [datamember] public string partnerid { get; set; } [datamember] public string sessionid { get; set; } } [servicecontract] interface iregisteroperation { [operationcontract] [webinvoke(uritemplate = "/endpoint", requestformat = webmessageformat.json, responseformat = webmessageformat.json, method = "*")] operationoutput operation(operationinput order); } and here implementation of interface:
public class registeroperation : iregisteroperation { public operationoutput operation(operationinput input) { system.io.streamwriter file = new system.io.streamwriter("c:\\testing.txt", false); file.writeline(input.testing); file.close(); operationoutput output = new operationoutput(); output.status = 200; output.message = "the action has been recorded on nave"; output.addinfo = ""; return output; } } i creating self-host using code:
host = new servicehost(implementationtype, baseaddress); serviceendpoint se = host.addserviceendpoint(endpointtype, new webhttpbinding(webhttpsecuritymode.transport), ""); se.behaviors.add(new webhttpbehavior()); host.open(); using debug notice hits breakpoint inside service, call localhost working parameter of input null, can see in image below:
here 2 images capturing post request json on fiddler:
have idea why getting null ? instead of string "test" on invocation in javascript?
thank in advance ;)
edit:
i activated https decryption on fiddler , pressed "yes" install certificate on trusted ca instead of pressin "no", , breakpoint hitted, , fiddler captured options request following images represent
shouldn't post request instead of options request?? maybe that's why don't see json?
thanks lot
i figured out, problem options request, need receive post request json.
i added behaviour attribute service host responds options request allowing wcf service host receive cross origin requests.
so added code answer of (cross origin resource sharing c# wcf restful web service hosted windows service) question , post request after first options request:
if link no longer available, here solution of question:
code:
create 2 classes follows:
messageinspectorimplementingidispatchmessageinspector.behaviorattributeimplementingattribute,iendpointbehavior,ioperationbehavior.
with following details:
//messageinspector class using system; using system.servicemodel; using system.servicemodel.channels; using system.servicemodel.dispatcher; using system.servicemodel.description; namespace mycorsservice { public class messageinspector : idispatchmessageinspector { private serviceendpoint _serviceendpoint; public messageinspector(serviceendpoint serviceendpoint) { _serviceendpoint = serviceendpoint; } /// <summary> /// called when inbound message been received /// </summary> /// <param name="request">the request message.</param> /// <param name="channel">the incoming channel.</param> /// <param name="instancecontext">the current service instance.</param> /// <returns> /// object used correlate statemsg. /// object passed in method. /// </returns> public object afterreceiverequest(ref message request, iclientchannel channel, instancecontext instancecontext) { statemessage statemsg = null; httprequestmessageproperty requestproperty = null; if (request.properties.containskey(httprequestmessageproperty.name)) { requestproperty = request.properties[httprequestmessageproperty.name] httprequestmessageproperty; } if (requestproperty != null) { var origin = requestproperty.headers["origin"]; if (!string.isnullorempty(origin)) { statemsg = new statemessage(); // if cors options request (preflight) detected, // create our own reply message , don't invoke // operation @ all. if (requestproperty.method == "options") { statemsg.message = message.createmessage(request.version, null); } request.properties.add("crossoriginresourcesharingstate", statemsg); } } return statemsg; } /// <summary> /// called after operation has returned before reply message /// sent. /// </summary> /// <param name="reply">the reply message. value null if /// operation 1 way.</param> /// <param name="correlationstate">the correlation object returned /// method.</param> public void beforesendreply(ref message reply, object correlationstate) { var statemsg = correlationstate statemessage; if (statemsg != null) { if (statemsg.message != null) { reply = statemsg.message; } httpresponsemessageproperty responseproperty = null; if (reply.properties.containskey(httpresponsemessageproperty.name)) { responseproperty = reply.properties[httpresponsemessageproperty.name] httpresponsemessageproperty; } if (responseproperty == null) { responseproperty = new httpresponsemessageproperty(); reply.properties.add(httpresponsemessageproperty.name, responseproperty); } // access-control-allow-origin should added cors responses responseproperty.headers.set("access-control-allow-origin", "*"); if (statemsg.message != null) { // following headers should added options requests responseproperty.headers.set("access-control-allow-methods", "post, options, get"); responseproperty.headers.set("access-control-allow-headers", "content-type, accept, authorization, x-requested-with"); } } } } class statemessage { public message message; } } //behaviorattribute class using system; using system.servicemodel.channels; using system.servicemodel.description; using system.servicemodel.dispatcher; namespace openbetretail.nfcreaderservice { public class behaviorattribute : attribute, iendpointbehavior, ioperationbehavior { public void validate(serviceendpoint endpoint) { } public void addbindingparameters(serviceendpoint endpoint, bindingparametercollection bindingparameters) { } /// <summary> /// service modify or extend service across endpoint. /// </summary> /// <param name="endpoint">the endpoint exposes contract.</param> /// <param name="endpointdispatcher">the endpoint dispatcher /// modified or extended.</param> public void applydispatchbehavior(serviceendpoint endpoint, endpointdispatcher endpointdispatcher) { // add inspector detects cross origin requests endpointdispatcher.dispatchruntime.messageinspectors.add( new messageinspector(endpoint)); } public void applyclientbehavior(serviceendpoint endpoint, clientruntime clientruntime) { } public void validate(operationdescription operationdescription) { } public void applydispatchbehavior(operationdescription operationdescription, dispatchoperation dispatchoperation) { } public void applyclientbehavior(operationdescription operationdescription, clientoperation clientoperation) { } public void addbindingparameters(operationdescription operationdescription, bindingparametercollection bindingparameters) { } } } after need add message inspector service end point behavior.
servicehost host = new servicehost(typeof(myservice), _baseaddress); foreach (serviceendpoint ep in host.description.endpoints) ep.behaviors.add(new behaviorattribute()); thanks ;)






Comments
Post a Comment