Skip to content

Commit 314dc62

Browse files
KenitoIncxuzhg
authored andcommitted
Fix issue with property names which differ from Clr property names
1 parent fd74a5c commit 314dc62

7 files changed

Lines changed: 327 additions & 8 deletions

File tree

src/Microsoft.AspNet.OData.Shared/ODataAPIHandler.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ internal static void CopyObjectProperties(object resource, IEdmModel model, IODa
178178
navigationProperties = edmEntityType.NavigationProperties();
179179
}
180180

181-
IDictionary<string, object> keys = GetKeys(entityKey, resource, type); // Refactored ApplyHandler. Consider removing this.
181+
IDictionary<string, object> keys = GetKeys(model, entityKey, resource, type); // Refactored ApplyHandler. Consider removing this.
182182

183183
IODataAPIHandler odataIdContainerHandler = null;
184184

@@ -203,7 +203,8 @@ internal static void CopyObjectProperties(object resource, IEdmModel model, IODa
203203
{
204204
foreach (IEdmNavigationProperty navProp in navigationProperties)
205205
{
206-
navPropNames.Add(navProp.Name);
206+
string clrPropertyName = EdmLibHelpers.GetClrPropertyName(navProp, model);
207+
navPropNames.Add(clrPropertyName);
207208
}
208209
}
209210

@@ -422,7 +423,7 @@ private static void CopyProperties(object originalObject, object newObject, List
422423
}
423424
}
424425

425-
private static IDictionary<string, object> GetKeys(IEnumerable<IEdmStructuralProperty> properties, object resource, Type type)
426+
private static IDictionary<string, object> GetKeys(IEdmModel model, IEnumerable<IEdmStructuralProperty> properties, object resource, Type type)
426427
{
427428
IDictionary<string, object> keys = new Dictionary<string, object>();
428429

@@ -433,7 +434,8 @@ private static IDictionary<string, object> GetKeys(IEnumerable<IEdmStructuralPro
433434

434435
foreach (IEdmStructuralProperty property in properties)
435436
{
436-
PropertyInfo prop = type.GetProperty(property.Name);
437+
string clrPropertyName = EdmLibHelpers.GetClrPropertyName(property, model);
438+
PropertyInfo prop = type.GetProperty(clrPropertyName);
437439
object value = prop.GetValue(resource, null);
438440

439441
keys.Add(new KeyValuePair<string, object>(property.Name, value));

src/Microsoft.AspNet.OData.Shared/Query/ExpandQueryBuilder.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ private string GenerateExpandQueryStringInternal(object value, IEdmModel model,
7070
foreach (IEdmNavigationProperty navProp in navigationProperties)
7171
{
7272
count++;
73-
PropertyInfo prop = type.GetProperty(navProp.Name);
73+
string clrPropertyName = EdmLibHelpers.GetClrPropertyName(navProp, model);
74+
PropertyInfo prop = type.GetProperty(clrPropertyName);
7475

7576
if (isCollection)
7677
{
@@ -86,7 +87,7 @@ private string GenerateExpandQueryStringInternal(object value, IEdmModel model,
8687
if (!navPropNames.Contains(navProp.Name))
8788
{
8889
expandString += !isNestedExpand ? "" : "(";
89-
expandString += count > 1 ? "," + prop.Name : string.Concat("$expand=", prop.Name);
90+
expandString += count > 1 ? "," + navProp.Name : string.Concat("$expand=", navProp.Name);
9091
navPropNames.Add(navProp.Name);
9192
expandString += GenerateExpandQueryStringInternal(navPropValue, model, true);
9293
}
@@ -108,7 +109,7 @@ private string GenerateExpandQueryStringInternal(object value, IEdmModel model,
108109
if (!navPropNames.Contains(navProp.Name))
109110
{
110111
expandString += !isNestedExpand ? "" : "(";
111-
expandString += count > 1 ? "," + prop.Name : string.Concat("$expand=", prop.Name);
112+
expandString += count > 1 ? "," + navProp.Name : string.Concat("$expand=", navProp.Name);
112113
navPropNames.Add(navProp.Name);
113114
expandString += GenerateExpandQueryStringInternal(navPropValue, model, true);
114115
}

test/E2ETest/Microsoft.Test.E2E.AspNet.OData/BulkOperation/BulkOperationController.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,4 +488,36 @@ private void InitEmployees()
488488
var cntrl = new EmployeesController();
489489
}
490490
}
491+
492+
public class StudentController : TestODataController
493+
{
494+
public static IList<Student> Students = null;
495+
public static IList<Course> Courses = null;
496+
497+
public StudentController()
498+
{
499+
if (null == Students)
500+
{
501+
InitStudents();
502+
}
503+
}
504+
505+
private void InitStudents()
506+
{
507+
Students = new List<Student>();
508+
Courses = new List<Course>();
509+
}
510+
511+
[ODataRoute("Students")]
512+
[HttpPost]
513+
[EnableQuery]
514+
public ITestActionResult Post([FromBody] Student student)
515+
{
516+
var handler = new StudentAPIHandler();
517+
518+
handler.DeepInsert(student, Request.GetModel(), new APIHandlerFactory(Request.GetModel()));
519+
520+
return Created(student);
521+
}
522+
}
491523
}

test/E2ETest/Microsoft.Test.E2E.AspNet.OData/BulkOperation/BulkOperationDataModel.cs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using System.Collections;
1010
using System.Collections.Generic;
1111
using System.ComponentModel.DataAnnotations;
12+
using System.Runtime.Serialization;
1213
using Microsoft.AspNet.OData;
1314
using Microsoft.AspNet.OData.Builder;
1415

@@ -161,6 +162,32 @@ public class UnTypedAddress
161162
public string Street { get; set; }
162163
}
163164

165+
[DataContract]
166+
public class Student
167+
{
168+
[Key]
169+
[DataMember(Name="StudentId")]
170+
public int Id { get; set; }
171+
172+
[DataMember(Name = "StudentName")]
173+
public string Name { get; set; }
174+
175+
[DataMember(Name = "StudentCourses")]
176+
public List<Course> Courses { get; set; }
177+
}
178+
179+
[DataContract]
180+
public class Course
181+
{
182+
[Key]
183+
[DataMember(Name = "CourseId")]
184+
public int Id { get; set; }
185+
186+
[DataMember(Name = "CourseName")]
187+
public string Name { get; set; }
188+
}
189+
190+
164191
public class FriendColl<T> : ICollection<T>
165192
{
166193
public FriendColl() { _items = new List<T>(); }

test/E2ETest/Microsoft.Test.E2E.AspNet.OData/BulkOperation/BulkOperationEdmModel.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ public static IEdmModel GetConventionModel(WebRouteConfiguration configuration)
7373
EntitySetConfiguration<NewOrder> overdueorders = builder.EntitySet<NewOrder>("OverdueOrders");
7474
EntitySetConfiguration<MyNewOrder> myoverdueorders = builder.EntitySet<MyNewOrder>("MyOverdueOrders");
7575
EntitySetConfiguration<NewOrder> myNewOrders = builder.EntitySet<NewOrder>("MyNewOrders");
76+
EntitySetConfiguration<Student> students = builder.EntitySet<Student>("Students");
77+
EntitySetConfiguration<Course> courses = builder.EntitySet<Course>("Courses");
7678

7779
// maybe following lines are not required once bug #1587 is fixed.
7880
// 1587: It's better to support automatically adding actions and functions in ODataConventionModelBuilder.

test/E2ETest/Microsoft.Test.E2E.AspNet.OData/BulkOperation/BulkOperationPatchHandlers.cs

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1926,4 +1926,230 @@ public override ODataAPIResponseStatus TryAddRelatedObject(IEdmStructuredObject
19261926
return ODataAPIResponseStatus.Success;
19271927
}
19281928
}
1929+
1930+
internal class StudentAPIHandler : ODataAPIHandler<Student>
1931+
{
1932+
public override ODataAPIResponseStatus TryCreate(IDictionary<string, object> keyValues, out Student createdObject, out string errorMessage)
1933+
{
1934+
createdObject = null;
1935+
errorMessage = string.Empty;
1936+
1937+
try
1938+
{
1939+
createdObject = new Student();
1940+
StudentController.Students.Add(createdObject);
1941+
1942+
return ODataAPIResponseStatus.Success;
1943+
}
1944+
catch (Exception ex)
1945+
{
1946+
errorMessage = ex.Message;
1947+
1948+
return ODataAPIResponseStatus.Failure;
1949+
}
1950+
}
1951+
1952+
public override ODataAPIResponseStatus TryDelete(IDictionary<string, object> keyValues, out string errorMessage)
1953+
{
1954+
errorMessage = string.Empty;
1955+
1956+
try
1957+
{
1958+
var id = keyValues.First().Value.ToString();
1959+
var student = StudentController.Students.First(x => x.Id == Int32.Parse(id));
1960+
1961+
StudentController.Students.Remove(student);
1962+
1963+
return ODataAPIResponseStatus.Success;
1964+
}
1965+
catch (Exception ex)
1966+
{
1967+
errorMessage = ex.Message;
1968+
1969+
return ODataAPIResponseStatus.Failure;
1970+
}
1971+
}
1972+
1973+
public override ODataAPIResponseStatus TryGet(IDictionary<string, object> keyValues, out Student originalObject, out string errorMessage)
1974+
{
1975+
ODataAPIResponseStatus status = ODataAPIResponseStatus.Success;
1976+
errorMessage = string.Empty;
1977+
originalObject = null;
1978+
1979+
try
1980+
{
1981+
var id = keyValues["Id"].ToString();
1982+
originalObject = StudentController.Students.FirstOrDefault(x => x.Id == Int32.Parse(id));
1983+
1984+
if (originalObject == null)
1985+
{
1986+
status = ODataAPIResponseStatus.NotFound;
1987+
}
1988+
}
1989+
catch (Exception ex)
1990+
{
1991+
status = ODataAPIResponseStatus.Failure;
1992+
errorMessage = ex.Message;
1993+
}
1994+
1995+
return status;
1996+
}
1997+
1998+
public override IODataAPIHandler GetNestedHandler(Student parent, string navigationPropertyName)
1999+
{
2000+
switch (navigationPropertyName)
2001+
{
2002+
case "Courses":
2003+
return new CourseAPIHandler(parent);
2004+
default:
2005+
return null;
2006+
}
2007+
}
2008+
2009+
public override ODataAPIResponseStatus TryAddRelatedObject(Student resource, out string errorMessage)
2010+
{
2011+
errorMessage = string.Empty;
2012+
2013+
return ODataAPIResponseStatus.Success;
2014+
}
2015+
2016+
public override Task<ODataAPIResponseStatus> TryCreateAsync(IDictionary<string, object> keyValues, out Student createdObject, out string errorMessage)
2017+
{
2018+
throw new NotImplementedException();
2019+
}
2020+
2021+
public override Task<ODataAPIResponseStatus> TryGetAsync(IDictionary<string, object> keyValues, out Student originalObject, out string errorMessage)
2022+
{
2023+
throw new NotImplementedException();
2024+
}
2025+
2026+
public override Task<ODataAPIResponseStatus> TryDeleteAsync(IDictionary<string, object> keyValues, out string errorMessage)
2027+
{
2028+
throw new NotImplementedException();
2029+
}
2030+
2031+
public override Task<ODataAPIResponseStatus> TryAddRelatedObjectAsync(Student resource, out string errorMessage)
2032+
{
2033+
throw new NotImplementedException();
2034+
}
2035+
2036+
public override IODataAPIHandler GetNestedHandlerAsync(Student parent, string navigationPropertyName)
2037+
{
2038+
throw new NotImplementedException();
2039+
}
2040+
}
2041+
2042+
internal class CourseAPIHandler : ODataAPIHandler<Course>
2043+
{
2044+
Student student;
2045+
public CourseAPIHandler(Student student)
2046+
{
2047+
this.student = student;
2048+
}
2049+
2050+
public override ODataAPIResponseStatus TryCreate(IDictionary<string, object> keyValues, out Course createdObject, out string errorMessage)
2051+
{
2052+
createdObject = null;
2053+
errorMessage = string.Empty;
2054+
2055+
try
2056+
{
2057+
createdObject = new Course();
2058+
StudentController.Courses.Add(createdObject);
2059+
2060+
return ODataAPIResponseStatus.Success;
2061+
}
2062+
catch (Exception ex)
2063+
{
2064+
errorMessage = ex.Message;
2065+
2066+
return ODataAPIResponseStatus.Failure;
2067+
}
2068+
}
2069+
2070+
public override ODataAPIResponseStatus TryDelete(IDictionary<string, object> keyValues, out string errorMessage)
2071+
{
2072+
errorMessage = string.Empty;
2073+
2074+
try
2075+
{
2076+
var id = keyValues.First().Value.ToString();
2077+
var course = StudentController.Courses.First(x => x.Id == Int32.Parse(id));
2078+
2079+
StudentController.Courses.Remove(course);
2080+
2081+
return ODataAPIResponseStatus.Success;
2082+
}
2083+
catch (Exception ex)
2084+
{
2085+
errorMessage = ex.Message;
2086+
2087+
return ODataAPIResponseStatus.Failure;
2088+
}
2089+
}
2090+
2091+
public override ODataAPIResponseStatus TryGet(IDictionary<string, object> keyValues, out Course originalObject, out string errorMessage)
2092+
{
2093+
ODataAPIResponseStatus status = ODataAPIResponseStatus.Success;
2094+
errorMessage = string.Empty;
2095+
originalObject = null;
2096+
2097+
try
2098+
{
2099+
var id = keyValues["Id"].ToString();
2100+
originalObject = StudentController.Courses.FirstOrDefault(x => x.Id == Int32.Parse(id));
2101+
2102+
if (originalObject == null)
2103+
{
2104+
status = ODataAPIResponseStatus.NotFound;
2105+
}
2106+
}
2107+
catch (Exception ex)
2108+
{
2109+
status = ODataAPIResponseStatus.Failure;
2110+
errorMessage = ex.Message;
2111+
}
2112+
2113+
return status;
2114+
}
2115+
2116+
public override IODataAPIHandler GetNestedHandler(Course parent, string navigationPropertyName)
2117+
{
2118+
return null;
2119+
}
2120+
2121+
public override ODataAPIResponseStatus TryAddRelatedObject(Course resource, out string errorMessage)
2122+
{
2123+
errorMessage = string.Empty;
2124+
2125+
this.student.Courses.Add(resource);
2126+
2127+
return ODataAPIResponseStatus.Success;
2128+
}
2129+
2130+
public override Task<ODataAPIResponseStatus> TryCreateAsync(IDictionary<string, object> keyValues, out Course createdObject, out string errorMessage)
2131+
{
2132+
throw new NotImplementedException();
2133+
}
2134+
2135+
public override Task<ODataAPIResponseStatus> TryGetAsync(IDictionary<string, object> keyValues, out Course originalObject, out string errorMessage)
2136+
{
2137+
throw new NotImplementedException();
2138+
}
2139+
2140+
public override Task<ODataAPIResponseStatus> TryDeleteAsync(IDictionary<string, object> keyValues, out string errorMessage)
2141+
{
2142+
throw new NotImplementedException();
2143+
}
2144+
2145+
public override Task<ODataAPIResponseStatus> TryAddRelatedObjectAsync(Course resource, out string errorMessage)
2146+
{
2147+
throw new NotImplementedException();
2148+
}
2149+
2150+
public override IODataAPIHandler GetNestedHandlerAsync(Course parent, string navigationPropertyName)
2151+
{
2152+
throw new NotImplementedException();
2153+
}
2154+
}
19292155
}

0 commit comments

Comments
 (0)