I have ASP.NET application with the form handled by AngularJS. There are 2 date-time pickers (fromDate and toDate variables) and check box that indicate if open dates are included (isOpenDatesIncluded).
The code looks as following:
1) In first AngularJS module:
SearchActionsApp.controller("ListController", function($scope, $location,$q, Actions, ActionDates, CounterAgents,Counteragents, AsyncTask) {
...
$scope.actionsQuery = {
searchText: "",
fromDate: new Date(moment().format("MM/DD/YYYY")),
toDate: new Date(moment().add('d', 3).format("MM/DD/YYYY")),
isOpenDatesIncluded: false,
...
ActionDates.query({ actionId: action.Id }, task.success, task.error);
...
}
2) In service.js:
.factory('ActionDates', function ($resource) {
return $resource('/RestApi/api/ActionDates', {});
})
3) On server side:
public IEnumerable<ActionDateItem> QueryActionDates(ActionDateQuery query)
{
var sql = query.BuildSql();
using (var cn = CreateSqlConnection())
{
return cn.Query<ActionDateItem>(sql, new
{
query.ActionId,
query.IsOpenDatesIncluded,
BeginDate = query.FromDate,
EndDate = query.ToDate
});
}
}
public class ActionDateQuery
{
public ActionDateQuery()
{
ActionId = -1;
IsOpenDatesIncluded = false;
FromDate = new DateTime(1980, 1, 1);
ToDate = DateTime.Now.AddYears(1);
}
public long ActionId { get; set; }
public bool IsOpenDatesIncluded { get; set; }
public DateTime FromDate { get; set; }
public DateTime ToDate { get; set; }
}
The issue is the query returns the set of data from: 1980, 1, 1 to DateTime.Now.AddYears(1), but I need to return the data in range: fromDate - toDate, which I get from the client side. I need to pass 3 more parameters except from action.Id that is: fromDate, toDate and isOpenDatesIncluded.
How to do that?
Simply add them to the arguments of the query method as follows:
query({
actionId: action.Id,
fromDate: $scope.actionsQuery.fromDate,
...
}, task.success, task.error)
If they are not pre-bound in the resouce, they will be appended to the request URL as query parameters.
-- Edit --
Also might I suggest using promises rather than callbacks, as it'll help with readability and chaining:
query({
actionId: action.Id,
fromDate: $scope.actionsQuery.fromDate,
...
}).$promise.then(function(response) {
// success
}).catch(function(error) {
// error
});
ActionDates.query({ actionId: action.Id }, task.success, task.error);
Add the missing 3 parameters, like
{actionId: action.Id, fromDate: fromDate, etc}
and try to bind your parameters in the resource
$resource('/RestApi/api/ActionDates', { id: '#id', fromdate:'#fromdate', etc});
Related
Hi I have problems when I use ODate for comparing my dates. When I do this next request:
https://localhost:44391/api/v1/Invoice/OData?$top=11&$skip=0&$filter=InvoiceDate lt 2014-10-30
I obtain the next error:
{
"StatusCode": 500,
"Message": "Unable to cast object of type 'Microsoft.OData.UriParser.ConvertNode' to type 'Microsoft.OData.UriParser.ConstantNode'."
}
The dates that I have in my database is looked like at nexts:
2013-12-30 00:00:00.000
2013-12-30 00:00:00.000
2017-07-14 00:00:00.000
In my class Startup I had the next:
private static IEdmModel GetEdmModel()
{
ODataConventionModelBuilder builder = new ODataConventionModelBuilder();
List<string> listaControllers = GetControllers();
foreach (string controller in listaControllers)
{
builder.EntitySet<BaseEntityDto>(controller);
}
return builder.GetEdmModel();
}
private static List<string> GetControllers()
{
Type parentType = typeof(ApiControllerBase<,,>);
Assembly assembly = Assembly.GetExecutingAssembly();
return assembly.GetTypes().Where(x => x.BaseType.Name == parentType.Name).Select(x => x.Name.Replace("Controller", "")).ToList<string>();
}
app.UseMvc(routeBuilder =>
{
routeBuilder.Expand().Select().Filter().Count().OrderBy().MaxTop(null);
routeBuilder.EnableDependencyInjection();
routeBuilder.MapODataServiceRoute("odata", "odata", GetEdmModel());
});
And in my entity Invoice.cs I had the next attribute:
public DateTime InvoiceDate { get; set; }
And When I executed the last query in the Postman the controller (Invoicecontroller.cs) that is executed is the next:
[HttpGet("OData")]
public async Task<PageResult<InvoiceDto>> Get(ODataQueryOptions<InvoiceDto> queryOptions)
{
var options = new ODataQueryListOptions(queryOptions);
var result = await InvoiceQueryService.GetAll(options.QueryListOptions);
var count = await InvoiceQueryService.Count(options.QueryListOptions);
return new PageResult<InvoiceDto>(result, null, count);
}
I don't know where the problem ocurred, and I need more information for solving the problem. Thanks to everyone for trying to solve this thing. I want to say that I use Views no Tables.
Only put this in my entity solve my problem:
[Column(TypeName = "datetime")]
public DateTime InvoiceDate { get; set; }
Thanks for all community for reading my question.
I have a problem, I need to send data from my Angular to my ASP.NET Core server. Here is controller:
[HttpPut]
public IActionResult setCoupon(int id, string CouponCode, int DiscountPercent)
{
try
{
var coupon = new Coupon()
{
Id = id,
CouponCode = CouponCode,
DiscountPercent = DiscountPercent
};
return Ok(coupon);
}
catch (Exception)
{
return BadRequest("Wystąpił błąd");
}
}
Here is factory from ngResource (getCoupon is working):
app.factory('couponApi',
function($resource) {
return $resource("/coupon/setCoupon",
{},
{
getCoupon: {
method: "GET",
isArray: false
},
putCoupon: {
method: "PUT",
isArray: false,
}
});
});
Here is usage of factory:
$scope.addCouponCode = function(coupon) {
couponApi.putCoupon(coupon);
};
When i debug my asp.net server i found my params null or 0. I have the same problem on restangular library.
I also try this way to write controller method
[HttpPut]
public IActionResult setCoupon(Coupon coupon)
{
try
{
return Ok(coupon);
}
catch (Exception)
{
return BadRequest("Wystąpił błąd");
}
}
My json which I try to send is this
{"id":1,"couponCode":"abc","discountPercent":10}
and my Echo method send me this:
{"id":0,"couponCode":null,"discountPercent":0}
Update
Apparently in asp.net core, method need to have attribute[FromBody]
[HttpPut]
public IActionResult setCoupon([FromBody] Coupon coupon)
{
try
{
return Ok(coupon);
}
catch (Exception)
{
return BadRequest(new {errorMessage = "Wystąpił błąd"});
}
}
As Aldo says in the comments. The answer is C# expects case-sensitive matching of the json data. So:
{"id":1,"couponCode":"abc","discountPercent":10}
needs to be:
{"id":1,"CouponCode":"abc","DiscountPercent":10}
You were getting a 0 for 'discountPercent' because that is the default value of the unmatched int, whereas null is the default for a unmatched string, hence Echo returns:
{"id":0,"couponCode":null,"discountPercent":0}
I'm making a Workflow designer similar to Visual Workflow Tracking*.
I would like add a new control to debug wf, but id don't know how to access to wf context
To Run WF I Use this :
WFApplication wfApp = new WorkflowApplication(act, inputs);
My idea is when i recive trace event, get context of wfApp, to get vars or arguments values.
It's posibble?
*You can donwload VisualStudioTracking Code From :
Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4
and then
:\WF_WCF_Samples\WF\Application\VisualWorkflowTracking*
Finally I solved the problem.
First I get all arguments names, and variables of workflow, from xaml.
class XamlHelper
{
private string xaml;
public XamlHelper(string xaml)
{
this.xaml = xaml;
DynamicActivity act = GetRuntimeExecutionRoot(this.xaml);
ArgumentNames = GetArgumentsNames(act);
GetVariables(act);
}
private void GetVariables(DynamicActivity act)
{
Variables = new List<string>();
InspectActivity(act);
}
private void InspectActivity(Activity root)
{
IEnumerator<Activity> activities =
WorkflowInspectionServices.GetActivities(root).GetEnumerator();
while (activities.MoveNext())
{
PropertyInfo propVars = activities.Current.GetType().GetProperties().FirstOrDefault(p => p.Name == "Variables" && p.PropertyType == typeof(Collection<Variable>));
if (propVars != null)
{
try
{
Collection<Variable> variables = (Collection<Variable>)propVars.GetValue(activities.Current, null);
variables.ToList().ForEach(v =>
{
Variables.Add(v.Name);
});
}
catch
{
}
}
InspectActivity(activities.Current);
}
}
public List<string> Variables
{
get;
private set;
}
public List<string> ArgumentNames
{
get;
private set;
}
private DynamicActivity GetRuntimeExecutionRoot(string xaml)
{
Activity root = ActivityXamlServices.Load(new StringReader(xaml));
WorkflowInspectionServices.CacheMetadata(root);
return root as DynamicActivity;
}
private List<string> GetArgumentsNames(DynamicActivity act)
{
List<string> names = new List<string>();
if (act != null)
{
act.Properties.Where(p => typeof(Argument).IsAssignableFrom(p.Type)).ToList().ForEach(dp =>
{
names.Add(dp.Name);
});
}
return names;
}
}
Second I create trace with these arguments and variable names
private static WFTrace CreateTrace(List<string> argumentNames, List<string> variablesNames)
{
WFTrace trace = new WFTrace();
trace.TrackingProfile = new TrackingProfile()
{
ImplementationVisibility = ImplementationVisibility.All,
Name = "CustomTrackingProfile",
Queries =
{
new CustomTrackingQuery()
{
Name = all,
ActivityName = all
},
new WorkflowInstanceQuery()
{
// Limit workflow instance tracking records for started and completed workflow states
States = {WorkflowInstanceStates.Started, WorkflowInstanceStates.Completed },
}
}
};
trace.TrackingProfile.Queries.Add(GetActivityQueryState(argumentNames, variablesNames));
return trace;
}
And then invoke wf and add traceextension.
Adam this is the code
private TrackingQuery GetActivityQueryState(List<string> argumentNames, List<string> variablesNames)
{
ActivityStateQuery query = new ActivityStateQuery()
{
ActivityName = "*",
States = { ActivityStates.Executing, ActivityStates.Closed }
};
if (argumentNames != null)
{
argumentNames.Distinct().ToList().ForEach(arg =>
{
query.Arguments.Add(arg);
});
}
if (variablesNames != null)
{
variablesNames.Distinct().ToList().ForEach(v =>
{
query.Variables.Add(v);
});
}
return query;
}
You can use a Tracking Participants to extract the variables and arguments when the workflow is running.
I try tracking variables with this tracking participant
private static VisualTrackingParticipant VisualTracking()
{
String all = "*";
VisualTrackingParticipant simTracker = new VisualTrackingParticipant()
{
TrackingProfile = new TrackingProfile()
{
Name = "CustomTrackingProfile",
Queries =
{
new CustomTrackingQuery()
{
Name = all,
ActivityName = all
},
new WorkflowInstanceQuery()
{
// Limit workflow instance tracking records for started and completed workflow states
// States = { WorkflowInstanceStates.Started, WorkflowInstanceStates.Completed },
States={all}
},
new ActivityStateQuery()
{
// Subscribe for track records from all activities for all states
ActivityName = all,
States = { all },
// Extract workflow variables and arguments as a part of the activity tracking record
// VariableName = "*" allows for extraction of all variables in the scope
// of the activity
Variables =
{
{ all }
},
Arguments={ {all}}
}
}
}
};
return simTracker;
}
and this is VisualTrackingParticipant
public class VisualTrackingParticipant : System.Activities.Tracking.TrackingParticipant
{
public event EventHandler<TrackingEventArgs> TrackingRecordReceived;
public Dictionary<string, Activity> ActivityIdToWorkflowElementMap { get; set; }
protected override void Track(TrackingRecord record, TimeSpan timeout)
{
OnTrackingRecordReceived(record, timeout);
}
//On Tracing Record Received call the TrackingRecordReceived with the record received information from the TrackingParticipant.
//We also do not worry about Expressions' tracking data
protected void OnTrackingRecordReceived(TrackingRecord record, TimeSpan timeout)
{
System.Diagnostics.Debug.WriteLine(
String.Format("Tracking Record Received: {0} with timeout: {1} seconds.", record, timeout.TotalSeconds)
);
if (TrackingRecordReceived != null)
{
ActivityStateRecord activityStateRecord = record as ActivityStateRecord;
if//(
(activityStateRecord != null)
// && (!activityStateRecord.Activity.TypeName.Contains("System.Activities.Expressions")))
{
Activity act = null;
ActivityIdToWorkflowElementMap.TryGetValue(activityStateRecord.Activity.Id, out act);
TrackingRecordReceived(this, new TrackingEventArgs(
record,
timeout,
act
)
);
}
else
{
TrackingRecordReceived(this, new TrackingEventArgs(record, timeout, null));
}
}
}
}
//Custom Tracking EventArgs
public class TrackingEventArgs : EventArgs
{
public TrackingRecord Record {get; set;}
public TimeSpan Timeout {get; set;}
public Activity Activity { get; set; }
public TrackingEventArgs(TrackingRecord trackingRecord, TimeSpan timeout, Activity activity)
{
this.Record = trackingRecord;
this.Timeout = timeout;
this.Activity = activity;
}
}
if I trace this wf :
<Activity mc:Ignorable="sap" x:Class="Microsoft.Samples.Workflow" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:av="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="clr-namespace:Microsoft.VisualBasic;assembly=System" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:s1="clr-namespace:System;assembly=System" xmlns:s2="clr-namespace:System;assembly=System.Xml" xmlns:s3="clr-namespace:System;assembly=System.Core" xmlns:sa="clr-namespace:System.Activities;assembly=System.Activities" xmlns:sad="clr-namespace:System.Activities.Debugger;assembly=System.Activities" xmlns:sap="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=System" xmlns:scg1="clr-namespace:System.Collections.Generic;assembly=System.ServiceModel" xmlns:scg2="clr-namespace:System.Collections.Generic;assembly=System.Core" xmlns:scg3="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:sd="clr-namespace:System.Data;assembly=System.Data" xmlns:sd1="clr-namespace:System.Data;assembly=System.Data.DataSetExtensions" xmlns:sl="clr-namespace:System.Linq;assembly=System.Core" xmlns:st="clr-namespace:System.Text;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<x:Members>
<x:Property Name="decisionVar" Type="InArgument(x:Boolean)" />
</x:Members>
<sap:VirtualizedContainerService.HintSize>666,676</sap:VirtualizedContainerService.HintSize>
<mva:VisualBasic.Settings>Assembly references and imported namespaces serialized as XML namespaces</mva:VisualBasic.Settings>
<Flowchart sad:XamlDebuggerXmlReader.FileName="C:\WF_WCF_Samples\WF\Application\VisualWorkflowTracking\CS\VisualWorkflowTracking\Workflow.xaml" sap:VirtualizedContainerService.HintSize="626,636" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces">
<Flowchart.Variables>
<Variable x:TypeArguments="x:String" Name="myStr" />
</Flowchart.Variables>
<sap:WorkflowViewStateService.ViewState>
<scg3:Dictionary x:TypeArguments="x:String, x:Object">
<x:Boolean x:Key="IsExpanded">False</x:Boolean>
<av:Point x:Key="ShapeLocation">270,7.5</av:Point>
<av:Size x:Key="ShapeSize">60,75</av:Size>
<av:PointCollection x:Key="ConnectorLocation">300,82.5 300,111.5</av:PointCollection>
<x:Double x:Key="Width">611.5</x:Double>
</scg3:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<Flowchart.StartNode>
<FlowStep x:Name="__ReferenceID0">
<sap:WorkflowViewStateService.ViewState>
<scg3:Dictionary x:TypeArguments="x:String, x:Object">
<av:Point x:Key="ShapeLocation">179,111.5</av:Point>
<av:Size x:Key="ShapeSize">242,58</av:Size>
<av:PointCollection x:Key="ConnectorLocation">300,169.5 300,199.5 280,199.5 280,269.5</av:PointCollection>
</scg3:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<Assign sap:VirtualizedContainerService.HintSize="242,58">
<Assign.To>
<OutArgument x:TypeArguments="x:String">[myStr]</OutArgument>
</Assign.To>
<Assign.Value>
<InArgument x:TypeArguments="x:String">PDC Rocks</InArgument>
</Assign.Value>
</Assign>
<FlowStep.Next>
<FlowStep x:Name="__ReferenceID1">
<sap:WorkflowViewStateService.ViewState>
<scg3:Dictionary x:TypeArguments="x:String, x:Object">
<av:Point x:Key="ShapeLocation">174.5,269.5</av:Point>
<av:Size x:Key="ShapeSize">211,61</av:Size>
<av:PointCollection x:Key="ConnectorLocation">155.33,351.361666666667 155.33,481 204.5,481</av:PointCollection>
</scg3:Dictionary>
</sap:WorkflowViewStateService.ViewState>
<WriteLine sap:VirtualizedContainerService.HintSize="211,61" Text="[myStr]" />
</FlowStep>
</FlowStep.Next>
</FlowStep>
</Flowchart.StartNode>
<x:Reference>__ReferenceID0</x:Reference>
<x:Reference>__ReferenceID1</x:Reference>
</Flowchart>
</Activity>
When activitity assing close y recive this trace this args
[Arg] Value = PDC Rocks
[Arg] To = PDC Rocks
and I don't know the name of var where value is assined
I'd like to know how to run this query in Linq way.
UPDATE orders SET shipDate = '6/15/2012' WHERE orderId IN ('123123','4986948','23947439')
My Codes,
[HttpGet]
public void test()
{
EFOrdersRepository ordersRepository = new EFOrdersRepository();
var query = ordersRepository.Orders;
// How to run this query in LINQ
// Query : UPDATE orders SET shipDate = '6/15/2012' WHERE orderId IN ('123123','4986948','23947439')
}
EFOrdersRepository.cs
public class EFOrdersRepository
{
private EFMysqlContext context = new EFMysqlContext();
public IQueryable<Order> Orders
{
get { return context.orders; }
}
}
EFMysqlContext.cs
class EFMysqlContext : DbContext
{
public DbSet<Order> orders { get; set; }
}
Actually it's pretty easy check the following code
EFOrdersRepository db = new EFOrdersRepository();
int[] ids= new string[] { "123123", "4986948", "23947439"};
//this linq give's the orders with the numbers
List<Order> orders = db.Order().ToList()
.Where( x => ids.Contains(x.orderId.Contains));
foreach(var order in orders)
{
order.ShipDate = '06/15/2012';
db.Entry(usuario).State = EntityState.Modified;
}
db.SaveChanges();
Something like this should work (warning Pseudo code ahead!!)
EDIT I like using the Jorge's method of retrieving the orders better (using contains), but leaving this here as another alternative. The statements below the code sample still hold true however.
[HttpGet]
public void test()
{
EFOrdersRepository ordersRepository = new EFOrdersRepository();
var query = ordersRepository.Orders.Where(x=>x.orderId == '123123' ||
x.orderId == '4986948' || x.orderId = '23947439').ToList();
foreach(var order in query){
var localOrder = order;
order.ShipDate = '06/15/2012';
}
ordersRepository.SaveChanges();
}
Basically, LINQ does not do 'bulk updates' well. You either have to fetch and loop through your orders or write a stored procedure that can take an array of ids and bulk update them that way. If you are only doing a few at a time, the above will work ok. If you have tons of orders that need to be updated, the ORM probably will not be the best choice. I look forward to see if anyone else has a better approach.
Disclaimer: the var localOrder = order line is to ensure that there are no modified closure issues. Also, ReSharper and other tools may have a less verbose way of writing the above.
Note: You need to call SaveChanges from your DBContext at the end
Short answer:
var f = new[] { 123123, 4986948, 23947439 };
var matchingOrders = orders.Where(x => f.Contains(x.ID)).ToList();
matchingOrders.ForEach(x => x.ShipDate = newDate);
Complete test:
// new date value
var newDate = new DateTime(2012, 6, 15);
// id's
var f = new[] { 123123, 4986948, 23947439 };
// simpulating the orders from the db
var orders = Builder<Order2>.CreateListOfSize(10).Build().ToList();
orders.Add(new Order2 { ID = 123123 });
orders.Add(new Order2 { ID = 4986948 });
orders.Add(new Order2 { ID = 23947439 });
// selecting only the matching orders
var matchingOrders = orders.Where(x => f.Contains(x.ID)).ToList();
matchingOrders.ForEach(x => Console.WriteLine("ID: " + x.ID + " Date: " + x.ShipDate.ToShortDateString()));
// setting the new value to all the results
matchingOrders.ForEach(x => x.ShipDate = newDate);
matchingOrders.ForEach(x => Console.WriteLine("ID: " + x.ID + " Date: " + x.ShipDate.ToShortDateString()));
Output:
ID: 123123 Date: 1/1/0001
ID: 4986948 Date: 1/1/0001
ID: 23947439 Date: 1/1/0001
ID: 123123 Date: 6/15/2012
ID: 4986948 Date: 6/15/2012
ID: 23947439 Date: 6/15/2012
In ORMs, You have to fetch the record first make the change to the record then save it back. To do that, I will add an UpdateOrder method to my Repositary like this
public bool UpdateOrder(Order order)
{
int result=false;
int n=0;
context.Orders.Attach(order);
context.Entry(order).State=EntityState.Modified;
try
{
n=context.SaveChanges();
result=true;
}
catch (DbUpdateConcurrencyException ex)
{
ex.Entries.Single().Reload();
n= context.SaveChanges();
result= true;
}
catch (Exception ex2)
{
//log error or propogate to parent
}
return result;
}
And i will call it from my Action method like this
int orderId=123232;
var orders=ordersRepository.Orders.Where(x=> x.orderId.Contains(orderId)).ToList();
if(orders!=null)
{
foreach(var order in orders)
{
order.ShipDate=DateTime.Parse('12/12/2012);
var result= ordersRepository.UpdateOrder();
}
}
In this Approach, if you have to update many number of records, you are executing thatn many number of update statement to the database. In this purticular case, i would like to execute the Raw SQL statement with only one query using the Database.SqlQuery method
string yourQry="UPDATE orders SET shipDate = '6/15/2012'
WHERE orderId IN ('123123','4986948','23947439')";
var reslt=context.Database.SqlQuery<int>(yourQry);
I have been trying to add some events to the fullCalendar using a call to a ASHX page using the following code.
Page script:
<script type="text/javascript">
$(document).ready(function() {
$('#calendar').fullCalendar({
header: {
left: 'prev,next today', center: 'title', right: 'month, agendaWeek,agendaDay'
},
events: 'FullCalendarEvents.ashx'
})
});
</script>
c# code:
public class EventsData
{
public int id { get; set; }
public string title { get; set; }
public string start { get; set; }
public string end { get; set; }
public string url { get; set; }
public int accountId { get; set; }
}
public class FullCalendarEvents : IHttpHandler
{
private static List<EventsData> testEventsData = new List<EventsData>
{
new EventsData {accountId = 0, title = "test 1", start = DateTime.Now.ToString("yyyy-MM-dd"), id=0},
new EventsData{ accountId = 1, title="test 2", start = DateTime.Now.AddHours(2).ToString("yyyy-MM-dd"), id=2}
};
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "application/json.";
context.Response.Write(GetEventData());
}
private string GetEventData()
{
List<EventsData> ed = testEventsData;
StringBuilder sb = new StringBuilder();
sb.Append("[");
foreach (var data in ed)
{
sb.Append("{");
sb.Append(string.Format("id: {0},", data.id));
sb.Append(string.Format("title:'{0}',", data.title));
sb.Append(string.Format("start: '{0}',", data.start));
sb.Append("allDay: false");
sb.Append("},");
}
sb.Remove(sb.Length - 1, 1);
sb.Append("]");
return sb.ToString();
}
}
The ASHX page gets called and returnd the following data:
[{id: 0,title:'test 1',start: '2010-06-07',allDay: false},{id: 2,title:'test 2',start: '2010-06-07',allDay: false}]
The call to the ASHX page does not display any results, but if I paste the values returned directly into the events it displays correctly. I am I have been trying to get this code to work for a day now and I can't see why the events are not getting set.
Any help or advise on how I can get this to work would be appreciated.
Steve
In case anyone stumbles across this problem. I tried all of the above solutions, but none of them worked.
For me, the problem was solved by using an older version of jquery. I switched from version 1.5.2 which was included in the fullcalendar package to version 1.3.2
Steve,
I ran into something similar -- it would render the events if the JSON was directly in the fullCalendar call, but it would not render the identicla JSON coming from an outside URL. I finally got it to work by modifying the JSON so that "id", "title", "start", "end", and "allDay" had the quotes around them.
So instead of this (to use your sample JSON):
[{id: 0,title:'test 1',start: '2010-06-07',allDay: false},{id: 2,title:'test 2',start: '2010-06-07',allDay: false}]
...I had this:
[{"id": 0,"title":"test 1","start": "2010-06-07","allDay": false},{"id": 2,"title":"test 2","start": "2010-06-07","allDay": false}]
Now, why it worked locally but not remotely, I can't say.
Your JSON data lost the end item:
{id: 0,title:'test 1',start: '2010-06-07',end: '2010-06-07',allDay: false}
Let's look at what we know and eliminate possibilities:
The ASHX page gets called and returnd the ... data:
So the server-side portion is working just fine, and the code to call out to the server side is working.
I paste the values returned directly into the events it displays correctly.
So the code that handles the response works correctly.
Logically we see here that code that connects your server response to your calendar's input is not working. Unfortunately, I'm not up on the jQuery fullCalendar method, but perhaps you're missing a callback declaration?
I think it might have something to do with your date values.
FullCalendar events from asp.net ASHX page not displaying is a correct solution to the issue.
And I used long format for dates.
And #Steve instead of StringAppending we can use :-
System.Web.Script.Serialization.JavaScriptSerializer oSerializer =
new System.Web.Script.Serialization.JavaScriptSerializer();
String sJSON = oSerializer.Serialize(evList);
evList being your list containing all events which has the essential properties like id,start,end,description,allDay etc..
I know this thread is an old thread,but this will be helpful to other users.
Just collating all the answers.
I struggled with this issue and resolved it using an .ashx handler as follows
My return class looks like…
public class Event
{
public Guid id { get; set; }
public string title { get; set; }
public string description { get; set; }
public long start { get; set; }
public long end { get; set; }
public bool allDay { get; set; }
}
Where DateTime values are converted to long values using…
private long ConvertToTimestamp(DateTime value)
{
long epoch = (value.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
return epoch;
}
And the ProcessRequest looks like…
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/html";
DateTime start = new DateTime(1970, 1, 1);
DateTime end = new DateTime(1970, 1, 1);
try
{
start = start.AddSeconds(double.Parse(context.Request.QueryString["start"]));
end = end.AddSeconds(double.Parse(context.Request.QueryString["end"]));
}
catch
{
start = DateTime.Today;
end = DateTime.Today.AddDays(1);
}
List<Event> evList = new List<Event>();
using (CondoManagerLib.Linq.CondoDataContext Dc = new CondoManagerLib.Linq.CondoDataContext(AppCode.Common.CGlobals.DsnDB))
{
evList = (from P in Dc.DataDailySchedules
where P.DateBeg>=start && P.DateEnd<=end
select new Event
{ description = P.Description,
id = P.RecordGuid,
title = P.Reason,
start = ConvertToTimestamp(P.DateBeg),
end = ConvertToTimestamp(P.DateEnd),
allDay = IsAllDay(P.DateBeg, P.DateEnd)
}).ToList();
}
System.Web.Script.Serialization.JavaScriptSerializer oSerializer = new System.Web.Script.Serialization.JavaScriptSerializer();
String sJSON = oSerializer.Serialize(evList);
context.Response.Write(sJSON);
}
And my Document Ready…
> $(document).ready(function () {
> $('#calendar').fullCalendar({
> header: { left: 'title', center: 'prev,today,next', right: 'month,agendaWeek,agendaDay' },
> editable: false,
> aspectRatio: 2.1,
> events: "CalendarEvents.ashx",
> eventRender: function (event, element) {
> element.qtip({
> content: event.description,
> position: { corner: { tooltip: 'topLeft', target: 'centerLeft'} },
> style: { border: { width: 1, radius: 3, color: '#000'},
> padding: 5,
> textAlign: 'center',
> tip: true,
> name: 'cream'
> }
> });
> }
> })
> });
The qTip pluging can be found at http://craigsworks.com/projects/qtip/
Hope this helps.