PDA

View Full Version : استفاده از گرید DevExpress در ASP.NET MVC



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)دانلود کنید.

مهدی کرامتی
چهارشنبه 27 آذر 1398, 23:06 عصر
وقتی شما نوع کنترلر رو موقع Scaffold کردن، Api Controller انتخاب می کنید بالطبع، یک پیشوند Api به مسیر فرخوانی اش اضافه میشه، و آدرس مقصد شما میشه:
https://localhost:44328/api/Members/index (https://localhost:44328/Members/index)

اگر هم می خواهید تاپیک تون خوانده بشه، عنوانش رو درست انتخاب کنید (عنوان این تاپیک رو ویرایش کردم).
مضمون سوال شما درباره استفاده از گرید DevExpress در ویو ها است، اما عنوان تاپیک تون چیزی نبود که جلب توجه کنه. اول خودتون قواعد رو رعایت کنید، بعد شروع کنید ایراد گرفتن از بقیه.

piroozman
شنبه 30 آذر 1398, 10:59 صبح
وقتی شما نوع کنترلر رو موقع Scaffold کردن، Api Controller انتخاب می کنید بالطبع، یک پیشوند Api به مسیر فرخوانی اش اضافه میشه، و آدرس مقصد شما میشه:
https://localhost:44328/api/Members/index (https://localhost:44328/Members/index)
خیلی ممنون از پاسختون. قبلا ً امتحان کردم جوابی نگرفتم. با خطای زیر مواجه میشم:


This XML file does not appear to have any style information associated with it. The document tree is shown below.

<Error>
<Message>
No HTTP resource was found that matches the request URI 'https://localhost:44328/api/Members/index'.
</Message>

<MessageDetail>
No action was found on the controller 'Members' that matches the request.
</MessageDetail>
</Error>



اگر هم می خواهید تاپیک تون خوانده بشه، عنوانش رو درست انتخاب کنید (عنوان این تاپیک رو ویرایش کردم).مضمون سوال شما درباره استفاده از گرید DevExpress در ویو ها است، اما عنوان تاپیک تون چیزی نبود که جلب توجه کنه.
از نظر خودم که عنوان خوبی بود. موضوع اصلی تاپیک استفاده از Routing بود، برای همین این موضوع رو براش انتخاب کردم. به هر حال ممنون که عنوان رو عوض کردید

اول خودتون قواعد رو رعایت کنید، بعد شروع کنید ایراد گرفتن از بقیه. خدا رو شکر تا به حال قواعد رو رعایت کردم و کسی بر من خرده نگرفته بود. انتخاب محل درج تاپیک طبق قاعده و طرح عنوان نیز بر اساس فکر و مشکل کاربر نوشته می شود. در کل خوشحالم که بالاخره «بنیانگذار سایت» آقای مهندس کرامتی قدم رنجه فرموند و یه پاسخ نصف و نیمه به من دادند. ولی مشکل من همچنان باقی است.
از سایر دوستان ممنون میشم یه نگاهی به کدها من بیاندازند و ایراد کار رو اعلام کنند.
دوستان دقت کنند که همه کدها به صورت ویزارد تولید شده اند و من هیچ دخل و تصرفی در آنها نداشته ام. پروژه را می توانید در قابل یک فایل فشرده از این اینجا (https://drive.google.com/file/d/1o7cTLaYlh4WVRTzcepcpVR8p4cGjc34B/view?usp=sharing)دریافت کنید.
یاعلی

piroozman
یک شنبه 01 دی 1398, 21:29 عصر
یعنی واقعا هیچ کس نیست جواب بده؟ دوستان، اساتید؟