Deserialize JSON Objects in Asp.Net MVC Controller - asp.net

I'm trying to deserialize an object which was generated by LinqToSql. The user is allowed to edit the data of the object in the view and then it gets posted back to the controller. The edited Data comes in JSON. How does this action have to look like?
Something like...
public ActionResult(JsonObject json)
{
MyClass c = Jsonify(json) as MyClass;
}
Is there a nice helpful static class in the framework I'm missing? Or do I have to create a DataContract?
Many thanks

System.Web.Script.Serialization.JavaScriptSerializer
public ActionResult Blah(JsonObject json)
{
JavaScriptSerializer js = new JavaScriptSerializer();
var c = js.Deserialize<MyClass>(json);
return View(c);
}
EDIT: Oops...just noticed you are passing an object instead of string....so you will need to use System.Runtime.Serialization.Json.DataContractJsonSerializer:
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(MyClass));
MyClass c = (MyClass)serializer.ReadObject(json);

Related

ASP.NET MVC cannot convert IList to IEnumerable? Also tried with IList to IList and still an error

Trying to create a partial view with ASP.NET MVC and Ajax. However I keep getting an error saying cannot convert IList to IEnumerable.
A class for my web service:
public IList<Courses> GetHallamUniCourses()
{
List <Courses> HallamCourse = new List <Courses>();
foreach(var courselist in _hallamUniProxy.GetAllCourses())
{
_courses = new Courses();
_courses.CourseID = courselist.CourseId;
_courses.CourseName = courselist.CourseName;
_courses.CourseDescription = courselist.CourseDescription;
_courses.EntryRequirements = courselist.EntryCriteria;
HallamCourse.Add(_courses);
}
return HallamCourse();
}
Then on the controller where the error is coming up:
IEnumerable<Courses.Services.Service.SheffieldHallam> courseHallam = _HallamService.GetHallamUniCourses();
Any ideas why this is happening?
Change the controllercode to:
IEnumerable<Courses> courseHallam = _HallamService.GetHallamUniCourses();
Just for fun here is a rewrite i think will do the trick for you, as well as its a little simpler.
public IList<Courses> GetHallamUniCourses()
{
return _hallamUniProxy.GetAllCourses().Select(a=>
new Courses()
{
CourseID = a.CourseId,
CourseName = a.CourseName,
CourseDescription = a.CourseDescription,
EntryRequirements = a.EntryCriteria
}).ToList();
}
But all in all it looks like you are missing some coding concepts. What you say is a "class", is a method (the one I rewrote above). A controller method in ASP.NET MVC usually return some sort of result.
so IEnumerable<Courses.Services.Service.SheffieldHallam> courseHallam = _HallamService.GetHallamUniCourses(); wont do.
Basic intro to a simple MVC controller
//The name of the class must be Name+Controller, and it must extend Controller
class SomeController: Controller{
//This is a method in the controller, it returns a Result
//its URI is http[s]://Domain/Some
public ContentResult Index(){
return Content("Hello");
}
//This is a sub method of controller some, it's URI is http[s]://Domain/Some/Else
public ContentResult Else(){
return Content("Hello");
}
}
so when you say that you get an error on a controller, the interesting part is where in the controller. If i said that i get an error in the controller on the return Content("Hello") then that might not be too descriptive

How ViewBag in ASP.NET MVC works

How does the ASP.NET MVC's ViewBag work? MSDN says it is just an Object, which intrigues me, how does "Magic" properties such as ViewBag.Foo and magic strings ViewBag["Hello"] actually work?
Also, how can I make one and use it in my ASP.NET WebForms app?
Examples would be really appreciated!
ViewBag is of type dynamic but, is internally an System.Dynamic.ExpandoObject()
It is declared like this:
dynamic ViewBag = new System.Dynamic.ExpandoObject();
which is why you can do :
ViewBag.Foo = "Bar";
A Sample Expander Object Code:
public class ExpanderObject : DynamicObject, IDynamicMetaObjectProvider
{
public Dictionary<string, object> objectDictionary;
public ExpanderObject()
{
objectDictionary = new Dictionary<string, object>();
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
object val;
if (objectDictionary.TryGetValue(binder.Name, out val))
{
result = val;
return true;
}
result = null;
return false;
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
try
{
objectDictionary[binder.Name] = value;
return true;
}
catch (Exception ex)
{
return false;
}
}
}
It's a dynamic object, meaning you can add properties to it in the controller, and read them later in the view, because you are essentially creating the object as you do, a feature of the dynamic type. See this MSDN article on dynamics. See this article on it's usage in relation to MVC.
If you wanted to use this for web forms, add a dynamic property to a base page class like so:
public class BasePage : Page
{
public dynamic ViewBagProperty
{
get;
set;
}
}
Have all of your pages inherit from this. You should be able to, in your ASP.NET markup, do:
<%= ViewBagProperty.X %>
That should work. If not, there are ways to work around it.
The ViewBag is an System.Dynamic.ExpandoObject as suggested. The properties in the ViewBag are essentially KeyValue pairs, where you access the value by the key. In this sense these are equivalent:
ViewBag.Foo = "Bar";
ViewBag["Foo"] = "Bar";
ViewBag is used to pass data from Controller Action to view to render the data that being passed. Now you can pass data using between Controller Action and View either by using ViewBag or ViewData.
ViewBag: It is type of Dynamic object, that means you can add new fields to viewbag dynamically and access these fields in the View. You need to initialize the object of viewbag at the time of creating new fields.
e.g:
1. Creating ViewBag:
ViewBag.FirstName="John";
Accessing View:
#ViewBag.FirstName.
ViewBag is of type dynamic. More, you cannot do ViewBag["Foo"]. You will get exception - Cannot apply indexing with [] to an expression of type 'System.Dynamic.DynamicObject'.
Internal implementation of ViewBag actually stores Foo into ViewData["Foo"] (type of ViewDataDictionary), so those 2 are interchangeable. ViewData["Foo"] and ViewBag.Foo.
And scope. ViewBag and ViewData are ment to pass data between Controller's Actions and View it renders.
ViewBag is a dynamic type that allow you to dynamically set or get values and allow you to add any number of additional fields without a strongly-typed class
They allow you to pass data from controller to view.
In controller......
public ActionResult Index()
{
ViewBag.victor = "My name is Victor";
return View();
}
In view
#foreach(string a in ViewBag.victor)
{
.........
}
What I have learnt is that both should have the save dynamic name property ie ViewBag.victor
public dynamic ViewBag
{
get
{
if (_viewBag == null)
{
_viewBag = new DynamicViewData(() => ViewData);
}
return _viewBag;
}
}

How can I read JSON in ASP.NET?

I need a simple method to read the results from Amazon Affiliates URL, I have the code for Amazon and I get a JSON result which I cannot read in ASP.NET.
Is there an easy method to parse the JSON data in ASP.NET 4.5 ?
You could also use the .NET built-in JavaScriptSerializer:
using System.Web.Script.Serialization;
...
JavaScriptSerializer js = new JavaScriptSerializer();
dynamic obj = js.Deserialize<dynamic>(jsonString);
You can use JObject class based on Json.net
Link : http://james.newtonking.com/pages/json-net.aspx
For parsing you can use JObject.Parse Method
Code
var jsonString = #"{""Name"":""Aghilas"",""Company"":""....."",
""Entered"":""2012-03-16T00:03:33.245-10:00""}";
dynamic json = JValue.Parse(jsonString);
// values require casting
string name = json.Name;
string company = json.Company;
DateTime entered = json.Entered;
Use JSON.NET package, its great and simple.
To install the package:
Open the console. "View" > "Other Windows" > "Package Manager Console"
Then type the following:
Install-Package Newtonsoft.Json
You can both read the Json object as dynamic object or as strongly-typed one.
In case you want to read the Json type as a strongly typed object, you can do the following:
The class to populate the data:
public class AmazonAffiliate
{
public string Username {get;set;}
public string Email {get;set;}
public Date BirthDate {get;set;}
}
Method for converting Json strings to strongly-typed class:
public static T GetJsonContent<T>(string jsonAsString)
{
var serializer = new JsonSerializer<T>();
return serializer.DeserializeFromString(jsonAsString);
}
And you can use it like this:
AmazonAffiliate affiliate = GetJsonContent<AmazonAffiliate>(jsonString);

Unit Testing An Extension Method on HtmlHelper

I have an HTMLHelper extension method that outputs HTML to Response.Write. How best to unit test this?
I'm considering mocking the HtmlHelper passed into the method, but am unsure as to how I should verify the HTML sent to Response.Write.
Thanks
If you are using an HTML helper to output text to the browser why not have it return a string and in your view do something like ...
<%=Html.YourExtension() %>
It makes it a great deal more testable.
Kindness,
Dan
EDIT:
Modification would be a change of signature
public static void YourExtension(this HtmlHelper html)
{
...
Response.Write(outputSting);
}
to
public static string YourExtension(this HtmlHelper html)
{
...
return outputSting;
}
I use the following code to test and validate html helpers. If you are doing anything complex, like disposable based helpers like beginform or helpers with dependencies you need a better test framework then just looking at the string of a single helper.
Validation is a another example.
Try the following:
var sb = new StringBuilder();
var context = new ViewContext();
context.ViewData = new ViewDataDictionary(_testModel);
context.Writer = new StringWriter(sb);
var page = new ViewPage<TestModel>();
var helper = new HtmlHelper<TestModel>(context, page);
//Do your stuff here to exercise your helper
//Get the results of all helpers
var result = sb.ToString();
//Asserts and string tests here for emitted HTML
Assert.IsNotNullOrEmpty(result);
This works if the method "YourExtension" is simply using HtmlHelper methods that return string or HtmlString. But methods like "BeginForm" return MvcForm object and also the form tag is written directly on TextWriter that HtmlHelper has reference to.

Proper way of using FormCollection in ASP.NET MVC2 Create Method?

I am currently developing an application with the new ASP.NET MVC2 framework. Originally I started writing this application in the ASP.NET MVC1 and I'm basically just updating it to MVC2.
My problem here is, that I don't really get the concept of the FormCollection object vs. the old Typed object.
This is my current code:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(FormCollection collection)
{
try
{
Member member = new Member();
member.FirstName = collection["FirstName"];
member.LastName = collection["LastName"];
member.Address = collection["Address"];
// ...
return RedirectToAction("Details", new { id = member.id });
}
catch
{
return View("Error");
}
}
This is the Code from the MVC1 application:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create(Member member)
{
try
{
memberRepository.Add(member);
memberRepository.Save();
return RedirectToAction("Details", new { id = member.id });
}
catch
{
}
return View(new MemberFormViewModel(member, memberRepository));
}
What are the benefits of switching to FormCollection in MVC2 and more importantly - how is it used properly?
You had the FormCollection object in v1 as well. But it is more preferred to use a typed object. So if you are already doing that, then continue doing so.
By using FormCollection, you wind up manually matching your post data or query string key/values into values to use in your code using string typing (resulting in stringly-typed code), when instead the built-in Model Binding can do this for you if you use form models, aka "typed objects."
I think by using the FormCollection, you would probably also lose the ability to use the handy Data Annotation (slash Validation) attributes on your model objects as well, which are designed for use with typed object model binding.
Additionally, unit testing can become much more cumbersome once you start touching your controller.Request.Form. You might find yourself having to mock and setup an HttpContextBase, and an HttpRequestBase just to have that mock request's .Form property return the NameValueCollection that you are wanting your test to see. Contrast this to letting model binding do the work for you such as:
// Arrange
var myModel = new MyModel( Property1 = "value1", Property2 = "value2");
// Act
var myResult = myController.MyActionMethod(myModel);
// Assert
// whatever you want the outcome to be
In summary, I would recommend against using FormCollection to the maximum extent possible.

Resources