Is it possible to configure default ASP.NET WebService test form to support JSON?
I mean the test form that built in in .NET framework...
Currently I have a WebService that decorated with [ScriptService], but when I testing it using built in test form page, it returns XML...I assume, this happens because test page sends Content-Type XML by default.
Thanks
EDIT (Example):
I have class:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Now I have ASP.NET WebService:
[ScriptService]
public class PersonService : WebService
{
[WebMethod]
public Person GetDave()
{
Person dave = new Person();
dave.FirstName = "Dave";
dave.LastName = "Test";
return dave;
}
}
When I call this WebService from web page using jQuery AJAX, I receive JSON Person object {"FirstName":"Dave","LastName":"Test"} (not string) in JavaScript, but when I invoking this WebService from ASP.NET WebService Test Form (When I right click on ASMX file and use "Preview In Browser"),
It returns:
<?xml version="1.0" encoding="utf-8" ?>
<Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://tempuri.org/">
<FirstName>Dave</FirstName>
<LastName>Test</LastName>
</Person>
What want, is when I invoke the service from test page, to see the same output:
{"FirstName":"Dave","LastName":"Test"}
You can use the code below
[WebMethod(Description = "Some Description")]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public string FunctionName()
{
// Return JSON data
JavaScriptSerializer js = new JavaScriptSerializer();
string retJSON = js.Serialize(Object);
return retJSON;
}
And also you need to add the reference.
Update
Here is the link which will explain about extending an existing ASP.NET Web Service to support JSON
Hope that helps
It looks like I found a solution...it still not complete solution, but this is the way to go :)
In [Drive]:\[WindowsDir]\Microsoft.NET\Framework\[Version]\CONFIG folder, exists the file named DefaultWsdlHelpGenerator.aspx. This file contains the whole code needed to automatically generate test page using WSDL. Now I can use this code to write my own test page and make requests using jQuery and not using HTML form...then I can put in config file and this should work.
<webServices>
<wsdlHelpGenerator href="WSTestPage.aspx"/>
</webServices>
Maybe somewhere exists more simple/ready way to do it, but I still not found it...
Add following references first
using System.Web.Script.Services;
using System.Web.Script.Serialization;
use the below code in your method, for converting any data into JSON Data format in end
JavaScriptSerializer serializer = new JavaScriptSerializer();
return serializer.Serialize(dr);
dr is array of DataRows from DataTable.Hope this will help You.
Related
I just started working with ASP.NET after PHP and have a question regarding using AJAX.
What is the correct methodology?
I googled that have Ajax helpers
Or use jquery code for calling methods from controller
Is it ok to return "ready" html code from controllers to view via ajax request?
For example, Now i use the same
$.post('/ControllerName/ActionFromController', { /* some params */ }, function(data){
$("#content_div").html(data);
});
my controller
public ActionResult ActionFromController()
{
// receiving parameters from AJAX request - Request.Form["parameter name"])
// to do something here
string cont = "some result of methjd works - HTML table or something else"
return cont;
}
So is it here any development methodology for using AJAX in asp.net MVC? Or is it ok to use ajax as it described above?
Almost there. The best way to bind your parameters is to strongly type them, which you can do with models. Create a model class:
public class SampleModel
{
public string ParamName1 {get;set;}
public int ParamName2 {get;set;}
}
Make sure your actions accepts this as an input:
public ActionResult ActionFromController(SampleModel model)
And when you send your ajax request specify parameters:
$.post(
'/ControllerName/ActionFromController',
{ "ParamName1": "value", "ParamName2": 1 },
function(data){
$("#content_div").html(data);
}
);
Otherwise what you have look fine.
I would suggest you to get some more information and possible results types:
JsonResult
PartialViewResult - try not to concatenate HTML in the string, return a Partial View which will contain HTML constructed based on model (for example some parameters from the ajax request. Useful resources: Partial View in ASP.NET MVC, Updating an MVC Partial View with Ajax
I am new to Web Technology. I have a WebService called Sample. It references a dll with name Custom.dll. My WebMethod is returning a class from Custom.dll which is marked as Serialization.
// My custom class
[System.CodeDom.Compiler.GeneratedCodeAttribute("wsdl", "2.0.50727.3038")]
[SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://somthing-something.mydomain.com/")]
public class CustomClass
{
public string id;
public string key;
}
// My Web Service method
[WebMethod]
public CustomClass MyWsMethod()
{
return new CustomClass{id="id", key="Key"};
}
Also to mention, my webservice is a WCF Service and has a asmx file in it.
I am consuming this webservice in my application and service referenced my webservice as localhostWS. My Application also references Custom.dll. When I am calling my webservice method then I am not able to get back the Custom.CustomClass object. I am returning localhostWS.CustomClass and also I am not able cast it to Custom.CustomClass.
CustomClass custom = localhostWS.MyWsMethod();
Here custom object is of type localhostWS.CustomClass but I was expecting Custom.CustomClass.
Can any body suggest me whats happening here. Please let know if I need to provide any further information. I have tried enough to be clear in my question.
Edit
I must also mention this, it will great to achieve this without changing any Client side code. Due to reasons it will not be possible to change that. However any suggestions are welcome.
I have a webforms project, and am attempting to run some code that allows me to make a call to an MVC route and then render the result within the body of the web forms page.
There are a couple of HttpResponse/Request/Context wrappers which I use to execute a call to an MVC route, e.g.:
private static string RenderInternal(string path)
{
var responseWriter = new StringWriter();
var mvcResponse = new MvcPlayerHttpResponseWrapper(responseWriter, PageRenderer.CurrentPageId);
var mvcRequest = new MvcPlayerHttpRequestWrapper(Request, path);
var mvcContext = new MvcPlayerHttpContextWrapper(Context, mvcResponse, mvcRequest);
lock (HttpContext.Current)
{
new MvcHttpHandlerWrapper().PublicProcessRequest(mvcContext);
}
...
The code works fine for executing simple MVC routes, for e.g. "/Home/Index". But I can't specify any query string parameters (e.g. "/Home/Index?foo=bar") as they simply get ignored. I have tried to set the QueryString directly within the RequestWrapper instance, like so:
public class MvcPlayerHttpRequestWrapper : HttpRequestWrapper
{
private readonly string _path;
private readonly NameValueCollection query = new NameValueCollection();
public MvcPlayerHttpRequestWrapper(HttpRequest httpRequest, string path)
: base(httpRequest)
{
var parts = path.Split('?');
if (parts.Length > 1)
{
query = ExtractQueryString(parts[1]);
}
_path = parts[0];
}
public override string Path
{
get
{
return _path;
}
}
public override NameValueCollection QueryString
{
get
{
return query;
}
}
...
When debugging I can see the correct values are in the "request.QueryString", but the values never get bound to the method parameter.
Does anyone know how QueryString values are used and bound from an http request to an MVC controller action?
It seems like the handling of the QueryString value is more complex than I anticipated. I have a limited knowledge of the internals of the MVC Request pipeline.
I have been trying to research the internals myself and will continue to do so. If I find anything I will update this post appropriately.
I have also created a very simple web forms project containing only the code needed to produce this problem and have shared it via dropbox: https://www.dropbox.com/s/vi6erzw24813zq1/StackMvcGetQuestion.zip
The project simply contains one Default.aspx page, a Controller, and the MvcWrapper class used to render out the result of an MVC path. If you look at the Default.aspx.cs you will see a route path containing a querystring parameter is passed in, but it never binds against the parameter on the action.
As a quick reference, here are some extracts from that web project.
The controller:
public class HomeController : Controller
{
public ActionResult Index(string foo)
{
return Content(string.Format("<p>foo = {0}</p>", foo));
}
}
The Default.aspx page:
protected void Page_Load(object sender, EventArgs e)
{
string path = "/Home/Index?foo=baz";
divMvcOutput.InnerHtml = MvcWrapper.MvcPlayerFunctions.Render(path);
}
I have been struggling with this for quite a while now, so would appreciate any advice in any form. :)
MVC framework will try to fill the values of the parameters of the action method from the query string (and other available data such as posted form fields, etc.), that part you got right. The part you missed is that it does so by matching the name of the parameter with the value names passed in. So if you have a method MyMethod in Controller MyController with the signature:
public ActionResult MyMethod(string Path)
{
//Some code goes here
}
The query string (or one of the other sources of variables) must contain a variable named "Path" for the framework to be able to detect it. The query string should be /MyController/MyMethod?Path=Baz
Ok. This was a long debugging session :) and this will be a long response, so bear with me :)
First how MVC works. When you call an action method with input parameters, the framework will call a class called "DefaultModelBinder" that will try and provide a value for each basic type (int, long, etc.) and instance of complex types (objects). This model binder will depend on something called the ValueProvider collection to look for variable names in query string, submitted forms, etc. One of the ValueProviders that interests us the most is the QueryStringValueProvider. As you can guess, it gets the variables defined in the query string. Deep inside the framework, this class calls HttpContext.Current to retrieve the values of the query string instead of relying on the ones being passed to it. In your setup this is causing it to see the original request with localhost:xxxx/Default.aspx as the underlying request causing it to see an empty query string. In fact inside the Action method (Bar in your case) you can get the value this.QueryString["variable"] and it will have the right value.
I modified the Player.cs file to use a web client to make a call to an MVC application running in a separate copy of VS and it worked perfectly. So I suggest you run your mvc application separately and call into it and it should work fine.
How would one get resx resource strings into javascript code stored in a .js file?
If your javascript is in a script block in the markup, you can use this syntax:
<%$Resources:Resource, FieldName %>
and it will parse the resource value in as it renders the page... Unfortunately, that will only be parsed if the javascript appears in the body of the page. In an external .js file referenced in a <script> tag, those server tags obviously never get parsed.
I don't want to have to write a ScriptService to return those resources or anything like that, since they don't change after the page is rendered so it's a waste to have something that active.
One possibility could be to write an ashx handler and point the <script> tags to that, but I'm still not sure how I would read in the .js files and parse any server tags like that before streaming the text to the client. Is there a line of code I can run that will do that task similarly to the ASP.NET parser?
Or does anyone have any other suggestions?
Here is my solution for now. I am sure I will need to make it more versatile in the future... but so far this is good.
using System.Collections;
using System.Linq;
using System.Resources;
using System.Web.Mvc;
using System.Web.Script.Serialization;
public class ResourcesController : Controller
{
private static readonly JavaScriptSerializer Serializer = new JavaScriptSerializer();
public ActionResult GetResourcesJavaScript(string resxFileName)
{
var resourceDictionary = new ResXResourceReader(Server.MapPath("~/App_GlobalResources/" + resxFileName + ".resx"))
.Cast<DictionaryEntry>()
.ToDictionary(entry => entry.Key.ToString(), entry => entry.Value.ToString());
var json = Serializer.Serialize(resourceDictionary);
var javaScript = string.Format("window.Resources = window.Resources || {{}}; window.Resources.{0} = {1};", resxFileName, json);
return JavaScript(javaScript);
}
}
// In the RegisterRoutes method in Global.asax:
routes.MapRoute("Resources", "resources/{resxFileName}.js", new { controller = "Resources", action = "GetResourcesJavaScript" });
So I can do
<script src="/resources/Foo.js"></script>
and then my scripts can reference e.g. window.Resources.Foo.Bar and get a string.
There's no native support for this.
I built a JavaScriptResourceHandler a while ago that can serve Serverside resources into the client page via objects where each property on the object represents a localization resource id and its value. You can check this out and download it from this blog post:
http://www.west-wind.com/Weblog/posts/698097.aspx
I've been using this extensively in a number of apps and it works well. The main win on this is that you can localize your resources in one place (Resx or in my case a custom ResourceProvider using a database) rather than having to have multiple localization schemes.
whereas "Common" is the name of the resource file and Msg1 is the fieldname. This also works for culture changes.
Partial Javascript...:
messages:
{
<%=txtRequiredField.UniqueID %>:{
required: "<%=Resources.Common.Msg1 %>",
maxlength: "Only 50 character allowed in required field."
}
}
In a nutshell, make ASP.NET serve javascript rather than HTML for a specific page. Cleanest if done as a custom IHttpHandler, but in a pinch a page will do, just remember to:
1) Clear out all the ASP.NET stuff and make it look like a JS file.
2) Set the content-type to "text/javascript" in the codebehind.
Once you have a script like this setup, you can then create a client-side copy of your resources that other client-side scripts can reference from your app.
If you have your resources in a separate assembly you can use the ResourceSet instead of the filename. Building on #Domenics great answer:
public class ResourcesController : Controller
{
private static readonly JavaScriptSerializer Serializer = new JavaScriptSerializer();
public ActionResult GetResourcesJavaScript()
{
// This avoids the file path dependency.
ResourceSet resourceSet = MyResource.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true);
// Create dictionary.
var resourceDictionary = resourceSet
.Cast<DictionaryEntry>()
.ToDictionary(entry => entry.Key.ToString(), entry => entry.Value.ToString());
var json = Serializer.Serialize(resourceDictionary);
var javaScript = string.Format("window.Resources = window.Resources || {{}}; window.Resources.resources = {1};", json);
return JavaScript(javaScript);
}
}
The downside is that this will not enable more than one resource-file per action. In that way #Domenics answer is more generic and reusable.
You may also consider using OutputCache, since the resource won't change a lot between requests.
[OutputCache(Duration = 3600, Location = OutputCacheLocation.ServerAndClient)]
public ActionResult GetResourcesJavaScript()
{
// Logic here...
}
http://www.asp.net/mvc/overview/older-versions-1/controllers-and-routing/improving-performance-with-output-caching-cs
I usually pass the resource string as a parameter to whatever javascript function I'm calling, that way I can continue to use the expression syntax in the HTML.
I the brown field application I'm working on we have an xslt that transforms the resx file into a javascript file as part of the build process. This works well since this is a web application. I'm not sure if the original question is a web application.
use a hidden field to hold the resource string value and then access the field value in javascript
for example :
" />
var todayString= $("input[name=TodayString][type=hidden]").val();
Add the function in the BasePage class:
protected string GetLanguageText(string _key)
{
System.Resources.ResourceManager _resourceTemp = new System.Resources.ResourceManager("Resources.Language", System.Reflection.Assembly.Load("App_GlobalResources"));
return _resourceTemp.GetString(_key);
}
Javascript:
var _resurceValue = "<%=GetLanguageText("UserName")%>";
or direct use:
var _resurceValue = "<%= Resources.Language.UserName %>";
Note:
The Language is my resouce name. Exam: Language.resx and Language.en-US.resx
I am trying to implement the code given for "jQuery Autocomplete and ASP.NET",
but unable to integrate it because you are using subsonic to query database.
So can you tell me how to query sqldatabase and bind the query result to the plugin from webservice in asp.net using C#?
This is a pretty easy task, the catch is that the jQuery autocomplete extender expects an array of values. Here is example of how I parse the standard XML results from a ASMX web serivce to use with the jQuery autocomplete extender.
Since ASP.NET likes to rewrite your ID's, you can pass in the ClientID to get the dynamic ID.
$("#<%= TextBox1.ClientID %>").autocomplete("/Demo/WebSvc.asmx/SuggestCustomers", {
parse: function(data) {
var parsed = [];
$(data).find("string").each(function() {
parsed[parsed.length] = {
data: [$(this).text()],
value: $(this).text(),
result: [$(this).text()]
};
});
return parsed;
},
dataType: "xml"
});
Here is what the associated web service would look like, remember to uncomment the [ScriptService] attribute on the web service:
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class WebSvc: WebService
{
[WebMethod]
public string[] SuggestedCustomers(string q)
{
// Do Query
// Add items into string array
List<string> items = new List<string>();
while (dr.Read())
{
items.Add(dr[0].ToString());
}
// Return array
return items.ToArray();
}
}
I am not fluent in asp.net but fundamentally like most web coding questions this involves breaking your problem into smaller ones.
From an architectural perspective your components might include the following...
a service layer that potentially uses your db etc to answer or produce a result for your query.
a web component or service entry point that uses the completed service mentioned above to return the data in a format the browesrr can easily understand - eg JSON.
some javascript using jquery which invokes the end point define in the immediate point above.
write unit tests for all the above components - don't forget to test failure cases because as we all know software sometimes fails ...