piroozman
دوشنبه 25 آذر 1398, 11:48 صبح
در پروژه ای از نوع MVC، قصد دارم به عنوان یه تازه کار، از گرید های شرکت Devexpress با نام DevExtreme استفاده کنم. برای ایجاد ارتباط با پایگاه داده از روش Code First استفاده کرده ام. در مدل خودم کلاسی دارم به نام Member. برای اضافه کردن کنترلر به پروژه روی پوشه Controller کلیک راست کرده و Add->Controller->DevExtreme Web API Controller with actions, using Entity Framework را انتخاب کردم. در ویزارد DatabasecContext، Model رو انتخاب کردم و نام کنترلر را MembersController تعیین کردم. بعد از این کار در پوشه Views پوشه ای به نام Members ایجاد کردم و در اون یک View با نام Index ایجاد کردم (دقیق نمی دونم چه نامی رو باید برای View باید انتخاب کنم). داخل Index کلیک راست کرده و از منوی ظاهر شده روی Insert A DevExtreme Control Here کلیک کردم. در ویزارد ظاهر شده کنترل خودم رو GridView انتخاب کردم و مابقی گزینه ها شامل DatabaseContext، مدل Memeber و کنترلر Members رو انتخاب کردم. کدهای تولید شده در فایل های مربوط به کنترلر، ویو و مسیریابها به شرح ذیر هستند:
Member Model:
public class Member {
#region Ctor
public Member()
{
}
#endregion
#region Properties
[DisplayName("شماره حساب")]
[Key]
public int MemberID { get; set; }
[Required(ErrorMessage ="*")]
[DisplayName("نام")]
public string FirstName { get; set; }
[Required(ErrorMessage = "*")]
[DisplayName("نام خانوادگی")]
public string LastName { get; set; }
[DisplayName("تلفن ثابت")]
public string Phone { get; set; }
[DisplayName("تلفن همراه")]
public string Mobile { get; set; }
[Required(ErrorMessage = "*")]
[DisplayName("کد ملی")]
public string NID { get; set; }
[Required(ErrorMessage = "*")]
[DisplayName("کد پرسنلی")]
public string MID { get; set; }
[Required(ErrorMessage = "*")]
[DisplayName("کد حقوقی")]
public string SalaryID { get; set; }
#endregion
}
MembersController:
using DevExtreme.AspNet.Data;
using DevExtreme.AspNet.Mvc;
using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Web.Http;
using System.Web.Http.ModelBinding;
namespace WebApplication2.Models.Controllers
{
//[Route("api/Members/{action}", Name = "MembersApi")]
public class MembersController : ApiController
{
private ApplicationDbContext _context = new ApplicationDbContext();
[HttpGet]
public HttpResponseMessage Get(DataSourceLoadOptions loadOptions) {
var members = _context.Members.Select(i => new {
i.MemberID,
i.FirstName,
i.LastName,
i.Phone,
i.Mobile,
i.NID,
i.MID,
i.SalaryID
});
return Request.CreateResponse(DataSourceLoader.Load(membe rs, loadOptions));
}
[HttpPost]
public HttpResponseMessage Post(FormDataCollection form) {
var model = new Member();
var values = JsonConvert.DeserializeObject<IDictionary>(form.Get("values"));
PopulateModel(model, values);
Validate(model);
if (!ModelState.IsValid)
return Request.CreateErrorResponse(HttpStatusCode.BadRequ est, GetFullErrorMessage(ModelState));
var result = _context.Members.Add(model);
_context.SaveChanges();
return Request.CreateResponse(HttpStatusCode.Created, result.MemberID);
}
[HttpPut]
public HttpResponseMessage Put(FormDataCollection form) {
var key = Convert.ToInt32(form.Get("key"));
var model = _context.Members.FirstOrDefault(item => item.MemberID == key);
if(model == null)
return Request.CreateResponse(HttpStatusCode.Conflict, "Member not found");
var values = JsonConvert.DeserializeObject<IDictionary>(form.Get("values"));
PopulateModel(model, values);
Validate(model);
if (!ModelState.IsValid)
return Request.CreateErrorResponse(HttpStatusCode.BadRequ est, GetFullErrorMessage(ModelState));
_context.SaveChanges();
return Request.CreateResponse(HttpStatusCode.OK);
}
[HttpDelete]
public void Delete(FormDataCollection form) {
var key = Convert.ToInt32(form.Get("key"));
var model = _context.Members.FirstOrDefault(item => item.MemberID == key);
_context.Members.Remove(model);
_context.SaveChanges();
}
private void PopulateModel(Member model, IDictionary values) {
string MEMBER_ID = nameof(Member.MemberID);
string FIRST_NAME = nameof(Member.FirstName);
string LAST_NAME = nameof(Member.LastName);
string PHONE = nameof(Member.Phone);
string MOBILE = nameof(Member.Mobile);
string NID = nameof(Member.NID);
string MID = nameof(Member.MID);
string SALARY_ID = nameof(Member.SalaryID);
if(values.Contains(MEMBER_ID)) {
model.MemberID = Convert.ToInt32(values[MEMBER_ID]);
}
if(values.Contains(FIRST_NAME)) {
model.FirstName = Convert.ToString(values[FIRST_NAME]);
}
if(values.Contains(LAST_NAME)) {
model.LastName = Convert.ToString(values[LAST_NAME]);
}
if(values.Contains(PHONE)) {
model.Phone = Convert.ToString(values[PHONE]);
}
if(values.Contains(MOBILE)) {
model.Mobile = Convert.ToString(values[MOBILE]);
}
if(values.Contains(NID)) {
model.NID = Convert.ToString(values[NID]);
}
if(values.Contains(MID)) {
model.MID = Convert.ToString(values[MID]);
}
if(values.Contains(SALARY_ID)) {
model.SalaryID = Convert.ToString(values[SALARY_ID]);
}
}
private string GetFullErrorMessage(ModelStateDictionary modelState) {
var messages = new List<string>();
foreach(var entry in modelState) {
foreach(var error in entry.Value.Errors)
messages.Add(error.ErrorMessage);
}
return String.Join(" ", messages);
}
protected override void Dispose(bool disposing) {
if (disposing) {
_context.Dispose();
}
base.Dispose(disposing);
}
}
}
Index View:
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
@(Html.DevExtreme().DataGrid<WebApplication2.Models.Member>()
.DataSource(ds => ds.WebApi()
.RouteName("MembersApi")
.LoadAction("Get")
.InsertAction("Post")
.UpdateAction("Put")
.DeleteAction("Delete")
.Key("MemberID")
)
.RemoteOperations(true)
.Columns(columns => {
columns.AddFor(m => m.MemberID);
columns.AddFor(m => m.FirstName);
columns.AddFor(m => m.LastName);
columns.AddFor(m => m.Phone);
columns.AddFor(m => m.Mobile);
columns.AddFor(m => m.NID);
columns.AddFor(m => m.MID);
columns.AddFor(m => m.SalaryID);
})
.Editing(e => e
.AllowAdding(true)
.AllowUpdating(true)
.AllowDeleting(true)
)
)
WebConfig.cs File:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
namespace WebApplication2
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// WebAPI when dealing with JSON & JavaScript!
// Setup json serialization to serialize classes to camel (std. Json format)
var formatter = GlobalConfiguration.Configuration.Formatters.JsonF ormatter;
formatter.SerializerSettings.ContractResolver =
new Newtonsoft.Json.Serialization.CamelCasePropertyNam esContractResolver();
}
}
}
Global.asax.cs file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
namespace WebApplication2
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Registe r);
FilterConfig.RegisterGlobalFilters(GlobalFilters.F ilters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
}
بعد از ذخیره سازی فایل ها و بیلد پروژه، وقتی سعی میکنم ویو index رو در مرورگر خودم ببینم (با نشانی https://localhost:44328/Members/index ) متاسفانه با خطای زیر مواجه میشم:
The resource cannot be found. Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /Members/index
باور کنید الان حدود 6 روز هستش که تو سایتهای شرکت Devexpress، سایت Stackoverflow و خیلی از سایت های فارسی دنبال این هستم که چطوری میتونم این مشکلم رو حل کنم اما نشد که نشد. حالا اگر کسی از دوستان میتونه در این زمینه کمکم کنه خیلی ممنون میشم. پروژه رو میتونید از این لینک (https://drive.google.com/file/d/1o7cTLaYlh4WVRTzcepcpVR8p4cGjc34B/view?usp=sharing)دانلود کنید.
Member Model:
public class Member {
#region Ctor
public Member()
{
}
#endregion
#region Properties
[DisplayName("شماره حساب")]
[Key]
public int MemberID { get; set; }
[Required(ErrorMessage ="*")]
[DisplayName("نام")]
public string FirstName { get; set; }
[Required(ErrorMessage = "*")]
[DisplayName("نام خانوادگی")]
public string LastName { get; set; }
[DisplayName("تلفن ثابت")]
public string Phone { get; set; }
[DisplayName("تلفن همراه")]
public string Mobile { get; set; }
[Required(ErrorMessage = "*")]
[DisplayName("کد ملی")]
public string NID { get; set; }
[Required(ErrorMessage = "*")]
[DisplayName("کد پرسنلی")]
public string MID { get; set; }
[Required(ErrorMessage = "*")]
[DisplayName("کد حقوقی")]
public string SalaryID { get; set; }
#endregion
}
MembersController:
using DevExtreme.AspNet.Data;
using DevExtreme.AspNet.Mvc;
using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
using System.Web.Http;
using System.Web.Http.ModelBinding;
namespace WebApplication2.Models.Controllers
{
//[Route("api/Members/{action}", Name = "MembersApi")]
public class MembersController : ApiController
{
private ApplicationDbContext _context = new ApplicationDbContext();
[HttpGet]
public HttpResponseMessage Get(DataSourceLoadOptions loadOptions) {
var members = _context.Members.Select(i => new {
i.MemberID,
i.FirstName,
i.LastName,
i.Phone,
i.Mobile,
i.NID,
i.MID,
i.SalaryID
});
return Request.CreateResponse(DataSourceLoader.Load(membe rs, loadOptions));
}
[HttpPost]
public HttpResponseMessage Post(FormDataCollection form) {
var model = new Member();
var values = JsonConvert.DeserializeObject<IDictionary>(form.Get("values"));
PopulateModel(model, values);
Validate(model);
if (!ModelState.IsValid)
return Request.CreateErrorResponse(HttpStatusCode.BadRequ est, GetFullErrorMessage(ModelState));
var result = _context.Members.Add(model);
_context.SaveChanges();
return Request.CreateResponse(HttpStatusCode.Created, result.MemberID);
}
[HttpPut]
public HttpResponseMessage Put(FormDataCollection form) {
var key = Convert.ToInt32(form.Get("key"));
var model = _context.Members.FirstOrDefault(item => item.MemberID == key);
if(model == null)
return Request.CreateResponse(HttpStatusCode.Conflict, "Member not found");
var values = JsonConvert.DeserializeObject<IDictionary>(form.Get("values"));
PopulateModel(model, values);
Validate(model);
if (!ModelState.IsValid)
return Request.CreateErrorResponse(HttpStatusCode.BadRequ est, GetFullErrorMessage(ModelState));
_context.SaveChanges();
return Request.CreateResponse(HttpStatusCode.OK);
}
[HttpDelete]
public void Delete(FormDataCollection form) {
var key = Convert.ToInt32(form.Get("key"));
var model = _context.Members.FirstOrDefault(item => item.MemberID == key);
_context.Members.Remove(model);
_context.SaveChanges();
}
private void PopulateModel(Member model, IDictionary values) {
string MEMBER_ID = nameof(Member.MemberID);
string FIRST_NAME = nameof(Member.FirstName);
string LAST_NAME = nameof(Member.LastName);
string PHONE = nameof(Member.Phone);
string MOBILE = nameof(Member.Mobile);
string NID = nameof(Member.NID);
string MID = nameof(Member.MID);
string SALARY_ID = nameof(Member.SalaryID);
if(values.Contains(MEMBER_ID)) {
model.MemberID = Convert.ToInt32(values[MEMBER_ID]);
}
if(values.Contains(FIRST_NAME)) {
model.FirstName = Convert.ToString(values[FIRST_NAME]);
}
if(values.Contains(LAST_NAME)) {
model.LastName = Convert.ToString(values[LAST_NAME]);
}
if(values.Contains(PHONE)) {
model.Phone = Convert.ToString(values[PHONE]);
}
if(values.Contains(MOBILE)) {
model.Mobile = Convert.ToString(values[MOBILE]);
}
if(values.Contains(NID)) {
model.NID = Convert.ToString(values[NID]);
}
if(values.Contains(MID)) {
model.MID = Convert.ToString(values[MID]);
}
if(values.Contains(SALARY_ID)) {
model.SalaryID = Convert.ToString(values[SALARY_ID]);
}
}
private string GetFullErrorMessage(ModelStateDictionary modelState) {
var messages = new List<string>();
foreach(var entry in modelState) {
foreach(var error in entry.Value.Errors)
messages.Add(error.ErrorMessage);
}
return String.Join(" ", messages);
}
protected override void Dispose(bool disposing) {
if (disposing) {
_context.Dispose();
}
base.Dispose(disposing);
}
}
}
Index View:
@{
Layout = "~/Views/Shared/_Layout.cshtml";
}
@(Html.DevExtreme().DataGrid<WebApplication2.Models.Member>()
.DataSource(ds => ds.WebApi()
.RouteName("MembersApi")
.LoadAction("Get")
.InsertAction("Post")
.UpdateAction("Put")
.DeleteAction("Delete")
.Key("MemberID")
)
.RemoteOperations(true)
.Columns(columns => {
columns.AddFor(m => m.MemberID);
columns.AddFor(m => m.FirstName);
columns.AddFor(m => m.LastName);
columns.AddFor(m => m.Phone);
columns.AddFor(m => m.Mobile);
columns.AddFor(m => m.NID);
columns.AddFor(m => m.MID);
columns.AddFor(m => m.SalaryID);
})
.Editing(e => e
.AllowAdding(true)
.AllowUpdating(true)
.AllowDeleting(true)
)
)
WebConfig.cs File:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Http;
namespace WebApplication2
{
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
// WebAPI when dealing with JSON & JavaScript!
// Setup json serialization to serialize classes to camel (std. Json format)
var formatter = GlobalConfiguration.Configuration.Formatters.JsonF ormatter;
formatter.SerializerSettings.ContractResolver =
new Newtonsoft.Json.Serialization.CamelCasePropertyNam esContractResolver();
}
}
}
Global.asax.cs file:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
namespace WebApplication2
{
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Registe r);
FilterConfig.RegisterGlobalFilters(GlobalFilters.F ilters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
}
بعد از ذخیره سازی فایل ها و بیلد پروژه، وقتی سعی میکنم ویو index رو در مرورگر خودم ببینم (با نشانی https://localhost:44328/Members/index ) متاسفانه با خطای زیر مواجه میشم:
The resource cannot be found. Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. Please review the following URL and make sure that it is spelled correctly.
Requested URL: /Members/index
باور کنید الان حدود 6 روز هستش که تو سایتهای شرکت Devexpress، سایت Stackoverflow و خیلی از سایت های فارسی دنبال این هستم که چطوری میتونم این مشکلم رو حل کنم اما نشد که نشد. حالا اگر کسی از دوستان میتونه در این زمینه کمکم کنه خیلی ممنون میشم. پروژه رو میتونید از این لینک (https://drive.google.com/file/d/1o7cTLaYlh4WVRTzcepcpVR8p4cGjc34B/view?usp=sharing)دانلود کنید.